summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorVictor Shyba <victor1984@riseup.net>2017-03-23 20:33:20 -0300
committerdrebs <drebs@leap.se>2017-04-04 18:27:38 +0200
commit26a65d100f91883027c17c219d018461968eda65 (patch)
tree1c2cdb4a8438aa730f4ac064cfe15ebf843e0740
parent45b73d58930a2a66394a6797c94a50c34e8f96e7 (diff)
[feature] add blobs listing
-rw-r--r--client/src/leap/soledad/client/_blobs.py6
-rw-r--r--server/src/leap/soledad/server/_blobs.py17
-rw-r--r--testing/tests/blobs/test_fs_backend.py9
-rw-r--r--testing/tests/server/test_blobs_server.py11
4 files changed, 43 insertions, 0 deletions
diff --git a/client/src/leap/soledad/client/_blobs.py b/client/src/leap/soledad/client/_blobs.py
index 7ecd4a4d..f9f1515b 100644
--- a/client/src/leap/soledad/client/_blobs.py
+++ b/client/src/leap/soledad/client/_blobs.py
@@ -158,6 +158,12 @@ class BlobManager(object):
return self.local.close()
@defer.inlineCallbacks
+ def list(self):
+ uri = urljoin(self.remote, self.user + '/')
+ data = yield self._client.get(uri)
+ defer.returnValue((yield data.json()))
+
+ @defer.inlineCallbacks
def put(self, doc, size):
fd = doc.blob_fd
# TODO this is a tee really, but ok... could do db and upload
diff --git a/server/src/leap/soledad/server/_blobs.py b/server/src/leap/soledad/server/_blobs.py
index 25266b18..3eac536e 100644
--- a/server/src/leap/soledad/server/_blobs.py
+++ b/server/src/leap/soledad/server/_blobs.py
@@ -27,6 +27,7 @@ environments.
import commands
import os
import base64
+import json
from twisted.logger import Logger
from twisted.web import static
@@ -65,6 +66,13 @@ class IBlobsBackend(Interface):
:returns: a deferred that fires upon finishing.
"""
+ def list_blobs(user, request):
+ """
+ Returns a json-encoded list of ids from user's blob.
+
+ :returns: a deferred that fires upon finishing.
+ """
+
def tag_header(user, blob_id, request):
"""
Adds a header 'Tag' with the last 20 bytes of the encoded file,
@@ -101,6 +109,13 @@ class FilesystemBlobsBackend(object):
os.makedirs(blobs_path)
self.path = blobs_path
+ def list_blobs(self, user, request):
+ blob_ids = []
+ base_path = os.path.join(self.path, user)
+ for _, _, filenames in os.walk(base_path):
+ blob_ids += filenames
+ return json.dumps(blob_ids)
+
def tag_header(self, user, blob_id, request):
with open(self._get_path(user, blob_id)) as doc_file:
doc_file.seek(-16, 2)
@@ -185,6 +200,8 @@ class BlobsResource(resource.Resource):
def render_GET(self, request):
logger.info("http get: %s" % request.path)
user, blob_id = request.postpath
+ if not blob_id:
+ return self._handler.list_blobs(user, request)
self._handler.tag_header(user, blob_id, request)
return self._handler.read_blob(user, blob_id, request)
diff --git a/testing/tests/blobs/test_fs_backend.py b/testing/tests/blobs/test_fs_backend.py
index ce82fce0..5be6c17d 100644
--- a/testing/tests/blobs/test_fs_backend.py
+++ b/testing/tests/blobs/test_fs_backend.py
@@ -25,6 +25,7 @@ from mock import Mock
import mock
import os
import base64
+import json
import pytest
@@ -86,3 +87,11 @@ class FilesystemBackendTestCase(unittest.TestCase):
backend.path = '/somewhere/'
path = backend._get_path('user', 'blob_id')
assert path == '/somewhere/user/b/blo/blob_i/blob_id'
+
+ @pytest.mark.usefixtures("method_tmpdir")
+ @mock.patch('leap.soledad.server._blobs.os.walk')
+ def test_list_blobs(self, walk_mock):
+ backend, _ = _blobs.FilesystemBlobsBackend(self.tempdir), None
+ walk_mock.return_value = [(_, _, ['blob_0']), (_, _, ['blob_1'])]
+ result = json.loads(backend.list_blobs('user', DummyRequest([''])))
+ assert result == ['blob_0', 'blob_1']
diff --git a/testing/tests/server/test_blobs_server.py b/testing/tests/server/test_blobs_server.py
index 1f35c285..3c534c0c 100644
--- a/testing/tests/server/test_blobs_server.py
+++ b/testing/tests/server/test_blobs_server.py
@@ -53,6 +53,17 @@ class BlobServerTestCase(unittest.TestCase):
@defer.inlineCallbacks
@pytest.mark.usefixtures("method_tmpdir")
+ def test_upload_list(self):
+ manager = BlobManager('', self.uri, self.secret,
+ self.secret, 'user')
+ yield manager._encrypt_and_upload('blob_id1', '1', '1', BytesIO("1"))
+ yield manager._encrypt_and_upload('blob_id2', '2', '2', BytesIO("2"))
+ blobs_list = yield manager.list()
+ assert len(blobs_list) == 2
+ assert 'blob_id1' in blobs_list and 'blob_id2' in blobs_list
+
+ @defer.inlineCallbacks
+ @pytest.mark.usefixtures("method_tmpdir")
def test_upload_deny_duplicates(self):
manager = BlobManager('', self.uri, self.secret,
self.secret, 'user')