summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorVictor Shyba <victor1984@riseup.net>2017-05-01 03:28:09 -0300
committerVictor Shyba <victor1984@riseup.net>2017-05-01 03:31:14 -0300
commit967c91c5bb7ecca3575c6ef7d0fb4461de4dafc7 (patch)
tree9992c4e7bcb1e7c383a26404b6ebf5fcfbbd95d8
parent336211e2526c71c34a82c4ec48ef32f8bb82fd1f (diff)
[bug] fail locally if blob exists
We can't let the local DB try an isertion before making sure doc isn't already there. - Resolves: #8845
-rw-r--r--client/src/leap/soledad/client/_blobs.py9
-rw-r--r--testing/tests/blobs/test_local_backend.py15
2 files changed, 24 insertions, 0 deletions
diff --git a/client/src/leap/soledad/client/_blobs.py b/client/src/leap/soledad/client/_blobs.py
index 6f692f6b..1475b302 100644
--- a/client/src/leap/soledad/client/_blobs.py
+++ b/client/src/leap/soledad/client/_blobs.py
@@ -194,6 +194,9 @@ class BlobManager(object):
@defer.inlineCallbacks
def put(self, doc, size):
+ if (yield self.local.exists(doc.blob_id)):
+ error_message = "Blob already exists: %s" % doc.blob_id
+ raise BlobAlreadyExistsError(error_message)
fd = doc.blob_fd
# TODO this is a tee really, but ok... could do db and upload
# concurrently. not sure if we'd gain something.
@@ -326,6 +329,12 @@ class SQLiteBlobBackend(object):
else:
defer.returnValue([])
+ @defer.inlineCallbacks
+ def exists(self, blob_id):
+ query = 'SELECT blob_id from blobs WHERE blob_id = ?'
+ result = yield self.dbpool.runQuery(query, (blob_id,))
+ defer.returnValue(bool(len(result)))
+
def _init_blob_table(conn):
maybe_create = (
diff --git a/testing/tests/blobs/test_local_backend.py b/testing/tests/blobs/test_local_backend.py
index 5caa7463..b5a14de4 100644
--- a/testing/tests/blobs/test_local_backend.py
+++ b/testing/tests/blobs/test_local_backend.py
@@ -20,6 +20,7 @@ Tests for sqlcipher backend on blobs client.
from twisted.trial import unittest
from twisted.internet import defer
from leap.soledad.client._blobs import BlobManager, BlobDoc, FIXED_REV
+from leap.soledad.client._blobs import BlobAlreadyExistsError
from io import BytesIO
from mock import Mock
import pytest
@@ -115,3 +116,17 @@ class BlobManagerTestCase(unittest.TestCase):
call_blob_id, call_fd = call_list[0][0]
self.assertEquals('missing_id', call_blob_id)
self.assertEquals('test', call_fd.getvalue())
+
+ @defer.inlineCallbacks
+ @pytest.mark.usefixtures("method_tmpdir")
+ def test_duplicated_blob_error_on_put(self):
+ self.manager._encrypt_and_upload = Mock(return_value=None)
+ content = "Blob content"
+ doc1 = BlobDoc(BytesIO(content), 'existing_id')
+ yield self.manager.put(doc1, len(content))
+ doc2 = BlobDoc(BytesIO(content), 'existing_id')
+ # reset mock, so we can check that upload wasnt called
+ self.manager._encrypt_and_upload = Mock(return_value=None)
+ with pytest.raises(BlobAlreadyExistsError):
+ yield self.manager.put(doc2, len(content))
+ self.assertFalse(self.manager._encrypt_and_upload.called)