summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorVictor Shyba <victor1984@riseup.net>2017-07-07 02:58:09 -0300
committerdrebs <drebs@leap.se>2017-07-18 15:30:30 -0300
commit1aa9dee0ce87434188d37c821617caeff24fd70f (patch)
treead95887aa4b7c598390d994aaa109bf8aa6e2fb9
parent679e1bb7990fc1fc9c4971db6383a75ae6acab80 (diff)
[feature] add namespace support for BlobsManager
'namespace' argument is supported by backend but not yet exposed on API for clients. Since IncomingBox makes heavy usage of it, this commit exposes the argument as a query string for clients to use it.
-rw-r--r--src/leap/soledad/client/_db/blobs.py4
-rw-r--r--src/leap/soledad/server/_blobs.py20
-rw-r--r--testing/tests/server/test_blobs_server.py12
3 files changed, 26 insertions, 10 deletions
diff --git a/src/leap/soledad/client/_db/blobs.py b/src/leap/soledad/client/_db/blobs.py
index 8f9f4769..604d4bef 100644
--- a/src/leap/soledad/client/_db/blobs.py
+++ b/src/leap/soledad/client/_db/blobs.py
@@ -240,7 +240,7 @@ class BlobManager(object):
logger.error('sorry, dunno what happened')
@defer.inlineCallbacks
- def _encrypt_and_upload(self, blob_id, fd):
+ def _encrypt_and_upload(self, blob_id, fd, **params):
# TODO ------------------------------------------
# this is wrong, is doing 2 stages.
# the crypto producer can be passed to
@@ -254,7 +254,7 @@ class BlobManager(object):
crypter = BlobEncryptor(doc_info, fd, secret=self.secret,
armor=False)
fd = yield crypter.encrypt()
- response = yield self._client.put(uri, data=fd)
+ response = yield self._client.put(uri, data=fd, params=params)
check_http_status(response.code)
logger.info("Finished upload: %s" % (blob_id,))
diff --git a/src/leap/soledad/server/_blobs.py b/src/leap/soledad/server/_blobs.py
index 793149cd..7648e18e 100644
--- a/src/leap/soledad/server/_blobs.py
+++ b/src/leap/soledad/server/_blobs.py
@@ -184,23 +184,24 @@ class BlobsResource(resource.Resource):
def render_GET(self, request):
logger.info("http get: %s" % request.path)
- user, blob_id = self._validate(request)
+ user, blob_id, namespace = self._validate(request)
if not blob_id:
order = request.args.get('order_by', [None])[0]
- return self._handler.list_blobs(user, request, order_by=order)
+ return self._handler.list_blobs(user, request, namespace,
+ order_by=order)
self._handler.add_tag_header(user, blob_id, request)
- return self._handler.read_blob(user, blob_id, request)
+ return self._handler.read_blob(user, blob_id, request, namespace)
def render_DELETE(self, request):
logger.info("http put: %s" % request.path)
- user, blob_id = self._validate(request)
- self._handler.delete_blob(user, blob_id)
+ user, blob_id, namespace = self._validate(request)
+ self._handler.delete_blob(user, blob_id, namespace)
return ''
def render_PUT(self, request):
logger.info("http put: %s" % request.path)
- user, blob_id = self._validate(request)
- d = self._handler.write_blob(user, blob_id, request)
+ user, blob_id, namespace = self._validate(request)
+ d = self._handler.write_blob(user, blob_id, request, namespace)
d.addCallback(lambda _: request.finish())
d.addErrback(self._error, request)
return NOT_DONE_YET
@@ -214,7 +215,10 @@ class BlobsResource(resource.Resource):
for arg in request.postpath:
if arg and not VALID_STRINGS.match(arg):
raise Exception('Invalid blob resource argument: %s' % arg)
- return request.postpath
+ namespace = request.args.get('namespace', [''])[0]
+ if namespace and not VALID_STRINGS.match(namespace):
+ raise Exception('Invalid blob namespace: %s' % namespace)
+ return request.postpath + [namespace]
if __name__ == '__main__':
diff --git a/testing/tests/server/test_blobs_server.py b/testing/tests/server/test_blobs_server.py
index bbb1b6d5..f4c9119b 100644
--- a/testing/tests/server/test_blobs_server.py
+++ b/testing/tests/server/test_blobs_server.py
@@ -80,6 +80,18 @@ class BlobServerTestCase(unittest.TestCase):
blobs_list = yield manager.remote_list(order_by='-date')
self.assertEquals(['blob_id1', 'blob_id2'], blobs_list)
+ @defer.inlineCallbacks
+ @pytest.mark.usefixtures("method_tmpdir")
+ def test_list_restricted_by_namespace(self):
+ manager = BlobManager('', self.uri, self.secret,
+ self.secret, 'user')
+ namespace = 'incoming'
+ yield manager._encrypt_and_upload('blob_id1', BytesIO("1"),
+ namespace=namespace)
+ yield manager._encrypt_and_upload('blob_id2', BytesIO("2"))
+ blobs_list = yield manager.remote_list(namespace=namespace)
+ self.assertEquals(['blob_id1'], blobs_list)
+
def __touch(self, *args):
path = os.path.join(*args)
with open(path, 'a'):