summaryrefslogtreecommitdiff
path: root/common
diff options
context:
space:
mode:
Diffstat (limited to 'common')
-rw-r--r--common/pkg/requirements-testing.pip6
-rw-r--r--common/pkg/requirements.pip2
-rw-r--r--common/src/leap/soledad/common/couch.py6
-rw-r--r--common/src/leap/soledad/common/tests/test_https.py66
-rw-r--r--common/src/leap/soledad/common/tests/test_server.py46
-rw-r--r--common/src/leap/soledad/common/tests/u1db_tests/test_https.py4
-rw-r--r--common/src/leap/soledad/common/tests/util.py7
7 files changed, 89 insertions, 48 deletions
diff --git a/common/pkg/requirements-testing.pip b/common/pkg/requirements-testing.pip
index c72c9fc4..e23135ac 100644
--- a/common/pkg/requirements-testing.pip
+++ b/common/pkg/requirements-testing.pip
@@ -1,6 +1,6 @@
mock
testscenarios
-leap.common
-leap.soledad.server
-leap.soledad.client
+leap.common>=0.4.0
+leap.soledad.server>=0.7.0
+leap.soledad.client>=0.7.0
setuptools-trial
diff --git a/common/pkg/requirements.pip b/common/pkg/requirements.pip
index 005d6884..b91186e7 100644
--- a/common/pkg/requirements.pip
+++ b/common/pkg/requirements.pip
@@ -2,7 +2,7 @@ simplejson
u1db
# leap deps -- bump me!
-leap.common>=0.7.0
+leap.common>=0.4.0
# XXX -- fix me!
# oauth is not strictly needed by us, but we need it until u1db adds it to its
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)