def _create_listener(self, content_type, body, *args, **kwargs):
        if content_type != 'application/json':
            raise qvarn.NotJson(content_type)

        rt = self._listener_coll.get_type()
        validator = qvarn.Validator()
        try:
            validator.validate_against_prototype(rt.get_type(), body,
                                                 rt.get_latest_prototype())
        except qvarn.ValidationError as e:
            qvarn.log.log('error', msg_text=str(e), body=body)
            return qvarn.bad_request_response(str(e))

        if 'type' not in body:
            body['type'] = 'listener'

        rtype = self._parent_coll.get_type_name()
        if body.get('listen_on_type', rtype) != rtype:
            return qvarn.bad_request_response(
                'listen_on_type does not have value {}'.format(rtype))
        body['listen_on_type'] = rtype

        id_allowed = self._api.is_id_allowed(kwargs.get('claims', {}))
        if id_allowed:
            result_body = self._listener_coll.post_with_id(body)
        else:
            result_body = self._listener_coll.post(body)
        location = self._get_new_resource_location(result_body)
        qvarn.log.log('debug',
                      msg_text='POST a new listener, result',
                      body=result_body,
                      location=location)
        return qvarn.created_response(result_body, location)
Beispiel #2
0
 def __init__(self):
     self._store = None
     self._validator = qvarn.Validator()
     self._baseurl = None
     self._rt_coll = None
     self._notifs = None
     self._alog = None
Beispiel #3
0
    def put(self, obj, claims=None, access_params=None):
        v = qvarn.Validator()
        v.validate_resource_update(obj, self.get_type())

        old = self.get(obj['id'], claims=claims, access_params=access_params)
        if old['revision'] != obj['revision']:
            raise WrongRevision(obj['revision'], old['revision'])

        new_obj = dict(obj)
        new_obj['revision'] = self._invent_id('revision')
        self._store.remove_objects(obj_id=new_obj['id'], subpath='')
        self._create_object(new_obj, obj_id=new_obj['id'], subpath='')

        return new_obj
Beispiel #4
0
    def _update(self, content_type, body, *args, **kwargs):
        qvarn.log.log('trace', msg_text='_update', kwargs=kwargs)
        claims = kwargs.get('claims')
        params = self.get_access_params(self._coll.get_type_name(), claims)

        if content_type != 'application/json':
            raise qvarn.NotJson(content_type)

        if 'type' not in body:
            body['type'] = self._coll.get_type_name()

        if 'id' not in body:
            body['id'] = kwargs['id']

        validator = qvarn.Validator()
        try:
            validator.validate_resource_update(body, self._coll.get_type())
        except qvarn.ValidationError as e:
            qvarn.log.log('error', msg_text=str(e), body=body)
            return qvarn.bad_request_response(str(e))

        obj_id = kwargs['id']
        # FIXME: the following test should be enabled once we
        # no longer need test-api.
        if False and body['id'] != obj_id:
            raise qvarn.IdMismatch(body['id'], obj_id)
        try:
            result_body = self._coll.put(body,
                                         claims=claims,
                                         access_params=params)
        except qvarn.WrongRevision as e:
            return qvarn.conflict_response(str(e))
        except qvarn.NoSuchResource as e:
            # We intentionally say bad request, instead of not found.
            # This is to be compatible with old Qvarn. This may get
            # changed later.
            return qvarn.bad_request_response(str(e))

        self._notify(result_body['id'], result_body['revision'], 'updated')
        self._log_access(
            result_body,
            result_body.get('type'),
            'PUT',
            # FIXME: add header getting to apifw
            bottle.request.get_header('Authorization', ''),
            bottle.request.get_header('Qvarn-Token', ''),
            bottle.request.get_header('Qvarn-Access-By', ''),
            bottle.request.get_header('Qvarn-Why', None))

        return qvarn.ok_response(result_body)
Beispiel #5
0
    def _put_subresource(self, content_type, body, *args, **kwargs):
        claims = kwargs.get('claims')
        params = self.get_access_params(self._parent_coll.get_type_name(),
                                        claims)

        if content_type != 'application/json':
            raise qvarn.NotJson(content_type)

        obj_id = kwargs['id']

        if 'revision' not in body:
            return qvarn.bad_request_response('must have revision')
        revision = body.pop('revision')

        id_allowed = self._api.is_id_allowed(kwargs.get('claims', {}))

        rt = self._parent_coll.get_type()
        validator = qvarn.Validator()
        try:
            validator.validate_subresource(self._subpath, rt, body)
        except qvarn.ValidationError as e:
            qvarn.log.log('error', msg_text=str(e), body=body)
            return qvarn.bad_request_response(str(e))

        try:
            if id_allowed:
                func = self._parent_coll.put_subresource_no_new_revision
            else:
                func = self._parent_coll.put_subresource
            result_body = func(body,
                               subpath=self._subpath,
                               obj_id=obj_id,
                               revision=revision,
                               claims=claims,
                               access_params=params)
        except qvarn.WrongRevision as e:
            return qvarn.conflict_response(str(e))
        except qvarn.NoSuchResource as e:
            return qvarn.no_such_resource_response(str(e))

        return qvarn.ok_response(result_body)
Beispiel #6
0
    def _create(self, content_type, body, *args, **kwargs):
        if content_type != 'application/json':
            raise qvarn.NotJson(content_type)

        if 'type' not in body:
            body['type'] = self._coll.get_type_name()

        id_allowed = self._api.is_id_allowed(kwargs.get('claims', {}))

        validator = qvarn.Validator()
        try:
            if id_allowed:
                validator.validate_new_resource_with_id(
                    body, self._coll.get_type())
            else:
                validator.validate_new_resource(body, self._coll.get_type())
        except (qvarn.HasId, qvarn.HasRevision) as e:
            qvarn.log.log('error', msg_text=str(e), body=body)
            return qvarn.bad_request_response(str(e))
        except qvarn.ValidationError as e:
            qvarn.log.log('error', msg_text=str(e), body=body)
            return qvarn.bad_request_response(str(e))

        result_body = self._coll.post_with_id(body)
        location = '{}{}/{}'.format(self._baseurl,
                                    self._coll.get_type().get_path(),
                                    result_body['id'])

        self._notify(result_body['id'], result_body['revision'], 'created')
        self._log_access(
            result_body,
            result_body.get('type'),
            'POST',
            # FIXME: add header getting to apifw
            bottle.request.get_header('Authorization', ''),
            bottle.request.get_header('Qvarn-Token', ''),
            bottle.request.get_header('Qvarn-Access-By', ''),
            bottle.request.get_header('Qvarn-Why', None))

        return qvarn.created_response(result_body, location)
Beispiel #7
0
    def setUp(self):
        self.spec = {
            'type': 'foo',
            'path': '/foos',
            'versions': [
                {
                    'version': 'v0',
                    'prototype': {
                        'type': '',
                        'id': '',
                        'revision': '',
                        'foo': '',
                    },
                    'subpaths': {
                        'sub': {
                            'prototype': {
                                'subfield': '',
                            },
                        },
                    },
                },
            ]
        }

        self.resource_type = qvarn.ResourceType()
        self.resource_type.from_spec(self.spec)

        self.validator = qvarn.Validator()

        self.resource = {
            'type': 'foo',
            'id': 'resource-1',
            'revision': 'revision-1',
            'foo': 'this is foo',
        }

        self.subresource = {
            'subfield': 'bananarama',
        }
    def _update_listener(self, content_type, body, *args, **kwargs):
        claims = kwargs.get('claims')
        params = self.get_access_params(self._listener_coll.get_type_name(),
                                        claims)

        if content_type != 'application/json':
            raise qvarn.NotJson(content_type)

        if 'type' not in body:
            body['type'] = 'listener'

        listener_id = kwargs['listener_id']
        if 'id' not in body:
            body['id'] = listener_id

        validator = qvarn.Validator()
        try:
            validator.validate_resource_update(body,
                                               self._listener_coll.get_type())
        except qvarn.ValidationError as e:
            qvarn.log.log('error', msg_text=str(e), body=body)
            return qvarn.bad_request_response(str(e))

        try:
            result_body = self._listener_coll.put(body,
                                                  claims=claims,
                                                  access_params=params)
        except qvarn.WrongRevision as e:
            return qvarn.conflict_response(str(e))
        except qvarn.NoSuchResource as e:
            # We intentionally say bad request, instead of not found.
            # This is to be compatible with old Qvarn. This may get
            # changed later.
            return qvarn.bad_request_response(str(e))

        return qvarn.ok_response(result_body)
Beispiel #9
0
 def post_with_id(self, obj):  # pragma: no cover
     v = qvarn.Validator()
     v.validate_new_resource_with_id(obj, self.get_type())
     result = self._post_helper(obj)
     return result
Beispiel #10
0
 def post(self, obj):
     v = qvarn.Validator()
     v.validate_new_resource(obj, self.get_type())
     return self._post_helper(obj)