From 778ec11d4db7be4ce4b1e2d90a11524b6057a107 Mon Sep 17 00:00:00 2001 From: drebs Date: Sat, 9 Dec 2017 13:44:29 -0200 Subject: [bug] handle path exceptions using twisted failures --- src/leap/soledad/server/_blobs.py | 53 +++++++++++++++++++++++++++++++-------- tests/blobs/test_fs_backend.py | 9 ++++--- 2 files changed, 47 insertions(+), 15 deletions(-) diff --git a/src/leap/soledad/server/_blobs.py b/src/leap/soledad/server/_blobs.py index cb726788..554fe5ac 100644 --- a/src/leap/soledad/server/_blobs.py +++ b/src/leap/soledad/server/_blobs.py @@ -95,13 +95,19 @@ class FilesystemBlobsBackend(object): def read_blob(self, user, blob_id, namespace=''): logger.info('reading blob: %s - %s@%s' % (user, blob_id, namespace)) - path = self._get_path(user, blob_id, namespace) + try: + path = self._get_path(user, blob_id, namespace) + except Exception as e: + return defer.fail(e) logger.debug('blob path: %s' % path) fd = open(path) return defer.succeed(fd) def get_flags(self, user, blob_id, namespace=''): - path = self._get_path(user, blob_id, namespace) + try: + path = self._get_path(user, blob_id, namespace) + except Exception as e: + return defer.fail(e) if not os.path.isfile(path): return defer.fail(BlobNotFound()) if not os.path.isfile(path + '.flags'): @@ -111,7 +117,10 @@ class FilesystemBlobsBackend(object): return defer.succeed(flags) def set_flags(self, user, blob_id, flags, namespace=''): - path = self._get_path(user, blob_id, namespace) + try: + path = self._get_path(user, blob_id, namespace) + except Exception as e: + return defer.fail(e) if not os.path.isfile(path): return defer.fail(BlobNotFound()) for flag in flags: @@ -142,7 +151,10 @@ class FilesystemBlobsBackend(object): yield self.semaphore.release() def delete_blob(self, user, blob_id, namespace=''): - blob_path = self._get_path(user, blob_id, namespace) + try: + blob_path = self._get_path(user, blob_id, namespace) + except Exception as e: + return defer.fail(e) if not os.path.isfile(blob_path): return defer.fail(BlobNotFound()) self.__touch(blob_path + '.deleted') @@ -154,12 +166,18 @@ class FilesystemBlobsBackend(object): return defer.succeed(None) def get_blob_size(self, user, blob_id, namespace=''): - blob_path = self._get_path(user, blob_id, namespace) + try: + blob_path = self._get_path(user, blob_id, namespace) + except Exception as e: + return defer.fail(e) size = os.stat(blob_path).st_size return defer.succeed(size) def count(self, user, namespace=''): - base_path = self._get_path(user, namespace=namespace) + try: + base_path = self._get_path(user, namespace=namespace) + except Exception as e: + return defer.fail(e) count = 0 for _, _, filenames in os.walk(base_path): count += len(filter(lambda i: not i.endswith('.flags'), filenames)) @@ -169,7 +187,10 @@ class FilesystemBlobsBackend(object): filter_flag=False): namespace = namespace or 'default' blob_ids = [] - base_path = self._get_path(user, namespace=namespace) + try: + base_path = self._get_path(user, namespace=namespace) + except Exception as e: + return defer.fail(e) def match(name): if deleted: @@ -202,10 +223,17 @@ class FilesystemBlobsBackend(object): yield blob_path def get_total_storage(self, user): - return self._get_disk_usage(self._get_path(user)) + try: + path = self._get_path(user) + except Exception as e: + return defer.fail(e) + return self._get_disk_usage(path) def get_tag(self, user, blob_id, namespace=''): - blob_path = self._get_path(user, blob_id, namespace) + try: + blob_path = self._get_path(user, blob_id, namespace) + except Exception as e: + return defer.fail(e) if not os.path.isfile(blob_path): return defer.fail(BlobNotFound()) with open(blob_path) as doc_file: @@ -236,8 +264,11 @@ class FilesystemBlobsBackend(object): return desired_path def exists(self, user, blob_id, namespace): - return os.path.isfile( - self._get_path(user, blob_id=blob_id, namespace=namespace)) + try: + path = self._get_path(user, blob_id=blob_id, namespace=namespace) + except Exception as e: + return defer.fail(e) + return os.path.isfile(path) def _get_path(self, user, blob_id='', namespace=''): parts = [user] diff --git a/tests/blobs/test_fs_backend.py b/tests/blobs/test_fs_backend.py index 28be4835..5b3ff30a 100644 --- a/tests/blobs/test_fs_backend.py +++ b/tests/blobs/test_fs_backend.py @@ -142,18 +142,19 @@ class FilesystemBackendTestCase(unittest.TestCase): target_dir = os.path.join(self.tempdir, 'user', 'incoming') walk_mock.assert_called_once_with(target_dir) + @defer.inlineCallbacks @pytest.mark.usefixtures("method_tmpdir") def test_path_validation_on_read_blob(self): blobs_path, request = self.tempdir, DummyRequest(['']) backend = _blobs.FilesystemBlobsBackend(blobs_path=blobs_path) with pytest.raises(Exception): - backend.read_blob('..', '..', request) + yield backend.read_blob('..', '..', request) with pytest.raises(Exception): - backend.read_blob('user', '../../../', request) + yield backend.read_blob('user', '../../../', request) with pytest.raises(Exception): - backend.read_blob('../../../', 'blob_id', request) + yield backend.read_blob('../../../', 'blob_id', request) with pytest.raises(Exception): - backend.read_blob('user', 'blob_id', request, namespace='..') + yield backend.read_blob('user', 'blob_id', request, namespace='..') @pytest.mark.usefixtures("method_tmpdir") @defer.inlineCallbacks -- cgit v1.2.3