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

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: more last minute changes 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
« no previous file with comments | « chrome/tools/build/generate_policy_source.py ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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. 255 """Handles a policy request that uses the deprecated protcol.
256 TODO(gfeher): Remove this when we certainly don't need it.
245 257
246 Checks for authorization, encodes the policy into protobuf representation 258 Checks for authorization, encodes the policy into protobuf representation
247 and constructs the response. 259 and constructs the response.
248 260
249 Args: 261 Args:
250 msg: The DevicePolicyRequest message received from the client. 262 msg: The DevicePolicyRequest message received from the client.
251 263
252 Returns: 264 Returns:
253 A tuple of HTTP status code and response data to send to the client. 265 A tuple of HTTP status code and response data to send to the client.
254 """ 266 """
267
255 # Check the management token. 268 # Check the management token.
256 token, response = self.CheckToken() 269 token, response = self.CheckToken()
257 if not token: 270 if not token:
258 return response 271 return response
259 272
260 # Stuff the policy dictionary into a response message and send it back. 273 # Stuff the policy dictionary into a response message and send it back.
261 response = dm.DeviceManagementResponse() 274 response = dm.DeviceManagementResponse()
262 response.error = dm.DeviceManagementResponse.SUCCESS 275 response.error = dm.DeviceManagementResponse.SUCCESS
263 response.policy_response.CopyFrom(dm.DevicePolicyResponse()) 276 response.policy_response.CopyFrom(dm.DevicePolicyResponse())
264 277
265 # Respond only if the client requested policy for the cros/device scope, 278 # Respond only if the client requested policy for the cros/device scope,
266 # since that's where chrome policy is supposed to live in. 279 # since that's where chrome policy is supposed to live in.
267 if msg.policy_scope in self._server.policy: 280 if msg.policy_scope == 'chromeos/device':
268 policy = self._server.policy[msg.policy_scope]['mandatory'] 281 policy = self._server.policy['google/chromeos/user']['mandatory']
269 setting = response.policy_response.setting.add() 282 setting = response.policy_response.setting.add()
270 setting.policy_key = 'chrome-policy' 283 setting.policy_key = 'chrome-policy'
271 policy_value = dm.GenericSetting() 284 policy_value = dm.GenericSetting()
272 for (key, value) in policy.iteritems(): 285 for (key, value) in policy.iteritems():
273 entry = policy_value.named_value.add() 286 entry = policy_value.named_value.add()
274 entry.name = key 287 entry.name = key
275 entry_value = dm.GenericValue() 288 entry_value = dm.GenericValue()
276 if isinstance(value, bool): 289 if isinstance(value, bool):
277 entry_value.value_type = dm.GenericValue.VALUE_TYPE_BOOL 290 entry_value.value_type = dm.GenericValue.VALUE_TYPE_BOOL
278 entry_value.bool_value = value 291 entry_value.bool_value = value
279 elif isinstance(value, int): 292 elif isinstance(value, int):
280 entry_value.value_type = dm.GenericValue.VALUE_TYPE_INT64 293 entry_value.value_type = dm.GenericValue.VALUE_TYPE_INT64
281 entry_value.int64_value = value 294 entry_value.int64_value = value
282 elif isinstance(value, str) or isinstance(value, unicode): 295 elif isinstance(value, str) or isinstance(value, unicode):
283 entry_value.value_type = dm.GenericValue.VALUE_TYPE_STRING 296 entry_value.value_type = dm.GenericValue.VALUE_TYPE_STRING
284 entry_value.string_value = value 297 entry_value.string_value = value
285 elif isinstance(value, list): 298 elif isinstance(value, list):
286 entry_value.value_type = dm.GenericValue.VALUE_TYPE_STRING_ARRAY 299 entry_value.value_type = dm.GenericValue.VALUE_TYPE_STRING_ARRAY
287 for list_entry in value: 300 for list_entry in value:
288 entry_value.string_array.append(str(list_entry)) 301 entry_value.string_array.append(str(list_entry))
289 entry.value.CopyFrom(entry_value) 302 entry.value.CopyFrom(entry_value)
290 setting.policy_value.CopyFrom(policy_value) 303 setting.policy_value.CopyFrom(policy_value)
291 304
292 self.DumpMessage('Response', response) 305 self.DumpMessage('Response', response)
293 306
294 return (200, response.SerializeToString()) 307 return (200, response.SerializeToString())
295 308
309 def ProcessPolicy(self, msg, request_type):
310 """Handles a policy request.
311
312 Checks for authorization, encodes the policy into protobuf representation
313 and constructs the response.
314
315 Args:
316 msg: The DevicePolicyRequest message received from the client.
317
318 Returns:
319 A tuple of HTTP status code and response data to send to the client.
320 """
321
322 if msg.request:
323 for request in msg.request:
324 if request.policy_type == 'google/chromeos/unregistered_user':
325 if request_type != 'ping':
326 return (400, 'Invalid request type')
327 return self.ProcessInitialPolicy(request)
328 elif (request.policy_type in
329 ('google/chromeos/user', 'google/chromeos/device')):
330 if request_type != 'policy':
331 return (400, 'Invalid request type')
332 return self.ProcessCloudPolicy(request)
333 else:
334 return (400, 'Invalid policy_type')
335 else:
336 return self.ProcessDevicePolicy(msg)
337
296 def SetProtobufMessageField(self, group_message, field, field_value): 338 def SetProtobufMessageField(self, group_message, field, field_value):
297 '''Sets a field in a protobuf message. 339 '''Sets a field in a protobuf message.
298 340
299 Args: 341 Args:
300 group_message: The protobuf message. 342 group_message: The protobuf message.
301 field: The field of the message to set, it shuold be a member of 343 field: The field of the message to set, it shuold be a member of
302 group_message.DESCRIPTOR.fields. 344 group_message.DESCRIPTOR.fields.
303 field_value: The value to set. 345 field_value: The value to set.
304 ''' 346 '''
305 if field.label == field.LABEL_REPEATED: 347 if field.type == field.TYPE_BOOL:
348 assert type(field_value) == bool
349 elif field.type == field.TYPE_STRING:
350 assert type(field_value) == str
351 elif field.type == field.TYPE_INT64:
352 assert type(field_value) == int
353 elif (field.type == field.TYPE_MESSAGE and
354 field.message_type.name == 'StringList'):
306 assert type(field_value) == list 355 assert type(field_value) == list
307 assert field.type == field.TYPE_STRING 356 entries = group_message.__getattribute__(field.name).entries
308 list_field = group_message.__getattribute__(field.name)
309 for list_item in field_value: 357 for list_item in field_value:
310 list_field.append(list_item) 358 entries.append(list_item)
359 return
311 else: 360 else:
312 # Simple cases: 361 raise Exception('Unknown field type %s' % field.type)
313 if field.type == field.TYPE_BOOL: 362 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 363
323 def GatherPolicySettings(self, settings, policies): 364 def GatherPolicySettings(self, settings, policies):
324 '''Copies all the policies from a dictionary into a protobuf of type 365 '''Copies all the policies from a dictionary into a protobuf of type
325 CloudPolicySettings. 366 CloudPolicySettings.
326 367
327 Args: 368 Args:
328 settings: The destination: a CloudPolicySettings protobuf. 369 settings: The destination: a CloudPolicySettings protobuf.
329 policies: The source: a dictionary containing policies under keys 370 policies: The source: a dictionary containing policies under keys
330 'recommended' and 'mandatory'. 371 'recommended' and 'mandatory'.
331 ''' 372 '''
(...skipping 13 matching lines...) Expand all
345 group_message.policy_options.mode = cp.PolicyOptions.MANDATORY 386 group_message.policy_options.mode = cp.PolicyOptions.MANDATORY
346 field_value = policies['mandatory'][field.name] 387 field_value = policies['mandatory'][field.name]
347 elif field.name in policies['recommended']: 388 elif field.name in policies['recommended']:
348 field_value = policies['recommended'][field.name] 389 field_value = policies['recommended'][field.name]
349 if field_value != None: 390 if field_value != None:
350 got_fields = True 391 got_fields = True
351 self.SetProtobufMessageField(group_message, field, field_value) 392 self.SetProtobufMessageField(group_message, field, field_value)
352 if got_fields: 393 if got_fields:
353 settings.__getattribute__(group.name).CopyFrom(group_message) 394 settings.__getattribute__(group.name).CopyFrom(group_message)
354 395
355 def ProcessCloudPolicyRequest(self, msg): 396 def ProcessCloudPolicy(self, msg):
356 """Handles a cloud policy request. (New protocol for policy requests.) 397 """Handles a cloud policy request. (New protocol for policy requests.)
357 398
358 Checks for authorization, encodes the policy into protobuf representation, 399 Checks for authorization, encodes the policy into protobuf representation,
359 signs it and constructs the repsonse. 400 signs it and constructs the repsonse.
360 401
361 Args: 402 Args:
362 msg: The CloudPolicyRequest message received from the client. 403 msg: The CloudPolicyRequest message received from the client.
363 404
364 Returns: 405 Returns:
365 A tuple of HTTP status code and response data to send to the client. 406 A tuple of HTTP status code and response data to send to the client.
366 """ 407 """
367 token, response = self.CheckToken() 408
368 if not token: 409 token_info, error = self.CheckToken()
369 return response 410 if not token_info:
411 return error
370 412
371 settings = cp.CloudPolicySettings() 413 settings = cp.CloudPolicySettings()
372 414
373 if msg.policy_scope in self._server.policy: 415 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. 416 msg.policy_type in self._server.policy):
417 # Response is only given if the scope is specified in the config file.
375 # Normally 'chromeos/device' and 'chromeos/user' should be accepted. 418 # Normally 'chromeos/device' and 'chromeos/user' should be accepted.
376 self.GatherPolicySettings(settings, 419 self.GatherPolicySettings(settings,
377 self._server.policy[msg.policy_scope]) 420 self._server.policy[msg.policy_type])
378 421
379 # Construct response 422 policy_data = dm.PolicyData()
380 signed_response = dm.SignedCloudPolicyResponse() 423 policy_data.policy_value = settings.SerializeToString()
381 signed_response.settings.CopyFrom(settings) 424 policy_data.policy_type = msg.policy_type
382 signed_response.timestamp = int(time.time()) 425 policy_data.timestamp = int(time.time() * 1000)
383 signed_response.request_token = token; 426 policy_data.request_token = token_info['device_token'];
384 signed_response.device_name = self.GetDeviceName() 427 policy_data.machine_name = token_info['machine_name']
385 428 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 429
395 response = dm.DeviceManagementResponse() 430 response = dm.DeviceManagementResponse()
396 response.error = dm.DeviceManagementResponse.SUCCESS 431 response.error = dm.DeviceManagementResponse.SUCCESS
397 response.cloud_policy_response.CopyFrom(cloud_response) 432 fetch_response = response.policy_response.response.add()
433 fetch_response.policy_data = signed_data
434 fetch_response.policy_data_signature = (
435 self._server.private_key.hashAndSign(signed_data).tostring())
436 for certificate in self._server.cert_chain:
437 fetch_response.certificate_chain.append(
438 certificate.writeBytes().tostring())
398 439
399 self.DumpMessage('Response', response) 440 self.DumpMessage('Response', response)
400 441
401 return (200, response.SerializeToString()) 442 return (200, response.SerializeToString())
402 443
403 def CheckToken(self): 444 def CheckToken(self):
404 """Helper for checking whether the client supplied a valid DM token. 445 """Helper for checking whether the client supplied a valid DM token.
405 446
406 Extracts the token from the request and passed to the server in order to 447 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 448 look up the client.
408 is None, the error response is a pair of status code and error message.
409 449
410 Returns: 450 Returns:
411 A pair of DM token and error response. If the token is None, the message 451 A pair of token information record and error response. If the first
412 will contain the error response to send back. 452 element is None, then the second contains an error code to send back to
453 the client. Otherwise the first element is the same structure that is
454 returned by LookupToken().
413 """ 455 """
414 error = None 456 error = None
415 dmtoken = None 457 dmtoken = None
416 request_device_id = self.GetUniqueParam('deviceid') 458 request_device_id = self.GetUniqueParam('deviceid')
417 match = re.match('GoogleDMToken token=(\\w+)', 459 match = re.match('GoogleDMToken token=(\\w+)',
418 self._headers.getheader('Authorization', '')) 460 self._headers.getheader('Authorization', ''))
419 if match: 461 if match:
420 dmtoken = match.group(1) 462 dmtoken = match.group(1)
421 if not dmtoken: 463 if not dmtoken:
422 error = dm.DeviceManagementResponse.DEVICE_MANAGEMENT_TOKEN_INVALID 464 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: 465 else:
427 return (dmtoken, None) 466 token_info = self._server.LookupToken(dmtoken)
467 if (not token_info or
468 not request_device_id or
469 token_info['device_id'] != request_device_id):
470 error = dm.DeviceManagementResponse.DEVICE_NOT_FOUND
471 else:
472 return (token_info, None)
428 473
429 response = dm.DeviceManagementResponse() 474 response = dm.DeviceManagementResponse()
430 response.error = error 475 response.error = error
431 476
432 self.DumpMessage('Response', response) 477 self.DumpMessage('Response', response)
433 478
434 return (None, (200, response.SerializeToString())) 479 return (None, (200, response.SerializeToString()))
435 480
436 def DumpMessage(self, label, msg): 481 def DumpMessage(self, label, msg):
437 """Helper for logging an ASCII dump of a protobuf message.""" 482 """Helper for logging an ASCII dump of a protobuf message."""
438 logging.debug('%s\n%s' % (label, str(msg))) 483 logging.debug('%s\n%s' % (label, str(msg)))
439 484
440 class TestServer(object): 485 class TestServer(object):
441 """Handles requests and keeps global service state.""" 486 """Handles requests and keeps global service state."""
442 487
443 def __init__(self, policy_path, policy_cert_chain): 488 def __init__(self, policy_path, policy_cert_chain):
444 """Initializes the server. 489 """Initializes the server.
445 490
446 Args: 491 Args:
447 policy_path: Names the file to read JSON-formatted policy from. 492 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 493 policy_cert_chain: List of paths to X.509 certificate files of the
449 certificate chain used for signing responses. 494 certificate chain used for signing responses.
450 """ 495 """
451 self._registered_devices = {} 496 self._registered_tokens = {}
452 self.policy = {} 497 self.policy = {}
453 if json is None: 498 if json is None:
454 print 'No JSON module, cannot parse policy information' 499 print 'No JSON module, cannot parse policy information'
455 else : 500 else :
456 try: 501 try:
457 self.policy = json.loads(open(policy_path).read()) 502 self.policy = json.loads(open(policy_path).read())
458 except IOError: 503 except IOError:
459 print 'Failed to load policy from %s' % policy_path 504 print 'Failed to load policy from %s' % policy_path
460 505
461 self.private_key = None 506 self.private_key = None
(...skipping 16 matching lines...) Expand all
478 Args: 523 Args:
479 path: The request path and query parameters received from the client. 524 path: The request path and query parameters received from the client.
480 headers: A rfc822.Message-like object containing HTTP headers. 525 headers: A rfc822.Message-like object containing HTTP headers.
481 request: The request data received from the client as a string. 526 request: The request data received from the client as a string.
482 Returns: 527 Returns:
483 A pair of HTTP status code and response data to send to the client. 528 A pair of HTTP status code and response data to send to the client.
484 """ 529 """
485 handler = RequestHandler(self, path, headers, request) 530 handler = RequestHandler(self, path, headers, request)
486 return handler.HandleRequest() 531 return handler.HandleRequest()
487 532
488 def RegisterDevice(self, device_id): 533 def RegisterDevice(self, device_id, machine_id, type):
489 """Registers a device and generate a DM token for it. 534 """Registers a device or user and generates a DM token for it.
490 535
491 Args: 536 Args:
492 device_id: The device identifier provided by the client. 537 device_id: The device identifier provided by the client.
493 538
494 Returns: 539 Returns:
495 The newly generated device token for the device. 540 The newly generated device token for the device.
496 """ 541 """
497 dmtoken_chars = [] 542 dmtoken_chars = []
498 while len(dmtoken_chars) < 32: 543 while len(dmtoken_chars) < 32:
499 dmtoken_chars.append(random.choice('0123456789abcdef')) 544 dmtoken_chars.append(random.choice('0123456789abcdef'))
500 dmtoken = ''.join(dmtoken_chars) 545 dmtoken = ''.join(dmtoken_chars)
501 self._registered_devices[dmtoken] = device_id 546 allowed_policy_types = {
502 return dmtoken 547 dm.DeviceRegisterRequest.USER: ['google/chromeos/user'],
548 dm.DeviceRegisterRequest.DEVICE: ['google/chromeos/device'],
549 dm.DeviceRegisterRequest.TT: ['google/chromeos/user'],
550 }
551 self._registered_tokens[dmtoken] = {
552 'device_id': device_id,
553 'device_token': dmtoken,
554 'allowed_policy_types': allowed_policy_types[type],
555 'machine_name': 'chromeos-' + machine_id,
556 }
557 return self._registered_tokens[dmtoken]
503 558
504 def LookupDevice(self, dmtoken): 559 def LookupToken(self, dmtoken):
505 """Looks up a device by DMToken. 560 """Looks up a device or a user by DM token.
506 561
507 Args: 562 Args:
508 dmtoken: The device management token provided by the client. 563 dmtoken: The device management token provided by the client.
509 564
510 Returns: 565 Returns:
511 The corresponding device identifier or None if not found. 566 A dictionary with information about a device or user that is registered by
567 dmtoken, or None if the token is not found.
512 """ 568 """
513 return self._registered_devices.get(dmtoken, None) 569 return self._registered_tokens.get(dmtoken, None)
514 570
515 def UnregisterDevice(self, dmtoken): 571 def UnregisterDevice(self, dmtoken):
516 """Unregisters a device identified by the given DM token. 572 """Unregisters a device identified by the given DM token.
517 573
518 Args: 574 Args:
519 dmtoken: The device management token provided by the client. 575 dmtoken: The device management token provided by the client.
520 """ 576 """
521 if dmtoken in self._registered_devices: 577 if dmtoken in self._registered_tokens.keys():
522 del self._registered_devices[dmtoken] 578 del self._registered_tokens[dmtoken]
OLDNEW
« no previous file with comments | « chrome/tools/build/generate_policy_source.py ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698