def testInsert(self): """Tests that we can create a new ticket.""" self.mox.StubOutWithMock(common_util, 'parse_serialized_json') common_util.parse_serialized_json().AndReturn({'userEmail': 'me'}) self.mox.StubOutWithMock(common_util, 'grab_header_field') common_util.grab_header_field('Authorization').AndReturn( 'Bearer %s' % self.registration.TEST_ACCESS_TOKEN) self.mox.ReplayAll() returned_json = self.registration.POST() self.assertIn('id', returned_json) self.mox.VerifyAll()
def testPatchTicket(self): """Tests that we correctly patch a ticket.""" expected_ticket = dict(id=1234, blah='hi') update_ticket = dict(blah='hi') self.tickets[(1234, None)] = dict(id=1234) self.mox.StubOutWithMock(common_util, 'parse_serialized_json') common_util.parse_serialized_json().AndReturn(update_ticket) self.mox.ReplayAll() returned_json = self.registration.PATCH(1234) self.assertEquals(expected_ticket, returned_json) self.mox.VerifyAll()
def testPatch(self): """Tests that we correctly patch a resource.""" expected_resource = dict(id=1234, blah='hi') update_resource = dict(blah='hi') self.resources[(1234, None)] = dict(id=1234) self.mox.StubOutWithMock(common_util, 'parse_serialized_json') common_util.parse_serialized_json().AndReturn(update_resource) self.mox.ReplayAll() returned_json = self.resource_method.PATCH(1234) self.assertEquals(expected_resource, returned_json) self.mox.VerifyAll()
def PUT(self, *args, **kwargs): """Replaces the given ticket with the incoming json blob. Format of this call is: PUT .../ticket_number Caller must define a json blob to patch the ticket with. Raises: """ self._fail_control_handler.ensure_not_in_failure_mode() id, api_key, _ = common_util.parse_common_args(args, kwargs) if not id: server_errors.HTTPError(400, 'Missing id for operation') data = common_util.parse_serialized_json() # Handle claiming a ticket with an authorized request. if data and data.get('userEmail') == 'me': self._add_claim_data(data) return self.resource.update_data_val(id, api_key, data_in=data, update=False)
def POST(self, *args, **kwargs): """Creates a new command using the incoming json data.""" # TODO(wiley) We could check authorization here, which should be # a client/owner of the device. self._fail_control_handler.ensure_not_in_failure_mode() data = common_util.parse_serialized_json() if not data: raise server_errors.HTTPError(400, 'Require JSON body') return self.create_command(data)
def testParseSerializeJson(self): """Tests that we can seralize / deserialize json from cherrypy.""" json_data = json.dumps(dict(a='b', b='c')) json_file = tempfile.TemporaryFile() json_file.write(json.dumps(json_data)) content_length = json_file.tell() json_file.seek(0) cherrypy.request.headers['Content-Length'] = content_length cherrypy.request.rfile = json_file self.assertEquals(common_util.parse_serialized_json(), json_data) json_file.close() # Also test the edge case without an input file. json_file = tempfile.TemporaryFile() cherrypy.request.rfile = json_file self.assertEquals(common_util.parse_serialized_json(), None) json_file.close()
def testReplaceTicket(self): """Tests that we correctly replace a ticket.""" update_ticket = dict(id=12345, blah='hi') self.tickets[(12345, None)] = dict(id=12345) self.mox.StubOutWithMock(common_util, 'parse_serialized_json') common_util.parse_serialized_json().AndReturn(update_ticket) self.mox.ReplayAll() returned_json = self.registration.PUT(12345) self.assertEquals(update_ticket, returned_json) self.mox.VerifyAll() self.mox.ResetAll() # Ticket id doesn't match. update_ticket = dict(id=12346, blah='hi') common_util.parse_serialized_json().AndReturn(update_ticket) self.mox.ReplayAll() self.assertRaises(server_errors.HTTPError, self.registration.PUT, 12345) self.mox.VerifyAll()
def PATCH(self, *args, **kwargs): """Updates the given resource with the incoming json blob. Format of this call is: PATCH .../resource_id Caller must define a json blob to patch the resource with. Raises: server_errors.HTTPError if the resource doesn't exist. """ id, api_key, _ = common_util.parse_common_args(args, kwargs) if not id: server_errors.HTTPError(400, 'Missing id for operation') data = common_util.parse_serialized_json() return self.resource.update_data_val(id, api_key, data_in=data)
def POST(self, *args, **kwargs): """Either creates a ticket OR claim/finalizes a ticket. This method implements the majority of the registration workflow. More specifically: POST ... creates a new ticket POST .../ticket_number/claim claims a given ticket with a fake email. POST .../ticket_number/finalize finalizes a ticket with a robot account. Raises: server_errors.HTTPError if the ticket should exist but doesn't (claim/finalize) or if we can't parse all the args. """ self._fail_control_handler.ensure_not_in_failure_mode() id, api_key, operation = common_util.parse_common_args( args, kwargs, supported_operations=set(['finalize'])) if operation: ticket = self.resource.get_data_val(id, api_key) if operation == 'finalize': return self._finalize(id, api_key, ticket) else: raise server_errors.HTTPError( 400, 'Unsupported method call %s' % operation) else: data = common_util.parse_serialized_json() if data is None or data.get('userEmail', None) != 'me': raise server_errors.HTTPError( 400, 'Require userEmail=me to create ticket %s' % operation) if [key for key in data.iterkeys() if key != 'userEmail']: raise server_errors.HTTPError( 400, 'Extra data for ticket creation: %r.' % data) if id: raise server_errors.HTTPError(400, 'Should not specify ticket ID.') self._add_claim_data(data) # We have an insert operation so make sure we have all required # fields. data.update(self._default_registration_ticket()) logging.info('Ticket is being created.') return self.resource.update_data_val(id, api_key, data_in=data)
def PATCH(self, *args, **kwargs): """Updates the given ticket with the incoming json blob. Format of this call is: PATCH .../ticket_number Caller must define a json blob to patch the ticket with. Raises: server_errors.HTTPError if the ticket doesn't exist. """ self._fail_control_handler.ensure_not_in_failure_mode() id, api_key, _ = common_util.parse_common_args(args, kwargs) if not id: server_errors.HTTPError(400, 'Missing id for operation') data = common_util.parse_serialized_json() return self.resource.update_data_val(id, api_key, data_in=data)
def POST(self, *args, **kwargs): """Handle POSTs for a device. Supported APIs include: POST /devices/<device-id>/patchState """ self._fail_control_handler.ensure_not_in_failure_mode() args = list(args) device_id = args.pop(0) if args else None operation = args.pop(0) if args else None if device_id is None or operation != 'patchState': raise server_errors.HTTPError(400, 'Unsupported operation.') data = common_util.parse_serialized_json() access_token = common_util.get_access_token() api_key = self._oauth.get_api_key_from_access_token(access_token) self._handle_state_patch(device_id, api_key, data) return {'state': self.resource.get_data_val(device_id, api_key)['state']}
def PUT(self, *args, **kwargs): """Update an existing device using the incoming json data. On startup, devices make a request like: PUT http://<server-host>/devices/<device-id> {'channel': {'supportedType': 'xmpp'}, 'commandDefs': {}, 'description': 'test_description ', 'displayName': 'test_display_name ', 'id': '4471f7', 'location': 'test_location ', 'name': 'test_device_name', 'state': {'base': {'firmwareVersion': '6771.0.2015_02_09_1429', 'isProximityTokenRequired': False, 'localDiscoveryEnabled': False, 'manufacturer': '', 'model': '', 'serialNumber': '', 'supportUrl': '', 'updateUrl': ''}}} This PUT has no API key, but comes with an OAUTH access token. """ self._fail_control_handler.ensure_not_in_failure_mode() device_id, _, _ = common_util.parse_common_args(args, kwargs) access_token = common_util.get_access_token() if not access_token: raise server_errors.HTTPError(401, 'Access denied.') api_key = self._oauth.get_api_key_from_access_token(access_token) data = common_util.parse_serialized_json() self._validate_device_resource(data) logging.info('Updating device with id=%s and device_config=%r', device_id, data) new_device = self.resource.update_data_val(device_id, api_key, data_in=data) return data