예제 #1
0
    def _destroy(self, trail, request, response):
        try:
            name = '/'.join(trail)
            msg = self._parse_maybe_body(request, name)
        except Exception as e:
            raise HTTPError(406, str(e))
        basename = self._db_container_key(None, trail)
        try:
            keylist = self.root.store.list(basename)
            if keylist is None:
                raise HTTPError(404)
            if len(keylist) != 0:
                raise HTTPError(409)
            ret = self.root.store.cut(basename.rstrip('/'))
        except CSStoreError:
            raise HTTPError(500)

        if ret is False:
            raise HTTPError(404)

        output = msg.reply(None)
        if output is None:
            response['code'] = 204
        else:
            response['output'] = output
            response['code'] = 200
예제 #2
0
    def _int_del_key(self, trail, request, response):
        key = self._db_key(trail)
        try:
            ret = self.root.store.cut(key)
        except CSStoreError:
            raise HTTPError(500)

        if ret is False:
            raise HTTPError(404)

        response['code'] = 204
예제 #3
0
 def _db_container_key(self, default, trail):
     f = None
     if len(trail) > 1:
         f = self._db_key(trail)
     elif len(trail) == 1 and trail[0] != '':
         raise HTTPError(403)
     elif default is None:
         # No dfault namespace, fail
         raise HTTPError(403)
     else:
         # Use the default namespace
         f = self._db_key([default, ''])
     return f
예제 #4
0
 def _int_get_key(self, trail, request, response):
     try:
         name = '/'.join(trail)
         msg = self._parse_query(request, name)
     except Exception as e:
         raise HTTPError(406, str(e))
     key = self._db_key(trail)
     try:
         output = self.root.store.get(key)
         if output is None:
             raise HTTPError(404)
         response['output'] = msg.reply(output)
     except CSStoreError:
         raise HTTPError(500)
예제 #5
0
    def _create(self, trail, request, response):
        default = request.get('default_namespace', None)
        basename = self._db_container_key(None, trail)
        try:
            ok = self._parent_exists(default, trail[:-1])
            if not ok:
                raise HTTPError(404)

            self.root.store.set(basename, '')
        except CSStoreExists:
            raise HTTPError(409)
        except CSStoreError:
            raise HTTPError(500)

        response['code'] = 201
예제 #6
0
 def _list(self, trail, request, response):
     try:
         name = '/'.join(trail)
         msg = self._parse_query(request, name)
     except Exception as e:
         raise HTTPError(406, str(e))
     default = request.get('default_namespace', None)
     basename = self._db_container_key(default, trail)
     try:
         keylist = self.root.store.list(basename)
         self.logger.debug('list %s returned %r', basename, keylist)
         if keylist is None:
             raise HTTPError(404)
         response['output'] = msg.reply(json.dumps(keylist))
     except CSStoreError:
         raise HTTPError(500)
예제 #7
0
 def DELETE(self, request, response):
     trail = request.get('trail', [])
     if len(trail) == 0:
         raise HTTPError(405)
     if trail[-1] == '':
         self._destroy(trail, request, response)
     else:
         self._del_key(trail, request, response)
예제 #8
0
 def _int_get_key(self, trail, request, response):
     # default to simple
     query = request.get('query', '')
     if len(query) == 0:
         query = {'type': 'simple', 'value': ''}
     try:
         name = '/'.join(trail)
         msg = self._parse(request, query, name)
     except Exception as e:
         raise HTTPError(406, str(e))
     key = self._db_key(trail)
     try:
         output = self.root.store.get(key)
         if output is None:
             raise HTTPError(404)
         response['output'] = msg.reply(output)
     except CSStoreError:
         raise HTTPError(500)
예제 #9
0
    def _destroy(self, trail, request, response):
        basename = self._db_container_key(None, trail)
        try:
            keylist = self.root.store.list(basename)
            if keylist is None:
                raise HTTPError(404)
            if basename not in keylist:
                # uh ?
                raise HTTPError(409)
            if len(keylist) != 1:
                raise HTTPError(409)
            ret = self.root.store.cut(basename)
        except CSStoreError:
            raise HTTPError(500)

        if ret is False:
            raise HTTPError(404)

        response['code'] = 204
예제 #10
0
 def _list(self, trail, request, response):
     default = request.get('default_namespace', None)
     basename = self._db_container_key(default, trail)
     userfilter = request.get('query', dict()).get('filter', '')
     try:
         keylist = self.root.store.list(basename + userfilter)
         if keylist is None:
             raise HTTPError(404)
         # remove the base container itself
         output = list()
         for k in keylist:
             if k == basename:
                 continue
             # strip away the internal prefix for storing keys
             name = k[len('keys/'):]
             output.append(name)
         response['output'] = json.dumps(output)
     except CSStoreError:
         raise HTTPError(500)
예제 #11
0
    def _find_handler(self, request):
        base = self
        command = request.get('command', 'GET')
        if command not in SUPPORTED_COMMANDS:
            raise HTTPError(501)
        trail = request.get('trail', None)
        if trail is not None:
            for comp in trail:
                subs = getattr(base, 'subs', {})
                if comp in subs:
                    base = subs[comp]
                    trail.pop(0)
                else:
                    break

        handler = getattr(base, command)
        if handler is None:
            raise HTTPError(400)

        return handler
예제 #12
0
    def _int_del_key(self, trail, request, response):
        try:
            name = '/'.join(trail)
            msg = self._parse_maybe_body(request, name)
        except Exception as e:
            raise HTTPError(406, str(e))
        key = self._db_key(trail)
        try:
            ret = self.root.store.cut(key)
        except CSStoreError:
            raise HTTPError(500)

        if ret is False:
            raise HTTPError(404)

        output = msg.reply(None)
        if output is None:
            response['code'] = 204
        else:
            response['output'] = output
            response['code'] = 200
예제 #13
0
    def _create(self, trail, request, response):
        try:
            name = '/'.join(trail)
            msg = self._parse_maybe_body(request, name)
        except Exception as e:
            raise HTTPError(406, str(e))
        default = request.get('default_namespace', None)
        basename = self._db_container_key(None, trail)
        try:
            if len(trail) > 2:
                ok = self._parent_exists(default, trail[:-1])
                if not ok:
                    raise HTTPError(404)

            self.root.store.span(basename)
        except CSStoreExists:
            raise HTTPError(409)
        except CSStoreError:
            raise HTTPError(500)

        output = msg.reply(None)
        if output is not None:
            response['output'] = output
        response['code'] = 201
예제 #14
0
    def _parent_exists(self, default, trail):
        # check that the containers exist
        basename = self._db_container_key(trail[0], trail[:-1] + [''])
        try:
            keylist = self.root.store.list(basename)
        except CSStoreError:
            raise HTTPError(500)

        self.logger.debug('parent_exists: %s (%s, %r) -> %r',
                          basename, default, trail, keylist)

        if keylist is not None:
            return True

        # create default namespace if it is the only missing piece
        if len(trail) == 2 and default == trail[0]:
            container = self._db_container_key(default, '')
            self.root.store.span(container)
            return True

        return False
예제 #15
0
    def _parent_exists(self, default, trail):
        # check that the containers exist
        basename = self._db_container_key(trail[0], '')
        try:
            keylist = self.root.store.list(basename)
        except CSStoreError:
            raise HTTPError(500)

        # create default namespace if it is the only missing piece
        if keylist is None and len(trail) == 2 and default == trail[0]:
            container = self._db_container_key(default, '')
            self.root.store.set(container, '')
            return True

        # check if any parent is missing
        for n in range(1, len(trail)):
            c = self._db_key(trail[:n] + [''])
            if c not in keylist:
                return False

        return True
예제 #16
0
    def _int_set_key(self, trail, request, response):
        content_type = request.get('headers', dict()).get('Content-Type', '')
        if content_type.split(';')[0].strip() != 'application/json':
            raise HTTPError(400, 'Invalid Content-Type')
        body = request.get('body')
        if body is None:
            raise HTTPError(400)
        value = bytes(body).decode('utf-8')
        try:
            name = '/'.join(trail)
            msg = self._parse(request, json.loads(value), name)
        except UnknownMessageType as e:
            raise HTTPError(406, str(e))
        except UnallowedMessage as e:
            raise HTTPError(406, str(e))
        except Exception as e:
            raise HTTPError(400, str(e))

        # must _db_key first as access control is done here for now
        # otherwise users would e able to probe containers in namespaces
        # they do not have access to.
        key = self._db_key(trail)

        try:
            default = request.get('default_namespace', None)
            ok = self._parent_exists(default, trail)
            if not ok:
                raise HTTPError(404)

            ok = self.root.store.set(key, msg.payload)
        except CSStoreExists:
            raise HTTPError(409)
        except CSStoreError:
            raise HTTPError(500)

        response['code'] = 201
예제 #17
0
 def _db_key(self, trail):
     if len(trail) < 2:
         raise HTTPError(403)
     return os.path.join('keys', *trail)
예제 #18
0
 def check_authz(self, req):
     if self.authz.handle(req) is False:
         raise HTTPError(403)
예제 #19
0
 def check_authz(self, req):
     req['client_id'] = 'test'
     req['path'] = '/'.join([''] + req.get('trail', []))
     if self.authz.handle(req) is False:
         raise HTTPError(403)
예제 #20
0
 def _parse_body(self, request, name):
     body = request.get('body')
     if body is None:
         raise HTTPError(400)
     value = json.loads(bytes(body).decode('utf-8'))
     return self._parse(request, value, name)
예제 #21
0
 def handle(self, request):
     raise HTTPError(403)
예제 #22
0
 def _request(self, cmd, request, response, path, **kwargs):
     if self.uuid in request['headers'].get('X-LOOP-CUSTODIA', ''):
         raise HTTPError(502, "Loop detected")
     reply = cmd(path, **kwargs)
     self._response(reply, response)
예제 #23
0
 def POST(self, request, response):
     trail = request.get('trail', [])
     if len(trail) > 0 and trail[-1] == '':
         self._create(trail, request, response)
     else:
         raise HTTPError(405)
예제 #24
0
 def PUT(self, request, response):
     trail = request.get('trail', [])
     if len(trail) == 0 or trail[-1] == '':
         raise HTTPError(405)
     else:
         self._set_key(trail, request, response)
예제 #25
0
 def _response(self, reply, response):
     if reply.status_code < 200 or reply.status_code > 299:
         raise HTTPError(reply.status_code)
     response['code'] = reply.status_code
     if reply.content:
         response['output'] = reply.content