示例#1
0
    def _delete(self, *args, **kwargs):
        claims = kwargs.get('claims')
        params = self.get_access_params(self._coll.get_type_name(), claims)
        qvarn.log.log('trace',
                      msg_text='_delete callback',
                      claims=claims,
                      params=params)

        obj_id = kwargs['id']
        try:
            self._coll.delete(obj_id, claims=claims, access_params=params)
        except qvarn.NoSuchResource as e:
            return qvarn.no_such_resource_response(str(e))

        self._notify(obj_id, None, 'deleted')
        self._log_access(
            {'id': obj_id},
            self._coll.get_type_name(),
            'DELETE',
            # 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({})
示例#2
0
    def _has_rule(self, content_type, body, *args, **kwargs):
        if content_type != 'application/json':
            raise qvarn.NotJson(content_type)

        if self._store.has_allow_rule(body):
            return qvarn.ok_response(None)
        return qvarn.no_such_resource_response('')
示例#3
0
    def _search(self, *args, **kwargs):
        claims = kwargs.get('claims')
        params = self.get_access_params(self._coll.get_type_name(), claims)

        path = kwargs['raw_uri_path']
        search_criteria = path.split('/search/', 1)[1]
        try:
            result = self._coll.search(search_criteria,
                                       claims=claims,
                                       access_params=params)
        except qvarn.UnknownSearchField as e:
            return qvarn.unknown_search_field_response(e)
        except qvarn.NeedSortOperator:
            return qvarn.need_sort_response()
        except qvarn.SearchParserError as e:
            return qvarn.search_parser_error_response(e)

        for obj in result:
            self._log_access(
                obj,
                self._coll.get_type_name(),
                'SEARCH',
                # 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({'resources': result})
示例#4
0
    def _put_file(self, content_type, body, *args, **kwargs):
        claims = kwargs.get('claims')
        params = self.get_access_params(self._parent_coll.get_type_name(),
                                        claims)

        obj_id = kwargs['id']

        # FIXME: add header getting to apifw
        import bottle
        revision = bottle.request.get_header('Revision')

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

        obj = self._parent_coll.get(obj_id, allow_cond=qvarn.Yes())
        if not id_allowed and obj['revision'] != revision:
            qvarn.log.log('error',
                          msg_text='Client gave wrong revision',
                          revision_from_client=revision,
                          current_revision=obj['revision'])
            return qvarn.conflict_response('Bad revision {}'.format(revision))

        sub_obj = self._parent_coll.get_subresource(obj_id,
                                                    self._subpath,
                                                    allow_cond=qvarn.Yes())
        sub_obj['content_type'] = content_type
        qvarn.log.log('trace',
                      msg_text='_put_file',
                      claims=claims,
                      access_params=params)
        if id_allowed:
            new_sub = self._parent_coll.put_subresource_no_revision(
                sub_obj,
                subpath=self._subpath,
                obj_id=obj_id,
                revision=revision,
                claims=claims,
                access_params=params)
        else:
            new_sub = self._parent_coll.put_subresource(sub_obj,
                                                        subpath=self._subpath,
                                                        obj_id=obj_id,
                                                        revision=revision,
                                                        claims=claims,
                                                        access_params=params)

        try:
            self._store.remove_blob(obj_id=obj_id, subpath=self._subpath)
            self._store.create_blob(body, obj_id=obj_id, subpath=self._subpath)
        except qvarn.NoSuchObject as e:
            return qvarn.no_such_resource_response(str(e))

        headers = {
            'Revision': new_sub['revision'],
        }
        return qvarn.ok_response('', headers)
 def _get_a_listener(self, *args, **kwargs):
     claims = kwargs.get('claims')
     params = self.get_access_params(self._listener_coll.get_type_name(),
                                     claims)
     try:
         obj = self._listener_coll.get(kwargs['listener_id'],
                                       claims=claims,
                                       access_params=params)
     except qvarn.NoSuchResource as e:
         return qvarn.no_such_resource_response(str(e))
     return qvarn.ok_response(obj)
 def _delete_listener(self, *args, **kwargs):
     claims = kwargs.get('claims')
     params = self.get_access_params(self._listener_coll.get_type_name(),
                                     claims)
     listener_id = kwargs['listener_id']
     self._listener_coll.delete(listener_id,
                                claims=claims,
                                access_params=params)
     for obj_id in self._find_notifications(listener_id):
         self._store.remove_objects(obj_id=obj_id)
     return qvarn.ok_response({})
示例#7
0
 def _version(self, *args, **kwargs):
     version = {
         'api': {
             'version': qvarn.__version__,
         },
         'implementation': {
             'name': 'Qvarn',
             'version': qvarn.__version__,
         },
     }
     return qvarn.ok_response(version)
    def _get_notifications_list(self, *args, **kwargs):
        def timestamp(pair):
            _, obj = pair
            return obj['timestamp']

        listener_id = kwargs['listener_id']
        cond = qvarn.All(qvarn.Equal('type', 'notification'),
                         qvarn.Equal('listener_id', listener_id))
        pairs = self._store.get_matches(cond)
        ordered = sorted(pairs, key=timestamp)
        body = {'resources': [{'id': keys['obj_id']} for keys, _ in ordered]}
        return qvarn.ok_response(body)
 def _get_a_notification(self, *args, **kwargs):
     listener_id = kwargs['listener_id']
     notification_id = kwargs['notification_id']
     cond = qvarn.All(
         qvarn.Equal('type', 'notification'),
         qvarn.Equal('listener_id', listener_id),
         qvarn.Equal('id', notification_id),
     )
     pairs = self._store.get_matches(cond)
     if not pairs:
         return qvarn.no_such_resource_response(notification_id)
     if len(pairs) > 1:
         raise qvarn.TooManyResources(notification_id)
     return qvarn.ok_response(pairs[0][1])
示例#10
0
    def _get_subresource(self, *args, **kwargs):
        claims = kwargs.get('claims')
        params = self.get_access_params(self._parent_coll.get_type_name(),
                                        claims)

        obj_id = kwargs['id']
        try:
            obj = self._parent_coll.get_subresource(obj_id,
                                                    self._subpath,
                                                    claims=claims,
                                                    access_params=params)
        except qvarn.NoSuchResource as e:
            return qvarn.no_such_resource_response(str(e))
        return qvarn.ok_response(obj)
示例#11
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)
示例#12
0
 def _delete_notification(self, *args, **kwargs):
     listener_id = kwargs['listener_id']
     notification_id = kwargs['notification_id']
     cond = qvarn.All(
         qvarn.Equal('type', 'notification'),
         qvarn.Equal('listener_id', listener_id),
         qvarn.Equal('id', notification_id),
     )
     for keys, _ in self._store.get_matches(cond):
         values = {
             key: keys[key]
             for key in keys if isinstance(keys[key], str)
         }
         self._store.remove_objects(**values)
     return qvarn.ok_response({})
示例#13
0
    def _list(self, *args, **kwargs):
        qvarn.log.log('trace', msg_text='_list', kwargs=kwargs)
        claims = kwargs.get('claims')
        params = self.get_access_params(self._coll.get_type_name(), claims)
        body = self._coll.list(claims=claims, access_params=params)

        for obj in body.get('resources', []):
            self._log_access(
                obj,
                self._coll.get_type_name(),
                'GET',
                # 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(body)
示例#14
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)
示例#15
0
 def _get_listener_list(self, content_type, body, *args, **kwargs):
     claims = kwargs.get('claims')
     params = self.get_access_params(self._listener_coll.get_type_name(),
                                     claims)
     rtype = self._parent_coll.get_type_name()
     resources = self._listener_coll.list(claims=claims,
                                          access_params=params)
     listener_list = resources['resources']
     listener_ids = [listener['id'] for listener in listener_list]
     listeners = [
         self._listener_coll.get(lid, claims=claims, access_params=params)
         for lid in listener_ids
     ]
     qvarn.log.log('trace', msg_text='xxx', listeners=listeners)
     correct_ids = [{
         "id": listener['id']
     } for listener in listeners if listener.get('listen_on_type') == rtype]
     body = {
         'resources': correct_ids,
     }
     return qvarn.ok_response(body)
示例#16
0
    def _get(self, *args, **kwargs):
        claims = kwargs.get('claims')
        params = self.get_access_params(self._coll.get_type_name(), claims)

        try:
            obj = self._coll.get(kwargs['id'],
                                 claims=claims,
                                 access_params=params)
        except qvarn.NoSuchResource as e:
            return qvarn.no_such_resource_response(str(e))

        self._log_access(
            obj,
            obj.get('type'),
            'GET',
            # 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(obj)
示例#17
0
    def _get_file(self, *args, **kwargs):
        qvarn.log.log('trace', msg_text='_get_file', kwargs=kwargs)
        claims = kwargs.get('claims')
        assert claims is not None
        params = self.get_access_params(self._parent_coll.get_type_name(),
                                        claims)

        obj_id = kwargs['id']
        try:
            obj = self._parent_coll.get(obj_id,
                                        claims=claims,
                                        access_params=params)
            sub_obj = self._parent_coll.get_subresource(obj_id,
                                                        self._subpath,
                                                        claims=claims,
                                                        access_params=params)
            blob = self._store.get_blob(obj_id=obj_id, subpath=self._subpath)
        except (qvarn.NoSuchResource, qvarn.NoSuchObject) as e:
            return qvarn.no_such_resource_response(str(e))
        headers = {
            'Content-Type': sub_obj['content_type'],
            'Revision': obj['revision'],
        }
        return qvarn.ok_response(blob, headers)
示例#18
0
    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)
示例#19
0
    def _remove_rule(self, content_type, body, *args, **kwargs):
        if content_type != 'application/json':
            raise qvarn.NotJson(content_type)

        self._store.remove_allow_rule(body)
        return qvarn.ok_response(None)