From d627675a6879d9ac7cbdacdd3f743c14a24c5167 Mon Sep 17 00:00:00 2001
From: drebs <drebs@leap.se>
Date: Fri, 22 Dec 2017 18:28:55 -0200
Subject: [PATCH] [bug] add BlobNotFound exception to methods interface

---
 src/leap/soledad/server/_blobs/fs_backend.py | 12 ++++++++----
 src/leap/soledad/server/_blobs/resource.py   |  2 ++
 src/leap/soledad/server/interfaces.py        | 19 +++++++++++++++++++
 3 files changed, 29 insertions(+), 4 deletions(-)

diff --git a/src/leap/soledad/server/_blobs/fs_backend.py b/src/leap/soledad/server/_blobs/fs_backend.py
index e1c49910..79bbc4d7 100644
--- a/src/leap/soledad/server/_blobs/fs_backend.py
+++ b/src/leap/soledad/server/_blobs/fs_backend.py
@@ -104,6 +104,8 @@ class FilesystemBlobsBackend(object):
     def read_blob(self, user, blob_id, consumer, namespace='', range=None):
         logger.info('reading blob: %s - %s@%s' % (user, blob_id, namespace))
         path = self._get_path(user, blob_id, namespace)
+        if not os.path.isfile(path):
+            raise BlobNotFound((user, blob_id))
         logger.debug('blob path: %s' % path)
         with open(path) as fd:
             if range is None:
@@ -122,7 +124,7 @@ class FilesystemBlobsBackend(object):
         except Exception as e:
             return defer.fail(e)
         if not os.path.isfile(path):
-            return defer.fail(BlobNotFound())
+            return defer.fail(BlobNotFound((user, blob_id)))
         if not os.path.isfile(path + '.flags'):
             return defer.succeed([])
         with open(path + '.flags', 'r') as flags_file:
@@ -135,7 +137,7 @@ class FilesystemBlobsBackend(object):
         except Exception as e:
             return defer.fail(e)
         if not os.path.isfile(path):
-            return defer.fail(BlobNotFound())
+            return defer.fail(BlobNotFound((user, blob_id)))
         for flag in flags:
             if flag not in ACCEPTED_FLAGS:
                 return defer.fail(InvalidFlag(flag))
@@ -184,7 +186,7 @@ class FilesystemBlobsBackend(object):
         except Exception as e:
             return defer.fail(e)
         if not os.path.isfile(blob_path):
-            return defer.fail(BlobNotFound())
+            return defer.fail(BlobNotFound((user, blob_id)))
         self.__touch(blob_path + '.deleted')
         os.unlink(blob_path)
         try:
@@ -198,6 +200,8 @@ class FilesystemBlobsBackend(object):
             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((user, blob_id)))
         size = os.stat(blob_path).st_size
         return defer.succeed(size)
 
@@ -270,7 +274,7 @@ class FilesystemBlobsBackend(object):
         except Exception as e:
             return defer.fail(e)
         if not os.path.isfile(blob_path):
-            return defer.fail(BlobNotFound())
+            return defer.fail(BlobNotFound((user, blob_id)))
         with open(blob_path) as doc_file:
             doc_file.seek(-16, 2)
             tag = base64.urlsafe_b64encode(doc_file.read())
diff --git a/src/leap/soledad/server/_blobs/resource.py b/src/leap/soledad/server/_blobs/resource.py
index dd9af861..0772c29b 100644
--- a/src/leap/soledad/server/_blobs/resource.py
+++ b/src/leap/soledad/server/_blobs/resource.py
@@ -206,6 +206,8 @@ class BlobsResource(resource.Resource):
 
         d = self._handler.get_blob_size(user, blob_id, namespace=namespace)
         d.addCallback(_handleRangeHeader)
+        d.addErrback(_catchBlobNotFound, request, user, blob_id)
+        d.addErrback(_catchAllErrors, request)
         return NOT_DONE_YET
 
     def render_DELETE(self, request):
diff --git a/src/leap/soledad/server/interfaces.py b/src/leap/soledad/server/interfaces.py
index 089111e3..96fa2f94 100644
--- a/src/leap/soledad/server/interfaces.py
+++ b/src/leap/soledad/server/interfaces.py
@@ -44,6 +44,9 @@ class IBlobsBackend(Interface):
         :return: A deferred that fires when the blob has been written to the
             consumer.
         :rtype: twisted.internet.defer.Deferred
+
+        :raise BlobNotFound: Raised (asynchronously) when the blob was not
+            found in the backend.
         """
 
     def write_blob(user, blob_id, producer, namespace=''):
@@ -80,6 +83,9 @@ class IBlobsBackend(Interface):
 
         :return: A deferred that fires when the blob has been deleted.
         :rtype: twisted.internet.defer.Deferred
+
+        :raise BlobNotFound: Raised (asynchronously) when the blob was not
+            found in the backend.
         """
 
     def get_blob_size(user, blob_id, namespace=''):
@@ -95,6 +101,9 @@ class IBlobsBackend(Interface):
 
         :return: A deferred that fires with the size of the blob.
         :rtype: twisted.internet.defer.Deferred
+
+        :raise BlobNotFound: Raised (asynchronously) when the blob was not
+            found in the backend.
         """
 
     def count(user, namespace=''):
@@ -168,6 +177,9 @@ class IBlobsBackend(Interface):
 
         :return: A deferred that fires with the tag of the blob.
         :rtype: twisted.internet.defer.Deferred
+
+        :raise BlobNotFound: Raised (asynchronously) when the blob was not
+            found in the backend.
         """
 
     def get_flags(user, blob_id, namespace=''):
@@ -183,6 +195,9 @@ class IBlobsBackend(Interface):
 
         :return: A deferred that fires with the list of flags for a blob.
         :rtype: twisted.internet.defer.Deferred
+
+        :raise BlobNotFound: Raised (asynchronously) when the blob was not
+            found in the backend.
         """
 
     def set_flags(user, blob_id, flags, namespace=''):
@@ -200,4 +215,8 @@ class IBlobsBackend(Interface):
 
         :return: A deferred that fires when the flags have been set.
         :rtype: twisted.internet.defer.Deferred
+
+        :raise BlobNotFound: Raised (asynchronously) when the blob was not
+            found in the backend.
+        :raise InvalidFlag: Raised when one of the flags passed is invalid.
         """
-- 
GitLab