Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(165)

Side by Side Diff: net/tools/testserver/device_management.py

Issue 6537020: Update policy backend and testserver for the newest policy protocol (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: it was a bad idea to zero out machine_id_ in the prev. patchset Created 9 years, 9 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
1 #!/usr/bin/python2.5 1 #!/usr/bin/python2.5
2 # Copyright (c) 2011 The Chromium Authors. All rights reserved. 2 # Copyright (c) 2011 The Chromium Authors. All rights reserved.
3 # Use of this source code is governed by a BSD-style license that can be 3 # Use of this source code is governed by a BSD-style license that can be
4 # found in the LICENSE file. 4 # found in the LICENSE file.
5 5
6 """A bare-bones test server for testing cloud policy support. 6 """A bare-bones test server for testing cloud policy support.
7 7
8 This implements a simple cloud policy test server that can be used to test 8 This implements a simple cloud policy test server that can be used to test
9 chrome's device management service client. The policy information is read from 9 chrome's device management service client. The policy information is read from
10 the file named device_management in the server's data directory. It contains 10 the file named device_management in the server's data directory. It contains
(...skipping 96 matching lines...) Expand 10 before | Expand all | Expand 10 after
107 107
108 Parses the data supplied at construction time and returns a pair indicating 108 Parses the data supplied at construction time and returns a pair indicating
109 http status code and response data to be sent back to the client. 109 http status code and response data to be sent back to the client.
110 110
111 Returns: 111 Returns:
112 A tuple of HTTP status code and response data to send to the client. 112 A tuple of HTTP status code and response data to send to the client.
113 """ 113 """
114 rmsg = dm.DeviceManagementRequest() 114 rmsg = dm.DeviceManagementRequest()
115 rmsg.ParseFromString(self._request) 115 rmsg.ParseFromString(self._request)
116 116
117 logging.debug('auth -> ' + self._headers.getheader('Authorization', ''))
118 logging.debug('deviceid -> ' + self.GetUniqueParam('deviceid'))
117 self.DumpMessage('Request', rmsg) 119 self.DumpMessage('Request', rmsg)
118 120
119 request_type = self.GetUniqueParam('request') 121 request_type = self.GetUniqueParam('request')
122 # Check server side requirements, as defined in
123 # device_management_backend.proto.
124 if (self.GetUniqueParam('devicetype') != '2' or
125 self.GetUniqueParam('apptype') != 'Chrome' or
126 (request_type != 'ping' and
127 len(self.GetUniqueParam('deviceid')) >= 64) or
128 len(self.GetUniqueParam('agent')) >= 64):
129 return (400, 'Invalid request parameter')
120 if request_type == 'register': 130 if request_type == 'register':
121 return self.ProcessRegister(rmsg.register_request) 131 return self.ProcessRegister(rmsg.register_request)
122 elif request_type == 'unregister': 132 elif request_type == 'unregister':
123 return self.ProcessUnregister(rmsg.unregister_request) 133 return self.ProcessUnregister(rmsg.unregister_request)
124 elif request_type == 'policy': 134 elif request_type == 'policy' or request_type == 'ping':
125 return self.ProcessPolicy(rmsg.policy_request) 135 return self.ProcessPolicy(rmsg.policy_request, request_type)
126 elif request_type == 'cloud_policy':
127 return self.ProcessCloudPolicyRequest(rmsg.cloud_policy_request)
128 elif request_type == 'managed_check':
129 return self.ProcessManagedCheck(rmsg.managed_check_request)
130 else: 136 else:
131 return (400, 'Invalid request parameter') 137 return (400, 'Invalid request parameter')
132 138
133 def CheckGoogleLogin(self): 139 def CheckGoogleLogin(self):
134 """Extracts the GoogleLogin auth token from the HTTP request, and 140 """Extracts the GoogleLogin auth token from the HTTP request, and
135 returns it. Returns None if the token is not present. 141 returns it. Returns None if the token is not present.
136 """ 142 """
137 match = re.match('GoogleLogin auth=(\\w+)', 143 match = re.match('GoogleLogin auth=(\\w+)',
138 self._headers.getheader('Authorization', '')) 144 self._headers.getheader('Authorization', ''))
139 if not match: 145 if not match:
140 return None 146 return None
141 return match.group(1) 147 return match.group(1)
142 148
143 def GetDeviceName(self):
144 """Returns the name for the currently authenticated device based on its
145 device id.
146 """
147 return 'chromeos-' + self.GetUniqueParam('deviceid')
148
149 def ProcessRegister(self, msg): 149 def ProcessRegister(self, msg):
150 """Handles a register request. 150 """Handles a register request.
151 151
152 Checks the query for authorization and device identifier, registers the 152 Checks the query for authorization and device identifier, registers the
153 device with the server and constructs a response. 153 device with the server and constructs a response.
154 154
155 Args: 155 Args:
156 msg: The DeviceRegisterRequest message received from the client. 156 msg: The DeviceRegisterRequest message received from the client.
157 157
158 Returns: 158 Returns:
159 A tuple of HTTP status code and response data to send to the client. 159 A tuple of HTTP status code and response data to send to the client.
160 """ 160 """
161 # Check the auth token and device ID. 161 # Check the auth token and device ID.
162 if not self.CheckGoogleLogin(): 162 if not self.CheckGoogleLogin():
163 return (403, 'No authorization') 163 return (403, 'No authorization')
164 164
165 device_id = self.GetUniqueParam('deviceid') 165 device_id = self.GetUniqueParam('deviceid')
166 if not device_id: 166 if not device_id:
167 return (400, 'Missing device identifier') 167 return (400, 'Missing device identifier')
168 168
169 # Register the device and create a token. 169 token_info = self._server.RegisterDevice(device_id,
170 dmtoken = self._server.RegisterDevice(device_id) 170 msg.machine_id,
171 msg.type)
171 172
172 # Send back the reply. 173 # Send back the reply.
173 response = dm.DeviceManagementResponse() 174 response = dm.DeviceManagementResponse()
174 response.error = dm.DeviceManagementResponse.SUCCESS 175 response.error = dm.DeviceManagementResponse.SUCCESS
175 response.register_response.device_management_token = dmtoken 176 response.register_response.device_management_token = (
177 token_info['device_token'])
178 response.register_response.machine_name = token_info['machine_name']
176 179
177 self.DumpMessage('Response', response) 180 self.DumpMessage('Response', response)
178 181
179 return (200, response.SerializeToString()) 182 return (200, response.SerializeToString())
180 183
181 def ProcessUnregister(self, msg): 184 def ProcessUnregister(self, msg):
182 """Handles a register request. 185 """Handles a register request.
183 186
184 Checks for authorization, unregisters the device and constructs the 187 Checks for authorization, unregisters the device and constructs the
185 response. 188 response.
(...skipping 14 matching lines...) Expand all
200 203
201 # Prepare and send the response. 204 # Prepare and send the response.
202 response = dm.DeviceManagementResponse() 205 response = dm.DeviceManagementResponse()
203 response.error = dm.DeviceManagementResponse.SUCCESS 206 response.error = dm.DeviceManagementResponse.SUCCESS
204 response.unregister_response.CopyFrom(dm.DeviceUnregisterResponse()) 207 response.unregister_response.CopyFrom(dm.DeviceUnregisterResponse())
205 208
206 self.DumpMessage('Response', response) 209 self.DumpMessage('Response', response)
207 210
208 return (200, response.SerializeToString()) 211 return (200, response.SerializeToString())
209 212
210 def ProcessManagedCheck(self, msg): 213 def ProcessInitialPolicy(self, msg):
211 """Handles a 'managed check' request. 214 """Handles a 'preregister policy' request.
212 215
213 Queries the list of managed users and responds the client if their user 216 Queries the list of managed users and responds the client if their user
214 is managed or not. 217 is managed or not.
215 218
216 Args: 219 Args:
217 msg: The ManagedCheckRequest message received from the client. 220 msg: The PolicyFetchRequest message received from the client.
218 221
219 Returns: 222 Returns:
220 A tuple of HTTP status code and response data to send to the client. 223 A tuple of HTTP status code and response data to send to the client.
221 """ 224 """
222 # Check the management token. 225 # Check the GAIA token.
223 auth = self.CheckGoogleLogin() 226 auth = self.CheckGoogleLogin()
224 if not auth: 227 if not auth:
225 return (403, 'No authorization') 228 return (403, 'No authorization')
226 229
227 managed_check_response = dm.ManagedCheckResponse() 230 chrome_initial_settings = dm.ChromeInitialSettingsProto()
228 if ('*' in self._server.policy['managed_users'] or 231 if ('*' in self._server.policy['managed_users'] or
229 auth in self._server.policy['managed_users']): 232 auth in self._server.policy['managed_users']):
230 managed_check_response.mode = dm.ManagedCheckResponse.MANAGED; 233 chrome_initial_settings.enrollment_provision = (
234 dm.ChromeInitialSettingsProto.MANAGED);
231 else: 235 else:
232 managed_check_response.mode = dm.ManagedCheckResponse.UNMANAGED; 236 chrome_initial_settings.enrollment_provision = (
237 dm.ChromeInitialSettingsProto.UNMANAGED);
238
239 policy_data = dm.PolicyData()
240 policy_data.policy_type = msg.policy_type
241 policy_data.policy_value = chrome_initial_settings.SerializeToString()
233 242
234 # Prepare and send the response. 243 # Prepare and send the response.
235 response = dm.DeviceManagementResponse() 244 response = dm.DeviceManagementResponse()
236 response.error = dm.DeviceManagementResponse.SUCCESS 245 response.error = dm.DeviceManagementResponse.SUCCESS
237 response.managed_check_response.CopyFrom(managed_check_response) 246 fetch_response = response.policy_response.response.add()
247 fetch_response.policy_data = (
248 policy_data.SerializeToString())
238 249
239 self.DumpMessage('Response', response) 250 self.DumpMessage('Response', response)
240 251
241 return (200, response.SerializeToString()) 252 return (200, response.SerializeToString())
242 253
243 def ProcessPolicy(self, msg): 254 def ProcessDevicePolicy(self, msg):
244 """Handles a policy request.
245
246 Checks for authorization, encodes the policy into protobuf representation
247 and constructs the response.
248
249 Args:
250 msg: The DevicePolicyRequest message received from the client.
251
252 Returns:
253 A tuple of HTTP status code and response data to send to the client.
254 """
255 # Check the management token. 255 # Check the management token.
256 token, response = self.CheckToken() 256 token, response = self.CheckToken()
257 if not token: 257 if not token:
258 return response 258 return response
259 259
260 # Stuff the policy dictionary into a response message and send it back. 260 # Stuff the policy dictionary into a response message and send it back.
261 response = dm.DeviceManagementResponse() 261 response = dm.DeviceManagementResponse()
262 response.error = dm.DeviceManagementResponse.SUCCESS 262 response.error = dm.DeviceManagementResponse.SUCCESS
263 response.policy_response.CopyFrom(dm.DevicePolicyResponse()) 263 response.policy_response.CopyFrom(dm.DevicePolicyResponse())
264 264
265 # Respond only if the client requested policy for the cros/device scope, 265 # Respond only if the client requested policy for the cros/device scope,
266 # since that's where chrome policy is supposed to live in. 266 # since that's where chrome policy is supposed to live in.
267 if msg.policy_scope in self._server.policy: 267 if msg.policy_scope == 'chromeos/device':
268 policy = self._server.policy[msg.policy_scope]['mandatory'] 268 policy = self._server.policy['google/chromeos/user']['mandatory']
Mattias Nissler (ping if slow) 2011/03/01 10:25:49 huh? why these changes?
gfeher 2011/03/01 15:53:00 Because this is for handling the old protocol and
269 setting = response.policy_response.setting.add() 269 setting = response.policy_response.setting.add()
270 setting.policy_key = 'chrome-policy' 270 setting.policy_key = 'chrome-policy'
271 policy_value = dm.GenericSetting() 271 policy_value = dm.GenericSetting()
272 for (key, value) in policy.iteritems(): 272 for (key, value) in policy.iteritems():
273 entry = policy_value.named_value.add() 273 entry = policy_value.named_value.add()
274 entry.name = key 274 entry.name = key
275 entry_value = dm.GenericValue() 275 entry_value = dm.GenericValue()
276 if isinstance(value, bool): 276 if isinstance(value, bool):
277 entry_value.value_type = dm.GenericValue.VALUE_TYPE_BOOL 277 entry_value.value_type = dm.GenericValue.VALUE_TYPE_BOOL
278 entry_value.bool_value = value 278 entry_value.bool_value = value
279 elif isinstance(value, int): 279 elif isinstance(value, int):
280 entry_value.value_type = dm.GenericValue.VALUE_TYPE_INT64 280 entry_value.value_type = dm.GenericValue.VALUE_TYPE_INT64
281 entry_value.int64_value = value 281 entry_value.int64_value = value
282 elif isinstance(value, str) or isinstance(value, unicode): 282 elif isinstance(value, str) or isinstance(value, unicode):
283 entry_value.value_type = dm.GenericValue.VALUE_TYPE_STRING 283 entry_value.value_type = dm.GenericValue.VALUE_TYPE_STRING
284 entry_value.string_value = value 284 entry_value.string_value = value
285 elif isinstance(value, list): 285 elif isinstance(value, list):
286 entry_value.value_type = dm.GenericValue.VALUE_TYPE_STRING_ARRAY 286 entry_value.value_type = dm.GenericValue.VALUE_TYPE_STRING_ARRAY
287 for list_entry in value: 287 for list_entry in value:
288 entry_value.string_array.append(str(list_entry)) 288 entry_value.string_array.append(str(list_entry))
289 entry.value.CopyFrom(entry_value) 289 entry.value.CopyFrom(entry_value)
290 setting.policy_value.CopyFrom(policy_value) 290 setting.policy_value.CopyFrom(policy_value)
291 291
292 self.DumpMessage('Response', response) 292 self.DumpMessage('Response', response)
293 293
294 return (200, response.SerializeToString()) 294 return (200, response.SerializeToString())
295 295
296 def ProcessPolicy(self, msg, request_type):
297 """Handles a policy request.
298
299 Checks for authorization, encodes the policy into protobuf representation
300 and constructs the response.
301
302 Args:
303 msg: The DevicePolicyRequest message received from the client.
304
305 Returns:
306 A tuple of HTTP status code and response data to send to the client.
307 """
308
309 if msg.request:
310 for request in msg.request:
311 if request.policy_type == 'google/chromeos/unregistered_user':
312 if request_type != 'ping':
313 return (400, 'Invalid request type')
314 return self.ProcessInitialPolicy(request)
315 elif (request.policy_type in
316 ('google/chromeos/user', 'google/chromeos/device')):
317 if request_type != 'policy':
318 return (400, 'Invalid request type')
319 return self.ProcessCloudPolicy(request)
320 else:
321 return (400, 'Invalid policy_type')
322 else:
323 return self.ProcessDevicePolicy(msg)
324
296 def SetProtobufMessageField(self, group_message, field, field_value): 325 def SetProtobufMessageField(self, group_message, field, field_value):
297 '''Sets a field in a protobuf message. 326 '''Sets a field in a protobuf message.
298 327
299 Args: 328 Args:
300 group_message: The protobuf message. 329 group_message: The protobuf message.
301 field: The field of the message to set, it shuold be a member of 330 field: The field of the message to set, it shuold be a member of
302 group_message.DESCRIPTOR.fields. 331 group_message.DESCRIPTOR.fields.
303 field_value: The value to set. 332 field_value: The value to set.
304 ''' 333 '''
305 if field.label == field.LABEL_REPEATED: 334 if field.type == field.TYPE_BOOL:
335 assert type(field_value) == bool
336 elif field.type == field.TYPE_STRING:
337 assert type(field_value) == str
338 elif field.type == field.TYPE_INT64:
339 assert type(field_value) == int
340 elif (field.type == field.TYPE_MESSAGE and
341 field.message_type.name == 'StringList'):
306 assert type(field_value) == list 342 assert type(field_value) == list
307 assert field.type == field.TYPE_STRING 343 entries = group_message.__getattribute__(field.name).entries
308 list_field = group_message.__getattribute__(field.name)
309 for list_item in field_value: 344 for list_item in field_value:
310 list_field.append(list_item) 345 entries.append(list_item)
346 return
311 else: 347 else:
312 # Simple cases: 348 raise Exception('Unknown field type %s' % field.type)
313 if field.type == field.TYPE_BOOL: 349 group_message.__setattr__(field.name, field_value)
314 assert type(field_value) == bool
315 elif field.type == field.TYPE_STRING:
316 assert type(field_value) == str
317 elif field.type == field.TYPE_INT64:
318 assert type(field_value) == int
319 else:
320 raise Exception('Unknown field type %s' % field.type_name)
321 group_message.__setattr__(field.name, field_value)
322 350
323 def GatherPolicySettings(self, settings, policies): 351 def GatherPolicySettings(self, settings, policies):
324 '''Copies all the policies from a dictionary into a protobuf of type 352 '''Copies all the policies from a dictionary into a protobuf of type
325 CloudPolicySettings. 353 CloudPolicySettings.
326 354
327 Args: 355 Args:
328 settings: The destination: a CloudPolicySettings protobuf. 356 settings: The destination: a CloudPolicySettings protobuf.
329 policies: The source: a dictionary containing policies under keys 357 policies: The source: a dictionary containing policies under keys
330 'recommended' and 'mandatory'. 358 'recommended' and 'mandatory'.
331 ''' 359 '''
(...skipping 13 matching lines...) Expand all
345 group_message.policy_options.mode = cp.PolicyOptions.MANDATORY 373 group_message.policy_options.mode = cp.PolicyOptions.MANDATORY
346 field_value = policies['mandatory'][field.name] 374 field_value = policies['mandatory'][field.name]
347 elif field.name in policies['recommended']: 375 elif field.name in policies['recommended']:
348 field_value = policies['recommended'][field.name] 376 field_value = policies['recommended'][field.name]
349 if field_value != None: 377 if field_value != None:
350 got_fields = True 378 got_fields = True
351 self.SetProtobufMessageField(group_message, field, field_value) 379 self.SetProtobufMessageField(group_message, field, field_value)
352 if got_fields: 380 if got_fields:
353 settings.__getattribute__(group.name).CopyFrom(group_message) 381 settings.__getattribute__(group.name).CopyFrom(group_message)
354 382
355 def ProcessCloudPolicyRequest(self, msg): 383 def ProcessCloudPolicy(self, msg):
356 """Handles a cloud policy request. (New protocol for policy requests.) 384 """Handles a cloud policy request. (New protocol for policy requests.)
357 385
358 Checks for authorization, encodes the policy into protobuf representation, 386 Checks for authorization, encodes the policy into protobuf representation,
359 signs it and constructs the repsonse. 387 signs it and constructs the repsonse.
360 388
361 Args: 389 Args:
362 msg: The CloudPolicyRequest message received from the client. 390 msg: The CloudPolicyRequest message received from the client.
363 391
364 Returns: 392 Returns:
365 A tuple of HTTP status code and response data to send to the client. 393 A tuple of HTTP status code and response data to send to the client.
366 """ 394 """
367 token, response = self.CheckToken() 395
368 if not token: 396 token_info, error = self.CheckToken()
369 return response 397 if not token_info:
398 return error
370 399
371 settings = cp.CloudPolicySettings() 400 settings = cp.CloudPolicySettings()
372 401
373 if msg.policy_scope in self._server.policy: 402 if (msg.policy_type in token_info['allowed_policy_types'] and
374 # Respond is only given if the scope is specified in the config file. 403 msg.policy_type in self._server.policy):
404 # Response is only given if the scope is specified in the config file.
375 # Normally 'chromeos/device' and 'chromeos/user' should be accepted. 405 # Normally 'chromeos/device' and 'chromeos/user' should be accepted.
376 self.GatherPolicySettings(settings, 406 self.GatherPolicySettings(settings,
377 self._server.policy[msg.policy_scope]) 407 self._server.policy[msg.policy_type])
378 408
379 # Construct response 409 policy_data = dm.PolicyData()
380 signed_response = dm.SignedCloudPolicyResponse() 410 policy_data.policy_value = settings.SerializeToString()
381 signed_response.settings.CopyFrom(settings) 411 policy_data.policy_type = msg.policy_type
382 signed_response.timestamp = int(time.time()) 412 policy_data.timestamp = int(time.time() * 1000)
383 signed_response.request_token = token; 413 policy_data.request_token = token_info['device_token'];
384 signed_response.device_name = self.GetDeviceName() 414 policy_data.machine_name = token_info['machine_name']
385 415 signed_data = policy_data.SerializeToString()
386 cloud_response = dm.CloudPolicyResponse()
387 cloud_response.signed_response = signed_response.SerializeToString()
388 signed_data = cloud_response.signed_response
389 cloud_response.signature = (
390 self._server.private_key.hashAndSign(signed_data).tostring())
391 for certificate in self._server.cert_chain:
392 cloud_response.certificate_chain.append(
393 certificate.writeBytes().tostring())
394 416
395 response = dm.DeviceManagementResponse() 417 response = dm.DeviceManagementResponse()
396 response.error = dm.DeviceManagementResponse.SUCCESS 418 response.error = dm.DeviceManagementResponse.SUCCESS
397 response.cloud_policy_response.CopyFrom(cloud_response) 419 fetch_response = response.policy_response.response.add()
420 fetch_response.policy_data = signed_data
421 fetch_response.policy_data_signature = (
422 self._server.private_key.hashAndSign(signed_data).tostring())
423 for certificate in self._server.cert_chain:
424 fetch_response.certificate_chain.append(
425 certificate.writeBytes().tostring())
398 426
399 self.DumpMessage('Response', response) 427 self.DumpMessage('Response', response)
400 428
401 return (200, response.SerializeToString()) 429 return (200, response.SerializeToString())
402 430
403 def CheckToken(self): 431 def CheckToken(self):
404 """Helper for checking whether the client supplied a valid DM token. 432 """Helper for checking whether the client supplied a valid DM token.
405 433
406 Extracts the token from the request and passed to the server in order to 434 Extracts the token from the request and passed to the server in order to
407 look up the client. Returns a pair of token and error response. If the token 435 look up the client.
408 is None, the error response is a pair of status code and error message.
409 436
410 Returns: 437 Returns:
411 A pair of DM token and error response. If the token is None, the message 438 A pair of token information record and error response. If the first
412 will contain the error response to send back. 439 element is None, then the second contains an error code to send back to
440 the client. Otherwise the first element is the same structure that is
441 returned by LookupToken().
413 """ 442 """
414 error = None 443 error = None
415 dmtoken = None 444 dmtoken = None
416 request_device_id = self.GetUniqueParam('deviceid') 445 request_device_id = self.GetUniqueParam('deviceid')
417 match = re.match('GoogleDMToken token=(\\w+)', 446 match = re.match('GoogleDMToken token=(\\w+)',
418 self._headers.getheader('Authorization', '')) 447 self._headers.getheader('Authorization', ''))
419 if match: 448 if match:
420 dmtoken = match.group(1) 449 dmtoken = match.group(1)
421 if not dmtoken: 450 if not dmtoken:
422 error = dm.DeviceManagementResponse.DEVICE_MANAGEMENT_TOKEN_INVALID 451 error = dm.DeviceManagementResponse.DEVICE_MANAGEMENT_TOKEN_INVALID
423 elif (not request_device_id or
424 not self._server.LookupDevice(dmtoken) == request_device_id):
425 error = dm.DeviceManagementResponse.DEVICE_NOT_FOUND
426 else: 452 else:
427 return (dmtoken, None) 453 token_info = self._server.LookupToken(dmtoken)
454 if (not token_info or
455 not request_device_id or
456 token_info['device_id'] != request_device_id):
457 error = dm.DeviceManagementResponse.DEVICE_NOT_FOUND
458 else:
459 return (token_info, None)
428 460
429 response = dm.DeviceManagementResponse() 461 response = dm.DeviceManagementResponse()
430 response.error = error 462 response.error = error
431 463
432 self.DumpMessage('Response', response) 464 self.DumpMessage('Response', response)
433 465
434 return (None, (200, response.SerializeToString())) 466 return (None, (200, response.SerializeToString()))
435 467
436 def DumpMessage(self, label, msg): 468 def DumpMessage(self, label, msg):
437 """Helper for logging an ASCII dump of a protobuf message.""" 469 """Helper for logging an ASCII dump of a protobuf message."""
438 logging.debug('%s\n%s' % (label, str(msg))) 470 logging.debug('%s\n%s' % (label, str(msg)))
439 471
440 class TestServer(object): 472 class TestServer(object):
441 """Handles requests and keeps global service state.""" 473 """Handles requests and keeps global service state."""
442 474
443 def __init__(self, policy_path, policy_cert_chain): 475 def __init__(self, policy_path, policy_cert_chain):
444 """Initializes the server. 476 """Initializes the server.
445 477
446 Args: 478 Args:
447 policy_path: Names the file to read JSON-formatted policy from. 479 policy_path: Names the file to read JSON-formatted policy from.
448 policy_cert_chain: List of paths to X.509 certificate files of the 480 policy_cert_chain: List of paths to X.509 certificate files of the
449 certificate chain used for signing responses. 481 certificate chain used for signing responses.
450 """ 482 """
451 self._registered_devices = {} 483 self._registered_tokens = {}
452 self.policy = {} 484 self.policy = {}
453 if json is None: 485 if json is None:
454 print 'No JSON module, cannot parse policy information' 486 print 'No JSON module, cannot parse policy information'
455 else : 487 else :
456 try: 488 try:
457 self.policy = json.loads(open(policy_path).read()) 489 self.policy = json.loads(open(policy_path).read())
458 except IOError: 490 except IOError:
459 print 'Failed to load policy from %s' % policy_path 491 print 'Failed to load policy from %s' % policy_path
460 492
461 self.private_key = None 493 self.private_key = None
(...skipping 16 matching lines...) Expand all
478 Args: 510 Args:
479 path: The request path and query parameters received from the client. 511 path: The request path and query parameters received from the client.
480 headers: A rfc822.Message-like object containing HTTP headers. 512 headers: A rfc822.Message-like object containing HTTP headers.
481 request: The request data received from the client as a string. 513 request: The request data received from the client as a string.
482 Returns: 514 Returns:
483 A pair of HTTP status code and response data to send to the client. 515 A pair of HTTP status code and response data to send to the client.
484 """ 516 """
485 handler = RequestHandler(self, path, headers, request) 517 handler = RequestHandler(self, path, headers, request)
486 return handler.HandleRequest() 518 return handler.HandleRequest()
487 519
488 def RegisterDevice(self, device_id): 520 def RegisterDevice(self, device_id, machine_id, type):
489 """Registers a device and generate a DM token for it. 521 """Registers a device or user and generates a DM token for it.
490 522
491 Args: 523 Args:
492 device_id: The device identifier provided by the client. 524 device_id: The device identifier provided by the client.
493 525
494 Returns: 526 Returns:
495 The newly generated device token for the device. 527 The newly generated device token for the device.
496 """ 528 """
497 dmtoken_chars = [] 529 dmtoken_chars = []
498 while len(dmtoken_chars) < 32: 530 while len(dmtoken_chars) < 32:
499 dmtoken_chars.append(random.choice('0123456789abcdef')) 531 dmtoken_chars.append(random.choice('0123456789abcdef'))
500 dmtoken = ''.join(dmtoken_chars) 532 dmtoken = ''.join(dmtoken_chars)
501 self._registered_devices[dmtoken] = device_id 533 allowed_policy_types = {
502 return dmtoken 534 dm.DeviceRegisterRequest.USER: ['google/chromeos/user'],
535 dm.DeviceRegisterRequest.DEVICE: ['google/chromeos/device'],
536 dm.DeviceRegisterRequest.TT: ['google/chromeos/user'],
537 }
538 self._registered_tokens[dmtoken] = {
539 'device_id': device_id,
540 'device_token': dmtoken,
541 'allowed_policy_types': allowed_policy_types[type],
542 'machine_name': 'chromeos-' + machine_id,
543 }
544 return self._registered_tokens[dmtoken]
503 545
504 def LookupDevice(self, dmtoken): 546 def LookupToken(self, dmtoken):
505 """Looks up a device by DMToken. 547 """Looks up a device or a user by DM token.
506 548
507 Args: 549 Args:
508 dmtoken: The device management token provided by the client. 550 dmtoken: The device management token provided by the client.
509 551
510 Returns: 552 Returns:
511 The corresponding device identifier or None if not found. 553 A dictionary with information about a device or user that is registered by
554 dmtoken, or None if the token is not found.
512 """ 555 """
513 return self._registered_devices.get(dmtoken, None) 556 return self._registered_tokens.get(dmtoken, None)
514 557
515 def UnregisterDevice(self, dmtoken): 558 def UnregisterDevice(self, dmtoken):
516 """Unregisters a device identified by the given DM token. 559 """Unregisters a device identified by the given DM token.
517 560
518 Args: 561 Args:
519 dmtoken: The device management token provided by the client. 562 dmtoken: The device management token provided by the client.
520 """ 563 """
521 if dmtoken in self._registered_devices: 564 if dmtoken in self._registered_tokens.keys():
522 del self._registered_devices[dmtoken] 565 del self._registered_tokens[dmtoken]
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698