diff options
Diffstat (limited to 'common/src')
| -rw-r--r-- | common/src/leap/soledad/common/couch.py | 17 | ||||
| -rw-r--r-- | common/src/leap/soledad/common/tests/test_couch_operations_atomicity.py | 6 | ||||
| -rw-r--r-- | common/src/leap/soledad/common/tests/test_server.py | 54 | 
3 files changed, 52 insertions, 25 deletions
diff --git a/common/src/leap/soledad/common/couch.py b/common/src/leap/soledad/common/couch.py index 456d4fdf..11b77938 100644 --- a/common/src/leap/soledad/common/couch.py +++ b/common/src/leap/soledad/common/couch.py @@ -35,7 +35,6 @@ from couchdb.client import Server  from couchdb.http import (      ResourceConflict,      ResourceNotFound, -    Unauthorized,      ServerError,      Session,  ) @@ -48,6 +47,7 @@ from u1db.errors import (      ConflictedDoc,      DocumentDoesNotExist,      DocumentAlreadyDeleted, +    Unauthorized,  )  from u1db.backends import CommonBackend, CommonSyncTarget  from u1db.remote import http_app @@ -1451,7 +1451,6 @@ class CouchServerState(ServerState):          :return: The CouchDatabase object.          :rtype: CouchDatabase          """ -        # TODO: open couch          return CouchDatabase.open_database(              self._couch_url + '/' + dbname,              create=False) @@ -1460,16 +1459,20 @@ class CouchServerState(ServerState):          """          Ensure couch database exists. +        Usually, this method is used by the server to ensure the existence of +        a database. In our setup, the Soledad user that accesses the underlying +        couch server should never have permission to create (or delete) +        databases. But, in case it ever does, by raising an exception here we +        have one more guarantee that no modified client will be able to +        enforce creation of a database when syncing. +          :param dbname: The name of the database to ensure.          :type dbname: str          :return: The CouchDatabase object and the replica uid.          :rtype: (CouchDatabase, str)          """ -        db = CouchDatabase.open_database( -            self._couch_url + '/' + dbname, -            create=True) -        return db, db._replica_uid +        raise Unauthorized()      def delete_database(self, dbname):          """ @@ -1478,7 +1481,7 @@ class CouchServerState(ServerState):          :param dbname: The name of the database to delete.          :type dbname: str          """ -        CouchDatabase.delete_database(self._couch_url + '/' + dbname) +        raise Unauthorized()      def _set_couch_url(self, url):          """ diff --git a/common/src/leap/soledad/common/tests/test_couch_operations_atomicity.py b/common/src/leap/soledad/common/tests/test_couch_operations_atomicity.py index 5384d465..3c457cc5 100644 --- a/common/src/leap/soledad/common/tests/test_couch_operations_atomicity.py +++ b/common/src/leap/soledad/common/tests/test_couch_operations_atomicity.py @@ -33,11 +33,17 @@ from leap.soledad.common.tests.test_target import (      make_leap_document_for_test,      token_leap_sync_target,  ) +from leap.soledad.common.tests.test_server import _couch_ensure_database  REPEAT_TIMES = 20 +# monkey path CouchServerState so it can ensure databases. + +CouchServerState.ensure_database = _couch_ensure_database + +  class CouchAtomicityTestCase(CouchDBTestCase, TestCaseWithServer):      @staticmethod diff --git a/common/src/leap/soledad/common/tests/test_server.py b/common/src/leap/soledad/common/tests/test_server.py index 06595ed2..f8d2a64f 100644 --- a/common/src/leap/soledad/common/tests/test_server.py +++ b/common/src/leap/soledad/common/tests/test_server.py @@ -51,6 +51,17 @@ from leap.soledad.server import SoledadApp, LockResource  from leap.soledad.server.auth import URLToAuthorization +# monkey path CouchServerState so it can ensure databases. + +def _couch_ensure_database(self, dbname): +    db = CouchDatabase.open_database( +        self._couch_url + '/' + dbname, +        create=True) +    return db, db._replica_uid + +CouchServerState.ensure_database = _couch_ensure_database + +  class ServerAuthorizationTestCase(BaseLeapTest):      """      Tests related to Soledad server authorization. @@ -340,15 +351,16 @@ class EncryptedSyncTestCase(          _, doclist = sol1.get_all_docs()          self.assertEqual([], doclist)          doc1 = sol1.create_doc(json.loads(simple_doc)) -        # sync with server -        sol1._server_url = self.getURL() -        sol1.sync() -        # assert doc was sent to couch db +        # ensure remote db exists before syncing          db = CouchDatabase(              self._couch_url,              # the name of the user database is "user-<uuid>".              'user-user-uuid',          ) +        # sync with server +        sol1._server_url = self.getURL() +        sol1.sync() +        # assert doc was sent to couch db          _, doclist = db.get_all_docs()          self.assertEqual(1, len(doclist))          couchdoc = doclist[0] @@ -395,15 +407,16 @@ class EncryptedSyncTestCase(          _, doclist = sol1.get_all_docs()          self.assertEqual([], doclist)          doc1 = sol1.create_doc(json.loads(simple_doc)) -        # sync with server -        sol1._server_url = self.getURL() -        sol1.sync() -        # assert doc was sent to couch db +        # ensure remote db exists before syncing          db = CouchDatabase(              self._couch_url,              # the name of the user database is "user-<uuid>".              'user-user-uuid',          ) +        # sync with server +        sol1._server_url = self.getURL() +        sol1.sync() +        # assert doc was sent to couch db          _, doclist = db.get_all_docs()          self.assertEqual(1, len(doclist))          couchdoc = doclist[0] @@ -454,6 +467,12 @@ class EncryptedSyncTestCase(          self.assertEqual([], doclist)          content = binascii.hexlify(os.urandom(length/2))  # len() == length          doc1 = sol1.create_doc({'data': content}) +        # ensure remote db exists before syncing +        db = CouchDatabase( +            self._couch_url, +            # the name of the user database is "user-<uuid>". +            'user-user-uuid', +        )          # sync with server          sol1._server_url = self.getURL()          sol1.sync() @@ -473,11 +492,6 @@ class EncryptedSyncTestCase(          # assert incoming doc is equal to the first sent doc          self.assertEqual(doc1, doc2)          # delete remote database -        db = CouchDatabase( -            self._couch_url, -            # the name of the user database is "user-<uuid>". -            'user-user-uuid', -        )          db.delete_database() @@ -497,6 +511,12 @@ class EncryptedSyncTestCase(          # create many small files          for i in range(0, number_of_docs):              sol1.create_doc(json.loads(simple_doc)) +        # ensure remote db exists before syncing +        db = CouchDatabase( +            self._couch_url, +            # the name of the user database is "user-<uuid>". +            'user-user-uuid', +        )          # sync with server          sol1._server_url = self.getURL()          sol1.sync() @@ -516,11 +536,6 @@ class EncryptedSyncTestCase(          for doc in doclist:              self.assertEqual(sol1.get_doc(doc.doc_id), doc)          # delete remote database -        db = CouchDatabase( -            self._couch_url, -            # the name of the user database is "user-<uuid>". -            'user-user-uuid', -        )          db.delete_database()  class LockResourceTestCase( @@ -542,6 +557,9 @@ class LockResourceTestCase(          CouchDBTestCase.setUp(self)          self.tempdir = tempfile.mkdtemp(prefix="leap_tests-")          self._couch_url = 'http://localhost:' + str(self.wrapper.port) +        # create the databases +        CouchDatabase(self._couch_url, 'shared') +        CouchDatabase(self._couch_url, 'tokens')          self._state = CouchServerState(              self._couch_url, 'shared', 'tokens')  | 
