diff options
Diffstat (limited to 'common/src')
5 files changed, 85 insertions, 44 deletions
diff --git a/common/src/leap/soledad/common/couch.py b/common/src/leap/soledad/common/couch.py index 8d262ccd..ae9e7d2a 100644 --- a/common/src/leap/soledad/common/couch.py +++ b/common/src/leap/soledad/common/couch.py @@ -240,8 +240,12 @@ def raise_server_error(exc, ddoc_path): document for an yet unknown reason. """ path = "".join(ddoc_path) - if exc.message[1][0] == 'unnamed_error': + msg = exc.message[1][0] + if msg == 'unnamed_error': raise errors.MissingDesignDocListFunctionError(path) + elif msg == 'TypeError': + if 'point is undefined' in exc.message[1][1]: + raise errors.MissingDesignDocListFunctionError # other errors are unknown for now raise errors.DesignDocUnknownError(path) diff --git a/common/src/leap/soledad/common/tests/test_https.py b/common/src/leap/soledad/common/tests/test_https.py index 4dd55754..6907e3ed 100644 --- a/common/src/leap/soledad/common/tests/test_https.py +++ b/common/src/leap/soledad/common/tests/test_https.py @@ -50,16 +50,22 @@ LEAP_SCENARIOS = [ # The following tests come from `u1db.tests.test_https`. #----------------------------------------------------------------------------- -def token_leap_https_sync_target(test, host, path): +def token_leap_https_sync_target(test, host, path, cert_file=None): _, port = test.server.server_address - st = client.target.SoledadSyncTarget( + #source_replica_uid = test._soledad._dbpool.replica_uid + creds = {'token': {'uuid': 'user-uuid', 'token': 'auth-token'}} + if not cert_file: + cert_file = test.cacert_pem + st = client.http_target.SoledadHTTPSyncTarget( 'https://%s:%d/%s' % (host, port, path), - crypto=test._soledad._crypto) - st.set_token_credentials('user-uuid', 'auth-token') + source_replica_uid='other-id', + creds=creds, + crypto=test._soledad._crypto, + cert_file=cert_file) return st -class TestSoledadSyncTargetHttpsSupport( +class TestSoledadHTTPSyncTargetHttpsSupport( TestWithScenarios, test_https.TestHttpSyncTargetHttpsSupport, BaseSoledadTest): @@ -80,6 +86,29 @@ class TestSoledadSyncTargetHttpsSupport( http_client._VerifiedHTTPSConnection = client.api.VerifiedHTTPSConnection client.api.SOLEDAD_CERT = http_client.CA_CERTS + def test_cannot_verify_cert(self): + self.startServer() + # don't print expected traceback server-side + self.server.handle_error = lambda req, cli_addr: None + self.request_state._create_database('test') + remote_target = self.getSyncTarget( + 'localhost', 'test', cert_file=http_client.CA_CERTS) + d = remote_target.record_sync_info('other-id', 2, 'T-id') + + def _assert_raises(result): + from twisted.python.failure import Failure + if isinstance(result, Failure): + from OpenSSL.SSL import Error + error = result.value.message[0].value + if isinstance(error, Error): + msg = error.message[0][2] + self.assertEqual("certificate verify failed", msg) + return + self.fail("certificate verification should have failed.") + + d.addCallbacks(_assert_raises, _assert_raises) + return d + def test_working(self): """ Test that SSL connections work well. @@ -89,24 +118,19 @@ class TestSoledadSyncTargetHttpsSupport( """ self.startServer() db = self.request_state._create_database('test') - self.patch(client.api, 'SOLEDAD_CERT', self.cacert_pem) remote_target = self.getSyncTarget('localhost', 'test') - remote_target.record_sync_info('other-id', 2, 'T-id') - self.assertEqual( - (2, 'T-id'), db._get_replica_gen_and_trans_id('other-id')) + d = remote_target.record_sync_info('other-id', 2, 'T-id') + d.addCallback(lambda _: + self.assertEqual( + (2, 'T-id'), db._get_replica_gen_and_trans_id('other-id'))) + d.addCallback(lambda _: + remote_target.close()) + return d def test_host_mismatch(self): """ - Test that SSL connections to a hostname different than the one in the - certificate raise CertificateError. - - This test was adapted to patch Soledad's HTTPS connection custom class - with the intended CA certificates. + This test is disabled because soledad's twisted-based http agent uses + pyOpenSSL, which will complain if we try to use an IP to connect to + the remote host (see the original test in u1db_tests/test_https.py). """ - self.startServer() - self.request_state._create_database('test') - self.patch(client.api, 'SOLEDAD_CERT', self.cacert_pem) - remote_target = self.getSyncTarget('127.0.0.1', 'test') - self.assertRaises( - http_client.CertificateError, remote_target.record_sync_info, - 'other-id', 2, 'T-id') + pass diff --git a/common/src/leap/soledad/common/tests/test_server.py b/common/src/leap/soledad/common/tests/test_server.py index 2b653a1c..a8012e08 100644 --- a/common/src/leap/soledad/common/tests/test_server.py +++ b/common/src/leap/soledad/common/tests/test_server.py @@ -22,6 +22,7 @@ import tempfile import mock import time import binascii +from uuid import uuid4 from urlparse import urljoin from twisted.internet import defer @@ -93,7 +94,7 @@ class ServerAuthorizationTestCase(BaseSoledadTest): /user-db/doc/{id} | - /user-db/sync-from/{source} | GET, PUT, POST """ - uuid = 'myuuid' + uuid = uuid4().hex authmap = URLToAuthorization(uuid,) dbname = authmap._user_db_name # test global auth @@ -208,7 +209,7 @@ class ServerAuthorizationTestCase(BaseSoledadTest): """ Test if authorization fails for a wrong dbname. """ - uuid = 'myuuid' + uuid = uuid4().hex authmap = URLToAuthorization(uuid) dbname = 'somedb' # test wrong-db database resource auth @@ -283,7 +284,7 @@ class EncryptedSyncTestCase( sync_target = token_soledad_sync_target - def _soledad_instance(self, user='user-uuid', passphrase=u'123', + def _soledad_instance(self, user=None, passphrase=u'123', prefix='', secrets_path='secrets.json', local_db_path='soledad.u1db', @@ -336,15 +337,17 @@ class EncryptedSyncTestCase( TestCaseWithServer.tearDown(self) def _test_encrypted_sym_sync(self, passphrase=u'123', doc_size=2, - number_of_docs=1): + number_of_docs=1): """ Test the complete syncing chain between two soledad dbs using a Soledad server backed by a couch database. """ self.startServer() + user = 'user-' + uuid4().hex # instantiate soledad and create a document sol1 = self._soledad_instance( + user=user, # token is verified in test_target.make_token_soledad_app auth_token='auth-token', passphrase=passphrase) @@ -352,6 +355,7 @@ class EncryptedSyncTestCase( # instantiate another soledad using the same secret as the previous # one (so we can correctly verify the mac of the synced document) sol2 = self._soledad_instance( + user=user, prefix='x', auth_token='auth-token', secrets_path=sol1._secrets_path, @@ -359,7 +363,7 @@ class EncryptedSyncTestCase( # ensure remote db exists before syncing db = CouchDatabase.open_database( - urljoin(self._couch_url, 'user-user-uuid'), + urljoin(self._couch_url, 'user-' + user), create=True, ensure_ddocs=True) @@ -370,7 +374,7 @@ class EncryptedSyncTestCase( def _db1CreateDocs(results): deferreds = [] for i in xrange(number_of_docs): - content = binascii.hexlify(os.urandom(doc_size/2)) + content = binascii.hexlify(os.urandom(doc_size/2)) deferreds.append(sol1.create_doc({'data': content})) return defer.DeferredList(deferreds) @@ -461,6 +465,7 @@ class EncryptedSyncTestCase( """ return self._test_encrypted_sym_sync(doc_size=2, number_of_docs=100) + class LockResourceTestCase( CouchDBTestCase, TestCaseWithServer): """ @@ -506,7 +511,8 @@ class LockResourceTestCase( def test__try_obtain_filesystem_lock(self): responder = mock.Mock() - lr = LockResource('uuid', self._state, responder) + lock_uuid = uuid4().hex + lr = LockResource(lock_uuid, self._state, responder) self.assertFalse(lr._lock.locked) self.assertTrue(lr._try_obtain_filesystem_lock()) self.assertTrue(lr._lock.locked) @@ -514,7 +520,8 @@ class LockResourceTestCase( def test__try_release_filesystem_lock(self): responder = mock.Mock() - lr = LockResource('uuid', self._state, responder) + lock_uuid = uuid4().hex + lr = LockResource(lock_uuid, self._state, responder) lr._try_obtain_filesystem_lock() self.assertTrue(lr._lock.locked) lr._try_release_filesystem_lock() @@ -522,11 +529,12 @@ class LockResourceTestCase( def test_put(self): responder = mock.Mock() - lr = LockResource('uuid', self._state, responder) + lock_uuid = uuid4().hex + lr = LockResource(lock_uuid, self._state, responder) # lock! lr.put({}, None) # assert lock document was correctly written - lock_doc = lr._shared_db.get_doc('lock-uuid') + lock_doc = lr._shared_db.get_doc('lock-' + lock_uuid) self.assertIsNotNone(lock_doc) self.assertTrue(LockResource.TIMESTAMP_KEY in lock_doc.content) self.assertTrue(LockResource.LOCK_TOKEN_KEY in lock_doc.content) @@ -541,20 +549,22 @@ class LockResourceTestCase( def test_delete(self): responder = mock.Mock() - lr = LockResource('uuid', self._state, responder) + lock_uuid = uuid4().hex + lr = LockResource(lock_uuid, self._state, responder) # lock! lr.put({}, None) - lock_doc = lr._shared_db.get_doc('lock-uuid') + lock_doc = lr._shared_db.get_doc('lock-' + lock_uuid) token = lock_doc.content[LockResource.LOCK_TOKEN_KEY] # unlock! lr.delete({'token': token}, None) self.assertFalse(lr._lock.locked) - self.assertIsNone(lr._shared_db.get_doc('lock-uuid')) + self.assertIsNone(lr._shared_db.get_doc('lock-' + lock_uuid)) responder.send_response_json.assert_called_with(200) def test_put_while_locked_fails(self): responder = mock.Mock() - lr = LockResource('uuid', self._state, responder) + lock_uuid = uuid4().hex + lr = LockResource(lock_uuid, self._state, responder) # lock! lr.put({}, None) # try to lock again! @@ -572,7 +582,8 @@ class LockResourceTestCase( def test_unlock_unexisting_lock_fails(self): responder = mock.Mock() - lr = LockResource('uuid', self._state, responder) + lock_uuid = uuid4().hex + lr = LockResource(lock_uuid, self._state, responder) # unlock! lr.delete({'token': 'anything'}, None) responder.send_response_json.assert_called_with( @@ -580,11 +591,12 @@ class LockResourceTestCase( def test_unlock_with_wrong_token_fails(self): responder = mock.Mock() - lr = LockResource('uuid', self._state, responder) + lock_uuid = uuid4().hex + lr = LockResource(lock_uuid, self._state, responder) # lock! lr.put({}, None) # unlock! lr.delete({'token': 'wrongtoken'}, None) - self.assertIsNotNone(lr._shared_db.get_doc('lock-uuid')) + self.assertIsNotNone(lr._shared_db.get_doc('lock-' + lock_uuid)) responder.send_response_json.assert_called_with( 401, error='unlock unauthorized') diff --git a/common/src/leap/soledad/common/tests/u1db_tests/test_https.py b/common/src/leap/soledad/common/tests/u1db_tests/test_https.py index cea175d6..f22ce51e 100644 --- a/common/src/leap/soledad/common/tests/u1db_tests/test_https.py +++ b/common/src/leap/soledad/common/tests/u1db_tests/test_https.py @@ -80,10 +80,10 @@ class TestHttpSyncTargetHttpsSupport(tests.TestCaseWithServer): soledad.client.api.old__VerifiedHTTPSConnection super(TestHttpSyncTargetHttpsSupport, self).setUp() - def getSyncTarget(self, host, path=None): + def getSyncTarget(self, host, path=None, cert_file=None): if self.server is None: self.startServer() - return self.sync_target(self, host, path) + return self.sync_target(self, host, path, cert_file=cert_file) def test_working(self): self.startServer() diff --git a/common/src/leap/soledad/common/tests/util.py b/common/src/leap/soledad/common/tests/util.py index 17ed3855..60bab81c 100644 --- a/common/src/leap/soledad/common/tests/util.py +++ b/common/src/leap/soledad/common/tests/util.py @@ -50,7 +50,7 @@ from leap.soledad.common.couch import CouchDatabase, CouchServerState from leap.soledad.common.crypto import ENC_SCHEME_KEY from leap.soledad.client import Soledad -from leap.soledad.client import target +from leap.soledad.client import http_target from leap.soledad.client import auth from leap.soledad.client.crypto import decrypt_doc_dict @@ -102,7 +102,7 @@ def make_token_soledad_app(state): app = SoledadApp(state) def _verify_authentication_data(uuid, auth_data): - if uuid == 'user-uuid' and auth_data == 'auth-token': + if uuid.startswith('user-') and auth_data == 'auth-token': return True return False @@ -165,6 +165,7 @@ class MockedSharedDBTest(object): lock = Mock(return_value=('atoken', 300)) unlock = Mock(return_value=True) open = Mock(return_value=None) + close = Mock(return_value=None) syncable = True def __call__(self): @@ -173,7 +174,7 @@ class MockedSharedDBTest(object): def soledad_sync_target(test, path): - return target.SoledadSyncTarget( + return http_target.SoledadSyncTarget( test.getURL(path), crypto=test._soledad._crypto) |