From a39af0e003ba95c9b7ab554aa4a4c5ce316a43c7 Mon Sep 17 00:00:00 2001 From: drebs Date: Sun, 18 Dec 2016 12:56:21 -0200 Subject: [bug] disallow all requests to "user-{uuid}/" --- testing/tests/server/test_server.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'testing/tests/server/test_server.py') diff --git a/testing/tests/server/test_server.py b/testing/tests/server/test_server.py index 6710caaf..cae2e75c 100644 --- a/testing/tests/server/test_server.py +++ b/testing/tests/server/test_server.py @@ -110,7 +110,7 @@ class ServerAuthorizationTestCase(BaseSoledadTest): /shared-db/docs | - /shared-db/doc/{id} | GET, PUT, DELETE /shared-db/sync-from/{source} | - - /user-db | GET, PUT, DELETE + /user-db | - /user-db/docs | - /user-db/doc/{id} | - /user-db/sync-from/{source} | GET, PUT, POST @@ -174,13 +174,13 @@ class ServerAuthorizationTestCase(BaseSoledadTest): authmap.is_authorized( self._make_environ('/shared/sync-from/x', 'POST'))) # test user-db database resource auth - self.assertTrue( + self.assertFalse( authmap.is_authorized( self._make_environ('/%s' % dbname, 'GET'))) - self.assertTrue( + self.assertFalse( authmap.is_authorized( self._make_environ('/%s' % dbname, 'PUT'))) - self.assertTrue( + self.assertFalse( authmap.is_authorized( self._make_environ('/%s' % dbname, 'DELETE'))) self.assertFalse( -- cgit v1.2.3 From e73d36621052a69aae327200c063ac1689bcf9e0 Mon Sep 17 00:00:00 2001 From: drebs Date: Sun, 18 Dec 2016 14:21:54 -0200 Subject: [feat] reuse the url mapper instead of creating it for every request --- testing/tests/server/test_server.py | 251 ++++++++++++++++-------------------- 1 file changed, 114 insertions(+), 137 deletions(-) (limited to 'testing/tests/server/test_server.py') diff --git a/testing/tests/server/test_server.py b/testing/tests/server/test_server.py index cae2e75c..09242736 100644 --- a/testing/tests/server/test_server.py +++ b/testing/tests/server/test_server.py @@ -45,7 +45,7 @@ from leap.soledad.client import _crypto from leap.soledad.client import Soledad from leap.soledad.server.config import load_configuration from leap.soledad.server.config import CONFIG_DEFAULTS -from leap.soledad.server.auth import URLToAuthorization +from leap.soledad.server.auth import URLMapper from leap.soledad.server.auth import SoledadTokenAuthMiddleware @@ -116,175 +116,152 @@ class ServerAuthorizationTestCase(BaseSoledadTest): /user-db/sync-from/{source} | GET, PUT, POST """ uuid = uuid4().hex - authmap = URLToAuthorization(uuid,) - dbname = authmap._user_db_name + urlmap = URLMapper() + dbname = 'user-%s' % uuid + # test global auth - self.assertTrue( - authmap.is_authorized(self._make_environ('/', 'GET'))) + match = urlmap.match(self._make_environ('/', 'GET')) + # test shared-db database resource auth - self.assertTrue( - authmap.is_authorized( - self._make_environ('/shared', 'GET'))) - self.assertFalse( - authmap.is_authorized( + match = urlmap.match( + self._make_environ('/shared', 'GET')) + self.assertIsNotNone(match) + + self.assertIsNone( + urlmap.match( self._make_environ('/shared', 'PUT'))) - self.assertFalse( - authmap.is_authorized( + + self.assertIsNone( + urlmap.match( self._make_environ('/shared', 'DELETE'))) - self.assertFalse( - authmap.is_authorized( + + self.assertIsNone( + urlmap.match( self._make_environ('/shared', 'POST'))) + # test shared-db docs resource auth - self.assertFalse( - authmap.is_authorized( + self.assertIsNone( + urlmap.match( self._make_environ('/shared/docs', 'GET'))) - self.assertFalse( - authmap.is_authorized( + + self.assertIsNone( + urlmap.match( self._make_environ('/shared/docs', 'PUT'))) - self.assertFalse( - authmap.is_authorized( + + self.assertIsNone( + urlmap.match( self._make_environ('/shared/docs', 'DELETE'))) - self.assertFalse( - authmap.is_authorized( + + self.assertIsNone( + urlmap.match( self._make_environ('/shared/docs', 'POST'))) + # test shared-db doc resource auth - self.assertTrue( - authmap.is_authorized( - self._make_environ('/shared/doc/x', 'GET'))) - self.assertTrue( - authmap.is_authorized( - self._make_environ('/shared/doc/x', 'PUT'))) - self.assertTrue( - authmap.is_authorized( - self._make_environ('/shared/doc/x', 'DELETE'))) - self.assertFalse( - authmap.is_authorized( + match = urlmap.match( + self._make_environ('/shared/doc/x', 'GET')) + self.assertIsNotNone(match) + self.assertEqual('x', match.get('id')) + + match = urlmap.match( + self._make_environ('/shared/doc/x', 'PUT')) + self.assertIsNotNone(match) + self.assertEqual('x', match.get('id')) + + match = urlmap.match( + self._make_environ('/shared/doc/x', 'DELETE')) + self.assertEqual('x', match.get('id')) + + self.assertIsNone( + urlmap.match( self._make_environ('/shared/doc/x', 'POST'))) + # test shared-db sync resource auth - self.assertFalse( - authmap.is_authorized( + self.assertIsNone( + urlmap.match( self._make_environ('/shared/sync-from/x', 'GET'))) - self.assertFalse( - authmap.is_authorized( + + self.assertIsNone( + urlmap.match( self._make_environ('/shared/sync-from/x', 'PUT'))) - self.assertFalse( - authmap.is_authorized( + + self.assertIsNone( + urlmap.match( self._make_environ('/shared/sync-from/x', 'DELETE'))) - self.assertFalse( - authmap.is_authorized( + + self.assertIsNone( + urlmap.match( self._make_environ('/shared/sync-from/x', 'POST'))) + # test user-db database resource auth - self.assertFalse( - authmap.is_authorized( + self.assertIsNone( + urlmap.match( self._make_environ('/%s' % dbname, 'GET'))) - self.assertFalse( - authmap.is_authorized( + + self.assertIsNone( + urlmap.match( self._make_environ('/%s' % dbname, 'PUT'))) - self.assertFalse( - authmap.is_authorized( + + self.assertIsNone( + urlmap.match( self._make_environ('/%s' % dbname, 'DELETE'))) - self.assertFalse( - authmap.is_authorized( + + self.assertIsNone( + urlmap.match( self._make_environ('/%s' % dbname, 'POST'))) + # test user-db docs resource auth - self.assertFalse( - authmap.is_authorized( + self.assertIsNone( + urlmap.match( self._make_environ('/%s/docs' % dbname, 'GET'))) - self.assertFalse( - authmap.is_authorized( + + self.assertIsNone( + urlmap.match( self._make_environ('/%s/docs' % dbname, 'PUT'))) - self.assertFalse( - authmap.is_authorized( + + self.assertIsNone( + urlmap.match( self._make_environ('/%s/docs' % dbname, 'DELETE'))) - self.assertFalse( - authmap.is_authorized( + + self.assertIsNone( + urlmap.match( self._make_environ('/%s/docs' % dbname, 'POST'))) + # test user-db doc resource auth - self.assertFalse( - authmap.is_authorized( + self.assertIsNone( + urlmap.match( self._make_environ('/%s/doc/x' % dbname, 'GET'))) - self.assertFalse( - authmap.is_authorized( + + self.assertIsNone( + urlmap.match( self._make_environ('/%s/doc/x' % dbname, 'PUT'))) - self.assertFalse( - authmap.is_authorized( + + self.assertIsNone( + urlmap.match( self._make_environ('/%s/doc/x' % dbname, 'DELETE'))) - self.assertFalse( - authmap.is_authorized( + + self.assertIsNone( + urlmap.match( self._make_environ('/%s/doc/x' % dbname, 'POST'))) + # test user-db sync resource auth - self.assertTrue( - authmap.is_authorized( - self._make_environ('/%s/sync-from/x' % dbname, 'GET'))) - self.assertTrue( - authmap.is_authorized( - self._make_environ('/%s/sync-from/x' % dbname, 'PUT'))) - self.assertFalse( - authmap.is_authorized( - self._make_environ('/%s/sync-from/x' % dbname, 'DELETE'))) - self.assertTrue( - authmap.is_authorized( - self._make_environ('/%s/sync-from/x' % dbname, 'POST'))) - - def test_verify_action_with_wrong_dbnames(self): - """ - Test if authorization fails for a wrong dbname. - """ - uuid = uuid4().hex - authmap = URLToAuthorization(uuid) - dbname = 'somedb' - # test wrong-db database resource auth - self.assertFalse( - authmap.is_authorized( - self._make_environ('/%s' % dbname, 'GET'))) - self.assertFalse( - authmap.is_authorized( - self._make_environ('/%s' % dbname, 'PUT'))) - self.assertFalse( - authmap.is_authorized( - self._make_environ('/%s' % dbname, 'DELETE'))) - self.assertFalse( - authmap.is_authorized( - self._make_environ('/%s' % dbname, 'POST'))) - # test wrong-db docs resource auth - self.assertFalse( - authmap.is_authorized( - self._make_environ('/%s/docs' % dbname, 'GET'))) - self.assertFalse( - authmap.is_authorized( - self._make_environ('/%s/docs' % dbname, 'PUT'))) - self.assertFalse( - authmap.is_authorized( - self._make_environ('/%s/docs' % dbname, 'DELETE'))) - self.assertFalse( - authmap.is_authorized( - self._make_environ('/%s/docs' % dbname, 'POST'))) - # test wrong-db doc resource auth - self.assertFalse( - authmap.is_authorized( - self._make_environ('/%s/doc/x' % dbname, 'GET'))) - self.assertFalse( - authmap.is_authorized( - self._make_environ('/%s/doc/x' % dbname, 'PUT'))) - self.assertFalse( - authmap.is_authorized( - self._make_environ('/%s/doc/x' % dbname, 'DELETE'))) - self.assertFalse( - authmap.is_authorized( - self._make_environ('/%s/doc/x' % dbname, 'POST'))) - # test wrong-db sync resource auth - self.assertFalse( - authmap.is_authorized( - self._make_environ('/%s/sync-from/x' % dbname, 'GET'))) - self.assertFalse( - authmap.is_authorized( - self._make_environ('/%s/sync-from/x' % dbname, 'PUT'))) - self.assertFalse( - authmap.is_authorized( - self._make_environ('/%s/sync-from/x' % dbname, 'DELETE'))) - self.assertFalse( - authmap.is_authorized( - self._make_environ('/%s/sync-from/x' % dbname, 'POST'))) + match = urlmap.match( + self._make_environ('/%s/sync-from/x' % dbname, 'GET')) + self.assertEqual(uuid, match.get('uuid')) + self.assertEqual('x', match.get('source_replica_uid')) + + match = urlmap.match( + self._make_environ('/%s/sync-from/x' % dbname, 'PUT')) + self.assertEqual(uuid, match.get('uuid')) + self.assertEqual('x', match.get('source_replica_uid')) + + match = urlmap.match( + self._make_environ('/%s/sync-from/x' % dbname, 'DELETE')) + self.assertIsNone(match) + + match = urlmap.match( + self._make_environ('/%s/sync-from/x' % dbname, 'POST')) + self.assertEqual(uuid, match.get('uuid')) + self.assertEqual('x', match.get('source_replica_uid')) @pytest.mark.usefixtures("method_tmpdir") -- cgit v1.2.3 From 260805b9967184841c4499f94713a9a48c49a813 Mon Sep 17 00:00:00 2001 From: drebs Date: Sun, 18 Dec 2016 16:36:39 -0200 Subject: [feat] use twisted web http auth and creds --- testing/tests/server/test_server.py | 164 ++++++++---------------------------- 1 file changed, 37 insertions(+), 127 deletions(-) (limited to 'testing/tests/server/test_server.py') diff --git a/testing/tests/server/test_server.py b/testing/tests/server/test_server.py index 09242736..12f6fb20 100644 --- a/testing/tests/server/test_server.py +++ b/testing/tests/server/test_server.py @@ -18,11 +18,9 @@ Tests for server-related functionality. """ import binascii -import mock import os import pytest -from hashlib import sha512 from pkg_resources import resource_filename from urlparse import urljoin from uuid import uuid4 @@ -46,36 +44,6 @@ from leap.soledad.client import Soledad from leap.soledad.server.config import load_configuration from leap.soledad.server.config import CONFIG_DEFAULTS from leap.soledad.server.auth import URLMapper -from leap.soledad.server.auth import SoledadTokenAuthMiddleware - - -class ServerAuthenticationMiddlewareTestCase(CouchDBTestCase): - - def setUp(self): - super(ServerAuthenticationMiddlewareTestCase, self).setUp() - app = mock.Mock() - self._state = CouchServerState(self.couch_url) - app.state = self._state - self.auth_middleware = SoledadTokenAuthMiddleware(app) - self._authorize('valid-uuid', 'valid-token') - - def _authorize(self, uuid, token): - token_doc = {} - token_doc['_id'] = sha512(token).hexdigest() - token_doc[self._state.TOKENS_USER_ID_KEY] = uuid - token_doc[self._state.TOKENS_TYPE_KEY] = \ - self._state.TOKENS_TYPE_DEF - dbname = self._state._tokens_dbname() - db = self.couch_server.create(dbname) - db.save(token_doc) - self.addCleanup(self.delete_db, db.name) - - def test_authorized_user(self): - is_authorized = self.auth_middleware._verify_authentication_data - self.assertTrue(is_authorized('valid-uuid', 'valid-token')) - self.assertFalse(is_authorized('valid-uuid', 'invalid-token')) - self.assertFalse(is_authorized('invalid-uuid', 'valid-token')) - self.assertFalse(is_authorized('eve', 'invalid-token')) class ServerAuthorizationTestCase(BaseSoledadTest): @@ -90,12 +58,6 @@ class ServerAuthorizationTestCase(BaseSoledadTest): def tearDown(self): pass - def _make_environ(self, path_info, request_method): - return { - 'PATH_INFO': path_info, - 'REQUEST_METHOD': request_method, - } - def test_verify_action_with_correct_dbnames(self): """ Test encrypting and decrypting documents. @@ -120,146 +82,94 @@ class ServerAuthorizationTestCase(BaseSoledadTest): dbname = 'user-%s' % uuid # test global auth - match = urlmap.match(self._make_environ('/', 'GET')) + match = urlmap.match('/', 'GET') + self.assertIsNotNone(match) # test shared-db database resource auth - match = urlmap.match( - self._make_environ('/shared', 'GET')) + match = urlmap.match('/shared', 'GET') self.assertIsNotNone(match) - self.assertIsNone( - urlmap.match( - self._make_environ('/shared', 'PUT'))) + match = urlmap.match('/shared', 'PUT') + self.assertIsNone(match) - self.assertIsNone( - urlmap.match( - self._make_environ('/shared', 'DELETE'))) + match = urlmap.match('/shared', 'DELETE') + self.assertIsNone(match) - self.assertIsNone( - urlmap.match( - self._make_environ('/shared', 'POST'))) + match = urlmap.match('/shared', 'POST') + self.assertIsNone(match) # test shared-db docs resource auth - self.assertIsNone( - urlmap.match( - self._make_environ('/shared/docs', 'GET'))) + self.assertIsNone(urlmap.match('/shared/docs', 'GET')) - self.assertIsNone( - urlmap.match( - self._make_environ('/shared/docs', 'PUT'))) + self.assertIsNone(urlmap.match('/shared/docs', 'PUT')) - self.assertIsNone( - urlmap.match( - self._make_environ('/shared/docs', 'DELETE'))) + self.assertIsNone(urlmap.match('/shared/docs', 'DELETE')) - self.assertIsNone( - urlmap.match( - self._make_environ('/shared/docs', 'POST'))) + self.assertIsNone(urlmap.match('/shared/docs', 'POST')) # test shared-db doc resource auth - match = urlmap.match( - self._make_environ('/shared/doc/x', 'GET')) + match = urlmap.match('/shared/doc/x', 'GET') self.assertIsNotNone(match) self.assertEqual('x', match.get('id')) - match = urlmap.match( - self._make_environ('/shared/doc/x', 'PUT')) + match = urlmap.match('/shared/doc/x', 'PUT') self.assertIsNotNone(match) self.assertEqual('x', match.get('id')) - match = urlmap.match( - self._make_environ('/shared/doc/x', 'DELETE')) + match = urlmap.match('/shared/doc/x', 'DELETE') self.assertEqual('x', match.get('id')) - self.assertIsNone( - urlmap.match( - self._make_environ('/shared/doc/x', 'POST'))) + self.assertIsNone(urlmap.match('/shared/doc/x', 'POST')) # test shared-db sync resource auth - self.assertIsNone( - urlmap.match( - self._make_environ('/shared/sync-from/x', 'GET'))) + self.assertIsNone(urlmap.match('/shared/sync-from/x', 'GET')) - self.assertIsNone( - urlmap.match( - self._make_environ('/shared/sync-from/x', 'PUT'))) + self.assertIsNone(urlmap.match('/shared/sync-from/x', 'PUT')) - self.assertIsNone( - urlmap.match( - self._make_environ('/shared/sync-from/x', 'DELETE'))) + self.assertIsNone(urlmap.match('/shared/sync-from/x', 'DELETE')) - self.assertIsNone( - urlmap.match( - self._make_environ('/shared/sync-from/x', 'POST'))) + self.assertIsNone(urlmap.match('/shared/sync-from/x', 'POST')) # test user-db database resource auth - self.assertIsNone( - urlmap.match( - self._make_environ('/%s' % dbname, 'GET'))) + self.assertIsNone(urlmap.match('/%s' % dbname, 'GET')) - self.assertIsNone( - urlmap.match( - self._make_environ('/%s' % dbname, 'PUT'))) + self.assertIsNone(urlmap.match('/%s' % dbname, 'PUT')) - self.assertIsNone( - urlmap.match( - self._make_environ('/%s' % dbname, 'DELETE'))) + self.assertIsNone(urlmap.match('/%s' % dbname, 'DELETE')) - self.assertIsNone( - urlmap.match( - self._make_environ('/%s' % dbname, 'POST'))) + self.assertIsNone(urlmap.match('/%s' % dbname, 'POST')) # test user-db docs resource auth - self.assertIsNone( - urlmap.match( - self._make_environ('/%s/docs' % dbname, 'GET'))) + self.assertIsNone(urlmap.match('/%s/docs' % dbname, 'GET')) - self.assertIsNone( - urlmap.match( - self._make_environ('/%s/docs' % dbname, 'PUT'))) + self.assertIsNone(urlmap.match('/%s/docs' % dbname, 'PUT')) - self.assertIsNone( - urlmap.match( - self._make_environ('/%s/docs' % dbname, 'DELETE'))) + self.assertIsNone(urlmap.match('/%s/docs' % dbname, 'DELETE')) - self.assertIsNone( - urlmap.match( - self._make_environ('/%s/docs' % dbname, 'POST'))) + self.assertIsNone(urlmap.match('/%s/docs' % dbname, 'POST')) # test user-db doc resource auth - self.assertIsNone( - urlmap.match( - self._make_environ('/%s/doc/x' % dbname, 'GET'))) + self.assertIsNone(urlmap.match('/%s/doc/x' % dbname, 'GET')) - self.assertIsNone( - urlmap.match( - self._make_environ('/%s/doc/x' % dbname, 'PUT'))) + self.assertIsNone(urlmap.match('/%s/doc/x' % dbname, 'PUT')) - self.assertIsNone( - urlmap.match( - self._make_environ('/%s/doc/x' % dbname, 'DELETE'))) + self.assertIsNone(urlmap.match('/%s/doc/x' % dbname, 'DELETE')) - self.assertIsNone( - urlmap.match( - self._make_environ('/%s/doc/x' % dbname, 'POST'))) + self.assertIsNone(urlmap.match('/%s/doc/x' % dbname, 'POST')) # test user-db sync resource auth - match = urlmap.match( - self._make_environ('/%s/sync-from/x' % dbname, 'GET')) + match = urlmap.match('/%s/sync-from/x' % dbname, 'GET') self.assertEqual(uuid, match.get('uuid')) self.assertEqual('x', match.get('source_replica_uid')) - match = urlmap.match( - self._make_environ('/%s/sync-from/x' % dbname, 'PUT')) + match = urlmap.match('/%s/sync-from/x' % dbname, 'PUT') self.assertEqual(uuid, match.get('uuid')) self.assertEqual('x', match.get('source_replica_uid')) - match = urlmap.match( - self._make_environ('/%s/sync-from/x' % dbname, 'DELETE')) + match = urlmap.match('/%s/sync-from/x' % dbname, 'DELETE') self.assertIsNone(match) - match = urlmap.match( - self._make_environ('/%s/sync-from/x' % dbname, 'POST')) + match = urlmap.match('/%s/sync-from/x' % dbname, 'POST') self.assertEqual(uuid, match.get('uuid')) self.assertEqual('x', match.get('source_replica_uid')) -- cgit v1.2.3 From 6043f7966b64d6922987bca9137a524fb06a3379 Mon Sep 17 00:00:00 2001 From: drebs Date: Mon, 19 Dec 2016 09:43:03 -0200 Subject: [refactor] separate url mapper, avoid hanging tests Because the wsgi resource has its own threadpool, tests might get confused when shutting down and the reactor may get clogged waiting for the threadpool to be stopped. By refactoring the URLMapper to its own module, server tests can avoid loading the resource module, where the wsgi threadpool resides, so the threapool will not be started. --- testing/tests/server/test_server.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'testing/tests/server/test_server.py') diff --git a/testing/tests/server/test_server.py b/testing/tests/server/test_server.py index 12f6fb20..39d8e8c3 100644 --- a/testing/tests/server/test_server.py +++ b/testing/tests/server/test_server.py @@ -43,7 +43,7 @@ from leap.soledad.client import _crypto from leap.soledad.client import Soledad from leap.soledad.server.config import load_configuration from leap.soledad.server.config import CONFIG_DEFAULTS -from leap.soledad.server.auth import URLMapper +from leap.soledad.server.url_mapper import URLMapper class ServerAuthorizationTestCase(BaseSoledadTest): -- cgit v1.2.3 From 5058cae83227d4ba1b6390aa52a63b22a1acb11d Mon Sep 17 00:00:00 2001 From: drebs Date: Thu, 22 Dec 2016 07:56:01 -0200 Subject: [test] split url mapper test in many smaller tests --- testing/tests/server/test_server.py | 180 ++++++++++++++++-------------------- 1 file changed, 79 insertions(+), 101 deletions(-) (limited to 'testing/tests/server/test_server.py') diff --git a/testing/tests/server/test_server.py b/testing/tests/server/test_server.py index 39d8e8c3..da69c423 100644 --- a/testing/tests/server/test_server.py +++ b/testing/tests/server/test_server.py @@ -36,7 +36,6 @@ from test_soledad.util import ( make_token_soledad_app, make_soledad_document_for_test, soledad_sync_target, - BaseSoledadTest, ) from leap.soledad.client import _crypto @@ -46,133 +45,112 @@ from leap.soledad.server.config import CONFIG_DEFAULTS from leap.soledad.server.url_mapper import URLMapper -class ServerAuthorizationTestCase(BaseSoledadTest): - +class URLMapperTestCase(unittest.TestCase): """ - Tests related to Soledad server authorization. + Test if the URLMapper behaves as expected. + + The following table lists the authorized actions among all possible + u1db remote actions: + + URL path | Authorized actions + -------------------------------------------------- + / | GET + /shared-db | GET + /shared-db/docs | - + /shared-db/doc/{id} | - + /shared-db/sync-from/{source} | - + /user-db | - + /user-db/docs | - + /user-db/doc/{id} | - + /user-db/sync-from/{source} | GET, PUT, POST """ def setUp(self): - pass - - def tearDown(self): - pass - - def test_verify_action_with_correct_dbnames(self): - """ - Test encrypting and decrypting documents. - - The following table lists the authorized actions among all possible - u1db remote actions: - - URL path | Authorized actions - -------------------------------------------------- - / | GET - /shared-db | GET - /shared-db/docs | - - /shared-db/doc/{id} | GET, PUT, DELETE - /shared-db/sync-from/{source} | - - /user-db | - - /user-db/docs | - - /user-db/doc/{id} | - - /user-db/sync-from/{source} | GET, PUT, POST - """ - uuid = uuid4().hex - urlmap = URLMapper() - dbname = 'user-%s' % uuid - - # test global auth - match = urlmap.match('/', 'GET') - self.assertIsNotNone(match) + self._uuid = uuid4().hex + self._urlmap = URLMapper() + self._dbname = 'user-%s' % self._uuid - # test shared-db database resource auth - match = urlmap.match('/shared', 'GET') + def test_root_authorized(self): + match = self._urlmap.match('/', 'GET') self.assertIsNotNone(match) - match = urlmap.match('/shared', 'PUT') - self.assertIsNone(match) + def test_shared_authorized(self): + self.assertIsNotNone(self._urlmap.match('/shared', 'GET')) - match = urlmap.match('/shared', 'DELETE') - self.assertIsNone(match) + def test_shared_unauthorized(self): + self.assertIsNone(self._urlmap.match('/shared', 'PUT')) + self.assertIsNone(self._urlmap.match('/shared', 'DELETE')) + self.assertIsNone(self._urlmap.match('/shared', 'POST')) - match = urlmap.match('/shared', 'POST') - self.assertIsNone(match) + def test_shared_docs_unauthorized(self): + self.assertIsNone(self._urlmap.match('/shared/docs', 'GET')) + self.assertIsNone(self._urlmap.match('/shared/docs', 'PUT')) + self.assertIsNone(self._urlmap.match('/shared/docs', 'DELETE')) + self.assertIsNone(self._urlmap.match('/shared/docs', 'POST')) - # test shared-db docs resource auth - self.assertIsNone(urlmap.match('/shared/docs', 'GET')) - - self.assertIsNone(urlmap.match('/shared/docs', 'PUT')) - - self.assertIsNone(urlmap.match('/shared/docs', 'DELETE')) - - self.assertIsNone(urlmap.match('/shared/docs', 'POST')) - - # test shared-db doc resource auth - match = urlmap.match('/shared/doc/x', 'GET') + def test_shared_doc_authorized(self): + match = self._urlmap.match('/shared/doc/x', 'GET') self.assertIsNotNone(match) self.assertEqual('x', match.get('id')) - match = urlmap.match('/shared/doc/x', 'PUT') + match = self._urlmap.match('/shared/doc/x', 'PUT') self.assertIsNotNone(match) self.assertEqual('x', match.get('id')) - match = urlmap.match('/shared/doc/x', 'DELETE') + match = self._urlmap.match('/shared/doc/x', 'DELETE') + self.assertIsNotNone(match) self.assertEqual('x', match.get('id')) - self.assertIsNone(urlmap.match('/shared/doc/x', 'POST')) - - # test shared-db sync resource auth - self.assertIsNone(urlmap.match('/shared/sync-from/x', 'GET')) - - self.assertIsNone(urlmap.match('/shared/sync-from/x', 'PUT')) - - self.assertIsNone(urlmap.match('/shared/sync-from/x', 'DELETE')) - - self.assertIsNone(urlmap.match('/shared/sync-from/x', 'POST')) - - # test user-db database resource auth - self.assertIsNone(urlmap.match('/%s' % dbname, 'GET')) - - self.assertIsNone(urlmap.match('/%s' % dbname, 'PUT')) - - self.assertIsNone(urlmap.match('/%s' % dbname, 'DELETE')) - - self.assertIsNone(urlmap.match('/%s' % dbname, 'POST')) - - # test user-db docs resource auth - self.assertIsNone(urlmap.match('/%s/docs' % dbname, 'GET')) - - self.assertIsNone(urlmap.match('/%s/docs' % dbname, 'PUT')) - - self.assertIsNone(urlmap.match('/%s/docs' % dbname, 'DELETE')) - - self.assertIsNone(urlmap.match('/%s/docs' % dbname, 'POST')) - - # test user-db doc resource auth - self.assertIsNone(urlmap.match('/%s/doc/x' % dbname, 'GET')) - - self.assertIsNone(urlmap.match('/%s/doc/x' % dbname, 'PUT')) - - self.assertIsNone(urlmap.match('/%s/doc/x' % dbname, 'DELETE')) - - self.assertIsNone(urlmap.match('/%s/doc/x' % dbname, 'POST')) - - # test user-db sync resource auth - match = urlmap.match('/%s/sync-from/x' % dbname, 'GET') + def test_shared_doc_unauthorized(self): + self.assertIsNone(self._urlmap.match('/shared/doc/x', 'POST')) + + def test_shared_sync_unauthorized(self): + self.assertIsNone(self._urlmap.match('/shared/sync-from/x', 'GET')) + self.assertIsNone(self._urlmap.match('/shared/sync-from/x', 'PUT')) + self.assertIsNone(self._urlmap.match('/shared/sync-from/x', 'DELETE')) + self.assertIsNone(self._urlmap.match('/shared/sync-from/x', 'POST')) + + def test_user_db_unauthorized(self): + dbname = self._dbname + self.assertIsNone(self._urlmap.match('/%s' % dbname, 'GET')) + self.assertIsNone(self._urlmap.match('/%s' % dbname, 'PUT')) + self.assertIsNone(self._urlmap.match('/%s' % dbname, 'DELETE')) + self.assertIsNone(self._urlmap.match('/%s' % dbname, 'POST')) + + def test_user_db_docs_unauthorized(self): + dbname = self._dbname + self.assertIsNone(self._urlmap.match('/%s/docs' % dbname, 'GET')) + self.assertIsNone(self._urlmap.match('/%s/docs' % dbname, 'PUT')) + self.assertIsNone(self._urlmap.match('/%s/docs' % dbname, 'DELETE')) + self.assertIsNone(self._urlmap.match('/%s/docs' % dbname, 'POST')) + + def test_user_db_doc_unauthorized(self): + dbname = self._dbname + self.assertIsNone(self._urlmap.match('/%s/doc/x' % dbname, 'GET')) + self.assertIsNone(self._urlmap.match('/%s/doc/x' % dbname, 'PUT')) + self.assertIsNone(self._urlmap.match('/%s/doc/x' % dbname, 'DELETE')) + self.assertIsNone(self._urlmap.match('/%s/doc/x' % dbname, 'POST')) + + def test_user_db_sync_authorized(self): + uuid = self._uuid + dbname = self._dbname + match = self._urlmap.match('/%s/sync-from/x' % dbname, 'GET') self.assertEqual(uuid, match.get('uuid')) self.assertEqual('x', match.get('source_replica_uid')) - match = urlmap.match('/%s/sync-from/x' % dbname, 'PUT') + match = self._urlmap.match('/%s/sync-from/x' % dbname, 'PUT') self.assertEqual(uuid, match.get('uuid')) self.assertEqual('x', match.get('source_replica_uid')) - match = urlmap.match('/%s/sync-from/x' % dbname, 'DELETE') - self.assertIsNone(match) - - match = urlmap.match('/%s/sync-from/x' % dbname, 'POST') + match = self._urlmap.match('/%s/sync-from/x' % dbname, 'POST') self.assertEqual(uuid, match.get('uuid')) self.assertEqual('x', match.get('source_replica_uid')) + def test_user_db_sync_unauthorized(self): + dbname = self._dbname + self.assertIsNone( + self._urlmap.match('/%s/sync-from/x' % dbname, 'DELETE')) + @pytest.mark.usefixtures("method_tmpdir") class EncryptedSyncTestCase( -- cgit v1.2.3 From 0e12cd3eb1e20bb867f34e0bf60f280d93b6182d Mon Sep 17 00:00:00 2001 From: drebs Date: Wed, 18 Jan 2017 17:28:01 -0200 Subject: [feature] add server config option for blobs --- testing/tests/server/test_server.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'testing/tests/server/test_server.py') diff --git a/testing/tests/server/test_server.py b/testing/tests/server/test_server.py index da69c423..866d9eab 100644 --- a/testing/tests/server/test_server.py +++ b/testing/tests/server/test_server.py @@ -379,5 +379,6 @@ class ConfigurationParsingTest(unittest.TestCase): 'sudo -u soledad-admin /usr/bin/create-user-db', 'admin_netrc': '/etc/couchdb/couchdb-soledad-admin.netrc', - 'batching': False} + 'batching': False, + 'blobs': False} self.assertDictEqual(expected, config['soledad-server']) -- cgit v1.2.3 From e05e9566c55e20833a2c45fe2ca67e60df009aac Mon Sep 17 00:00:00 2001 From: drebs Date: Thu, 2 Feb 2017 12:15:45 -0200 Subject: [test] move server auth tests to its own file --- testing/tests/server/test_server.py | 46 ------------------------------------- 1 file changed, 46 deletions(-) (limited to 'testing/tests/server/test_server.py') diff --git a/testing/tests/server/test_server.py b/testing/tests/server/test_server.py index 866d9eab..ec0fc31d 100644 --- a/testing/tests/server/test_server.py +++ b/testing/tests/server/test_server.py @@ -21,7 +21,6 @@ import binascii import os import pytest -from pkg_resources import resource_filename from urlparse import urljoin from uuid import uuid4 @@ -40,8 +39,6 @@ from test_soledad.util import ( from leap.soledad.client import _crypto from leap.soledad.client import Soledad -from leap.soledad.server.config import load_configuration -from leap.soledad.server.config import CONFIG_DEFAULTS from leap.soledad.server.url_mapper import URLMapper @@ -339,46 +336,3 @@ class EncryptedSyncTestCase( Test if Soledad can sync many smallfiles. """ return self._test_encrypted_sym_sync(doc_size=2, number_of_docs=100) - - -class ConfigurationParsingTest(unittest.TestCase): - - def setUp(self): - self.maxDiff = None - - def test_use_defaults_on_failure(self): - config = load_configuration('this file will never exist') - expected = CONFIG_DEFAULTS - self.assertEquals(expected, config) - - def test_security_values_configuration(self): - # given - config_path = resource_filename('test_soledad', - 'fixture_soledad.conf') - # when - config = load_configuration(config_path) - - # then - expected = {'members': ['user1', 'user2'], - 'members_roles': ['role1', 'role2'], - 'admins': ['user3', 'user4'], - 'admins_roles': ['role3', 'role3']} - self.assertDictEqual(expected, config['database-security']) - - def test_server_values_configuration(self): - # given - config_path = resource_filename('test_soledad', - 'fixture_soledad.conf') - # when - config = load_configuration(config_path) - - # then - expected = {'couch_url': - 'http://soledad:passwd@localhost:5984', - 'create_cmd': - 'sudo -u soledad-admin /usr/bin/create-user-db', - 'admin_netrc': - '/etc/couchdb/couchdb-soledad-admin.netrc', - 'batching': False, - 'blobs': False} - self.assertDictEqual(expected, config['soledad-server']) -- cgit v1.2.3 From 4ae57257fa2d40ceeba1558d995d3514e6f6d6fa Mon Sep 17 00:00:00 2001 From: drebs Date: Thu, 2 Feb 2017 12:28:19 -0200 Subject: [test] move server url mapper tests to its own file --- testing/tests/server/test_server.py | 109 ------------------------------------ 1 file changed, 109 deletions(-) (limited to 'testing/tests/server/test_server.py') diff --git a/testing/tests/server/test_server.py b/testing/tests/server/test_server.py index ec0fc31d..647ef5a8 100644 --- a/testing/tests/server/test_server.py +++ b/testing/tests/server/test_server.py @@ -25,7 +25,6 @@ from urlparse import urljoin from uuid import uuid4 from twisted.internet import defer -from twisted.trial import unittest from leap.soledad.common.couch.state import CouchServerState from leap.soledad.common.couch import CouchDatabase @@ -39,114 +38,6 @@ from test_soledad.util import ( from leap.soledad.client import _crypto from leap.soledad.client import Soledad -from leap.soledad.server.url_mapper import URLMapper - - -class URLMapperTestCase(unittest.TestCase): - """ - Test if the URLMapper behaves as expected. - - The following table lists the authorized actions among all possible - u1db remote actions: - - URL path | Authorized actions - -------------------------------------------------- - / | GET - /shared-db | GET - /shared-db/docs | - - /shared-db/doc/{id} | - - /shared-db/sync-from/{source} | - - /user-db | - - /user-db/docs | - - /user-db/doc/{id} | - - /user-db/sync-from/{source} | GET, PUT, POST - """ - - def setUp(self): - self._uuid = uuid4().hex - self._urlmap = URLMapper() - self._dbname = 'user-%s' % self._uuid - - def test_root_authorized(self): - match = self._urlmap.match('/', 'GET') - self.assertIsNotNone(match) - - def test_shared_authorized(self): - self.assertIsNotNone(self._urlmap.match('/shared', 'GET')) - - def test_shared_unauthorized(self): - self.assertIsNone(self._urlmap.match('/shared', 'PUT')) - self.assertIsNone(self._urlmap.match('/shared', 'DELETE')) - self.assertIsNone(self._urlmap.match('/shared', 'POST')) - - def test_shared_docs_unauthorized(self): - self.assertIsNone(self._urlmap.match('/shared/docs', 'GET')) - self.assertIsNone(self._urlmap.match('/shared/docs', 'PUT')) - self.assertIsNone(self._urlmap.match('/shared/docs', 'DELETE')) - self.assertIsNone(self._urlmap.match('/shared/docs', 'POST')) - - def test_shared_doc_authorized(self): - match = self._urlmap.match('/shared/doc/x', 'GET') - self.assertIsNotNone(match) - self.assertEqual('x', match.get('id')) - - match = self._urlmap.match('/shared/doc/x', 'PUT') - self.assertIsNotNone(match) - self.assertEqual('x', match.get('id')) - - match = self._urlmap.match('/shared/doc/x', 'DELETE') - self.assertIsNotNone(match) - self.assertEqual('x', match.get('id')) - - def test_shared_doc_unauthorized(self): - self.assertIsNone(self._urlmap.match('/shared/doc/x', 'POST')) - - def test_shared_sync_unauthorized(self): - self.assertIsNone(self._urlmap.match('/shared/sync-from/x', 'GET')) - self.assertIsNone(self._urlmap.match('/shared/sync-from/x', 'PUT')) - self.assertIsNone(self._urlmap.match('/shared/sync-from/x', 'DELETE')) - self.assertIsNone(self._urlmap.match('/shared/sync-from/x', 'POST')) - - def test_user_db_unauthorized(self): - dbname = self._dbname - self.assertIsNone(self._urlmap.match('/%s' % dbname, 'GET')) - self.assertIsNone(self._urlmap.match('/%s' % dbname, 'PUT')) - self.assertIsNone(self._urlmap.match('/%s' % dbname, 'DELETE')) - self.assertIsNone(self._urlmap.match('/%s' % dbname, 'POST')) - - def test_user_db_docs_unauthorized(self): - dbname = self._dbname - self.assertIsNone(self._urlmap.match('/%s/docs' % dbname, 'GET')) - self.assertIsNone(self._urlmap.match('/%s/docs' % dbname, 'PUT')) - self.assertIsNone(self._urlmap.match('/%s/docs' % dbname, 'DELETE')) - self.assertIsNone(self._urlmap.match('/%s/docs' % dbname, 'POST')) - - def test_user_db_doc_unauthorized(self): - dbname = self._dbname - self.assertIsNone(self._urlmap.match('/%s/doc/x' % dbname, 'GET')) - self.assertIsNone(self._urlmap.match('/%s/doc/x' % dbname, 'PUT')) - self.assertIsNone(self._urlmap.match('/%s/doc/x' % dbname, 'DELETE')) - self.assertIsNone(self._urlmap.match('/%s/doc/x' % dbname, 'POST')) - - def test_user_db_sync_authorized(self): - uuid = self._uuid - dbname = self._dbname - match = self._urlmap.match('/%s/sync-from/x' % dbname, 'GET') - self.assertEqual(uuid, match.get('uuid')) - self.assertEqual('x', match.get('source_replica_uid')) - - match = self._urlmap.match('/%s/sync-from/x' % dbname, 'PUT') - self.assertEqual(uuid, match.get('uuid')) - self.assertEqual('x', match.get('source_replica_uid')) - - match = self._urlmap.match('/%s/sync-from/x' % dbname, 'POST') - self.assertEqual(uuid, match.get('uuid')) - self.assertEqual('x', match.get('source_replica_uid')) - - def test_user_db_sync_unauthorized(self): - dbname = self._dbname - self.assertIsNone( - self._urlmap.match('/%s/sync-from/x' % dbname, 'DELETE')) @pytest.mark.usefixtures("method_tmpdir") -- cgit v1.2.3 From b433c1ed736f5d4c19da4cdb21108a02459ca7fd Mon Sep 17 00:00:00 2001 From: drebs Date: Sat, 25 Feb 2017 08:53:38 -0300 Subject: [refactor] pass soledad object to client secrets api In order to be able to change passphrase, token and offline status of soledad from the bitmask client api, the secrets api also has to be able to use up-to-date values when encrypting/decrypting secrets and uploading/downloading them to the server. This commit makes public some soledad attributes that were previously "private" (i.e. used to start with "_" and were not meant to be accessed from outside), and passes the whole soledad object to the client secrets api. This makes the code cleaner and also allows for always getting newest values of soledad attributes. --- testing/tests/server/test_server.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'testing/tests/server/test_server.py') diff --git a/testing/tests/server/test_server.py b/testing/tests/server/test_server.py index 647ef5a8..4a5ec43f 100644 --- a/testing/tests/server/test_server.py +++ b/testing/tests/server/test_server.py @@ -135,7 +135,7 @@ class EncryptedSyncTestCase( user=user, prefix='x', auth_token='auth-token', - secrets_path=sol1._secrets_path, + secrets_path=sol1.secrets_path, passphrase=passphrase) # ensure remote db exists before syncing -- cgit v1.2.3