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)
Example #2
0
    def testParseCommonArgs(self):
        """Tests various flavors of the parse common args method."""
        id = 123456
        key = 'boogity'

        # Should parse all values.
        id, api_key, op = common_util.parse_common_args(
            (
                id,
                'boogity',
            ),
            dict(key=key),
            supported_operations=set(['boogity']))
        self.assertEquals(id, id)
        self.assertEquals(key, api_key)
        self.assertEquals('boogity', op)

        # Missing op.
        id, api_key, op = common_util.parse_common_args((id, ), dict(key=key))
        self.assertEquals(id, id)
        self.assertEquals(key, api_key)
        self.assertIsNone(op)

        # Missing key.
        id, api_key, op = common_util.parse_common_args((id, ), dict())
        self.assertEquals(id, id)
        self.assertIsNone(api_key)
        self.assertIsNone(op)

        # Missing all.
        id, api_key, op = common_util.parse_common_args(tuple(), dict())
        self.assertIsNone(id)
        self.assertIsNone(api_key)
        self.assertIsNone(op)

        # Too many args.
        self.assertRaises(server_errors.HTTPError,
                          common_util.parse_common_args, (
                              id,
                              'lame',
                              'stuff',
                          ), dict())

        # Operation when it's not expected.
        self.assertRaises(server_errors.HTTPError,
                          common_util.parse_common_args, (id, 'boogity'),
                          dict())
    def GET(self, *args, **kwargs):
        """GET .../ticket_number returns info about the ticket.

        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)
        return self.resource.get_data_val(id, api_key)
    def DELETE(self, *args, **kwargs):
        """Deletes the given device.

        Format of this call is:
        DELETE .../device_id

        Raises:
            server_errors.HTTPError if the device doesn't exist.
        """
        self._fail_control_handler.ensure_not_in_failure_mode()
        id, api_key, _ = common_util.parse_common_args(args, kwargs)
        self.resource.del_data_val(id, api_key)
        self.commands_instance.remove_device(id)
    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 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
    def GET(self, *args, **kwargs):
        """GET .../(device_id) gets device info or lists all devices.

        Supports both the GET / LIST commands for devices. List lists all
        devices a user has access to, however, this implementation just returns
        all devices.

        Raises:
            server_errors.HTTPError if the device doesn't exist.
        """
        self._fail_control_handler.ensure_not_in_failure_mode()
        id, api_key, _ = common_util.parse_common_args(args, kwargs)
        if not api_key:
            access_token = common_util.get_access_token()
            api_key = self._oauth.get_api_key_from_access_token(access_token)
        if id:
            return self.resource.get_data_val(id, api_key)
        else:
            # Returns listing (ignores optional parameters).
            listing = {'kind': 'clouddevices#devicesListResponse'}
            listing['devices'] = self.resource.get_data_vals()
            return listing