summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--service/pixelated/bitmask_libraries/nicknym.py4
-rw-r--r--service/pixelated/bitmask_libraries/provider.py14
-rw-r--r--service/pixelated/bitmask_libraries/session.py78
-rw-r--r--service/pixelated/bitmask_libraries/soledad.py74
-rw-r--r--service/pixelated/config/services.py2
-rw-r--r--service/pixelated/maintenance.py2
-rw-r--r--service/test/unit/bitmask_libraries/test_nicknym.py4
-rw-r--r--service/test/unit/bitmask_libraries/test_soledad.py61
8 files changed, 67 insertions, 172 deletions
diff --git a/service/pixelated/bitmask_libraries/nicknym.py b/service/pixelated/bitmask_libraries/nicknym.py
index 826ecb58..f931f3a9 100644
--- a/service/pixelated/bitmask_libraries/nicknym.py
+++ b/service/pixelated/bitmask_libraries/nicknym.py
@@ -19,11 +19,11 @@ from twisted.internet import defer
class NickNym(object):
- def __init__(self, provider, config, soledad_session, email_address, token, uuid):
+ def __init__(self, provider, config, soledad, email_address, token, uuid):
nicknym_url = _discover_nicknym_server(provider)
self._email = email_address
self.keymanager = KeyManager(self._email, nicknym_url,
- soledad_session.soledad,
+ soledad,
token=token, ca_cert_path=LeapCertificate(provider).provider_api_cert, api_uri=provider.api_uri,
api_version=provider.api_version,
uid=uuid, gpgbinary=config.gpg_binary)
diff --git a/service/pixelated/bitmask_libraries/provider.py b/service/pixelated/bitmask_libraries/provider.py
index a529208d..75dcd3ae 100644
--- a/service/pixelated/bitmask_libraries/provider.py
+++ b/service/pixelated/bitmask_libraries/provider.py
@@ -20,6 +20,7 @@ from leap.common.certs import get_digest
import requests
from .certs import LeapCertificate
from pixelated.support.tls_adapter import EnforceTLSv1Adapter
+from pixelated.bitmask_libraries.soledad import SoledadDiscoverException
class LeapProvider(object):
@@ -138,3 +139,16 @@ class LeapProvider(object):
def address_for(self, username):
return '%s@%s' % (username, self.domain)
+
+ def discover_soledad_server(self, user_uuid):
+ try:
+ json_data = self.fetch_soledad_json()
+
+ hosts = json_data['hosts']
+ host = hosts.keys()[0]
+ server_url = 'https://%s:%d/user-%s' % \
+ (hosts[host]['hostname'], hosts[host]['port'],
+ user_uuid)
+ return server_url
+ except Exception, e:
+ raise SoledadDiscoverException(e)
diff --git a/service/pixelated/bitmask_libraries/session.py b/service/pixelated/bitmask_libraries/session.py
index 53f35008..45ad1374 100644
--- a/service/pixelated/bitmask_libraries/session.py
+++ b/service/pixelated/bitmask_libraries/session.py
@@ -27,7 +27,7 @@ from leap.mail.imap.account import IMAPAccount
from leap.auth import SRPAuth
from .nicknym import NickNym
from .smtp import LeapSMTPConfig
-from .soledad import SoledadSessionFactory
+from .soledad import SoledadFactory
from leap.common.events import (
register,
@@ -39,36 +39,14 @@ SESSIONS = {}
class LeapSession(object):
- """
- A LEAP session.
-
- Properties:
-
- - ``smtp`` the smtp gateway instance (LeapSmtp).
-
- - ``config`` the configuration for this session (LeapClientConfig).
-
- - ``provider`` the responsible for interacting with provider.json (LeapProvider).
-
- - ``user_auth`` the secure remote password session data after authenticating with LEAP. See http://en.wikipedia.org/wiki/Secure_Remote_Password_protocol (SRPSession)
-
- - ``mail_store`` the MailStore to access the users mails
-
- - ``soledad_session`` the soledad session. See https://leap.se/soledad (LeapSecureRemotePassword)
-
- - ``nicknym`` the nicknym instance. See https://leap.se/nicknym (NickNym)
-
- - ``incoming_mail_fetcher`` Background job for fetching incoming mails from LEAP server (LeapIncomingMail)
- """
-
- def __init__(self, provider, user_auth, mail_store, soledad_session, nicknym, smtp_config):
+ def __init__(self, provider, user_auth, mail_store, soledad, nicknym, smtp_config):
self.smtp_config = smtp_config
self.config = provider.config
self.provider = provider
self.user_auth = user_auth
self.mail_store = mail_store
- self.soledad_session = soledad_session
+ self.soledad = soledad
self.nicknym = nicknym
self.fresh_account = False
register(events.KEYMANAGER_FINISHED_KEY_GENERATION, self._set_fresh_account)
@@ -82,16 +60,16 @@ class LeapSession(object):
@defer.inlineCallbacks
def after_first_sync(self):
yield self.nicknym.generate_openpgp_key()
- self.account = self._create_account(self.account_email, self.soledad_session)
+ self.account = self._create_account(self.account_email, self.soledad)
self.incoming_mail_fetcher = yield self._create_incoming_mail_fetcher(
self.nicknym,
- self.soledad_session,
+ self.soledad,
self.account,
self.account_email())
reactor.callFromThread(self.incoming_mail_fetcher.startService)
- def _create_account(self, user_mail, soledad_session):
- account = IMAPAccount(user_mail, soledad_session.soledad)
+ def _create_account(self, user_mail, soledad):
+ account = IMAPAccount(user_mail, soledad)
return account
def _set_fresh_account(self, *args):
@@ -105,10 +83,10 @@ class LeapSession(object):
self.stop_background_jobs
@defer.inlineCallbacks
- def _create_incoming_mail_fetcher(self, nicknym, soledad_session, account, user_mail):
+ def _create_incoming_mail_fetcher(self, nicknym, soledad, account, user_mail):
inbox = yield account.callWhenReady(lambda _: account.getMailbox('INBOX'))
defer.returnValue(IncomingMail(nicknym.keymanager,
- soledad_session.soledad,
+ soledad,
inbox.collection,
user_mail))
@@ -117,7 +95,7 @@ class LeapSession(object):
def sync(self):
try:
- return self.soledad_session.sync()
+ return self.soledad.sync()
except:
traceback.print_exc(file=sys.stderr)
raise
@@ -175,13 +153,20 @@ class LeapSessionFactory(object):
auth = srp_auth.authenticate(username, password)
account_email = self._provider.address_for(username)
- soledad = SoledadSessionFactory.create(self._provider, auth.token, auth.uuid, password)
- mail_store = LeapMailStore(soledad.soledad)
+ self._create_database_dir()
+ soledad = SoledadFactory.create(auth.token,
+ auth.uuid,
+ password,
+ self._secrets_path(auth.uuid),
+ self._local_db_path(auth.uuid),
+ self._provider.discover_soledad_server(auth.uuid),
+ LeapCertificate(self._provider).provider_api_cert)
+
+ mail_store = LeapMailStore(soledad)
nicknym = self._create_nicknym(account_email, auth.token, auth.uuid, soledad)
self._download_smtp_cert(auth)
-
smtp_host, smtp_port = self._provider.smtp_info()
smtp_config = LeapSMTPConfig(account_email, self._smtp_client_cert_path(), smtp_host, smtp_port)
@@ -225,8 +210,23 @@ class LeapSessionFactory(object):
else:
raise
- def _create_nicknym(self, email_address, token, uuid, soledad_session):
- return NickNym(self._provider, self._config, soledad_session, email_address, token, uuid)
+ def _create_nicknym(self, email_address, token, uuid, soledad):
+ return NickNym(self._provider, self._config, soledad, email_address, token, uuid)
+
+ def _leap_path(self):
+ return "%s/soledad" % self._config.leap_home
+
+ def _secrets_path(self, user_uuid):
+ return "%s/%s.secret" % (self._leap_path(), user_uuid)
+
+ def _local_db_path(self, user_uuid):
+ return "%s/%s.db" % (self._leap_path(), user_uuid)
- # memstore = MemoryStore(permanent_store=SoledadStore(soledad_session.soledad))
- # return SoledadBackedAccount(uuid, soledad_session.soledad, memstore)
+ def _create_database_dir(self):
+ try:
+ os.makedirs(self._leap_path())
+ except OSError as exc:
+ if exc.errno == errno.EEXIST and os.path.isdir(self._leap_path()):
+ pass
+ else:
+ raise
diff --git a/service/pixelated/bitmask_libraries/soledad.py b/service/pixelated/bitmask_libraries/soledad.py
index 0546a158..406e9fc1 100644
--- a/service/pixelated/bitmask_libraries/soledad.py
+++ b/service/pixelated/bitmask_libraries/soledad.py
@@ -13,15 +13,8 @@
#
# You should have received a copy of the GNU Affero General Public License
# along with Pixelated. If not, see <http://www.gnu.org/licenses/>.
-import errno
-
-import os
from leap.soledad.client import Soledad
from leap.soledad.common.crypto import WrongMacError, UnknownMacMethodError
-from pixelated.bitmask_libraries.certs import LeapCertificate
-
-SOLEDAD_TIMEOUT = 120
-SOLEDAD_CERT = '/tmp/ca.crt'
class SoledadDiscoverException(Exception):
@@ -34,71 +27,20 @@ class SoledadWrongPassphraseException(Exception):
super(SoledadWrongPassphraseException, self).__init__(*args, **kwargs)
-class SoledadSessionFactory(object):
- @classmethod
- def create(cls, provider, user_token, user_uuid, encryption_passphrase):
- return SoledadSession(provider, encryption_passphrase, user_token, user_uuid)
-
-
-class SoledadSession(object):
- def __init__(self, provider, encryption_passphrase, user_token, user_uuid):
- self.provider = provider
- self.config = provider.config
- self.user_uuid = user_uuid
- self.user_token = user_token
+class SoledadFactory(object):
- self.soledad = self._init_soledad(encryption_passphrase)
-
- def _init_soledad(self, encryption_passphrase):
+ @classmethod
+ def create(cls, user_token, user_uuid, encryption_passphrase, secrets, local_db, server_url, api_cert):
try:
- server_url = self._discover_soledad_server()
-
- self._create_database_dir()
- secrets = self._secrets_path()
- local_db = self._local_db_path()
-
- return Soledad(self.user_uuid,
+ return Soledad(user_uuid,
passphrase=unicode(encryption_passphrase),
secrets_path=secrets,
- local_db_path=local_db, server_url=server_url,
- cert_file=LeapCertificate(self.provider).provider_api_cert,
+ local_db_path=local_db,
+ server_url=server_url,
+ cert_file=api_cert,
shared_db=None,
- auth_token=self.user_token,
+ auth_token=user_token,
defer_encryption=False)
except (WrongMacError, UnknownMacMethodError), e:
raise SoledadWrongPassphraseException(e)
-
- def _leap_path(self):
- return "%s/soledad" % self.config.leap_home
-
- def _secrets_path(self):
- return "%s/%s.secret" % (self._leap_path(), self.user_uuid)
-
- def _local_db_path(self):
- return "%s/%s.db" % (self._leap_path(), self.user_uuid)
-
- def _create_database_dir(self):
- try:
- os.makedirs(self._leap_path())
- except OSError as exc:
- if exc.errno == errno.EEXIST and os.path.isdir(self._leap_path()):
- pass
- else:
- raise
-
- def sync(self):
- return self.soledad.sync()
-
- def _discover_soledad_server(self):
- try:
- json_data = self.provider.fetch_soledad_json()
-
- hosts = json_data['hosts']
- host = hosts.keys()[0]
- server_url = 'https://%s:%d/user-%s' % \
- (hosts[host]['hostname'], hosts[host]['port'],
- self.user_uuid)
- return server_url
- except Exception, e:
- raise SoledadDiscoverException(e)
diff --git a/service/pixelated/config/services.py b/service/pixelated/config/services.py
index 65a67a3d..35429c01 100644
--- a/service/pixelated/config/services.py
+++ b/service/pixelated/config/services.py
@@ -19,7 +19,7 @@ class Services(object):
def setup(self, leap_home, leap_session):
InputMail.FROM_EMAIL_ADDRESS = leap_session.account_email()
- search_index_storage_key = self.setup_search_index_storage_key(leap_session.soledad_session.soledad)
+ search_index_storage_key = self.setup_search_index_storage_key(leap_session.soledad)
yield self.setup_search_engine(
leap_home,
search_index_storage_key)
diff --git a/service/pixelated/maintenance.py b/service/pixelated/maintenance.py
index b18e881d..5e5f8da0 100644
--- a/service/pixelated/maintenance.py
+++ b/service/pixelated/maintenance.py
@@ -65,7 +65,7 @@ def execute_command(args, leap_session):
return leap_session
def get_soledad_handle(leap_session):
- soledad = leap_session.soledad_session.soledad
+ soledad = leap_session.soledad
return leap_session, soledad
diff --git a/service/test/unit/bitmask_libraries/test_nicknym.py b/service/test/unit/bitmask_libraries/test_nicknym.py
index dc4845d1..13e61a0a 100644
--- a/service/test/unit/bitmask_libraries/test_nicknym.py
+++ b/service/test/unit/bitmask_libraries/test_nicknym.py
@@ -29,7 +29,7 @@ class NickNymTest(AbstractLeapTest):
# when
NickNym(self.provider,
self.config,
- self.soledad_session,
+ self.soledad,
'test_user@some-server.test',
self.auth.token,
self.auth.uuid)
@@ -53,7 +53,7 @@ class NickNymTest(AbstractLeapTest):
keyman.get_key.side_effect = KeyNotFound
nicknym = NickNym(self.provider,
self.config,
- self.soledad_session,
+ self.soledad,
'test_user@some-server.test',
self.auth.token,
self.auth.uuid)
diff --git a/service/test/unit/bitmask_libraries/test_soledad.py b/service/test/unit/bitmask_libraries/test_soledad.py
deleted file mode 100644
index af2cfd0a..00000000
--- a/service/test/unit/bitmask_libraries/test_soledad.py
+++ /dev/null
@@ -1,61 +0,0 @@
-#
-# Copyright (c) 2014 ThoughtWorks, Inc.
-#
-# Pixelated is free software: you can redistribute it and/or modify
-# it under the terms of the GNU Affero General Public License as published by
-# the Free Software Foundation, either version 3 of the License, or
-# (at your option) any later version.
-#
-# Pixelated is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-# GNU Affero General Public License for more details.
-#
-# You should have received a copy of the GNU Affero General Public License
-# along with Pixelated. If not, see <http://www.gnu.org/licenses/>.
-from mock import patch
-from pixelated.bitmask_libraries.soledad import SoledadSession
-from pixelated.bitmask_libraries.certs import LeapCertificate
-from test_abstract_leap import AbstractLeapTest
-
-
-class SoledadSessionTest(AbstractLeapTest):
-
- def setUp(self):
- super(SoledadSessionTest, self).setUp()
-
- # given
- self.provider.fetch_soledad_json.return_value = {'hosts': {
- 'couch1': {
- 'hostname': 'couch1.some-server.test',
- 'ip_address': '192.168.1.1',
- 'port': 1234
- }
- }}
-
- @patch('pixelated.bitmask_libraries.soledad.Soledad')
- def test_that_soledad_is_created_with_required_params(self, soledad_mock):
- soledad_mock.return_value = None
- # when
- SoledadSession(self.provider, 'any-passphrase', self.auth.token, self.auth.uuid)
-
- # then
- soledad_mock.assert_called_with(self.auth.uuid, passphrase=u'any-passphrase',
- secrets_path='%s/soledad/%s.secret' % (self.leap_home, self.auth.uuid),
- local_db_path='%s/soledad/%s.db' % (self.leap_home, self.auth.uuid),
- server_url='https://couch1.some-server.test:1234/user-%s' % self.auth.uuid,
- cert_file=LeapCertificate(self.provider).provider_api_cert,
- shared_db=None,
- auth_token=self.auth.token, defer_encryption=False)
-
- @patch('pixelated.bitmask_libraries.soledad.Soledad')
- def test_that_sync_is_called(self, soledad_mock):
- instance = soledad_mock.return_value
- instance.server_url = '/foo/bar'
- soledad_session = SoledadSession(self.provider, 'any-passphrase', self.auth.token, self.auth.uuid)
-
- # when
- soledad_session.sync()
-
- # then
- instance.sync.assert_called_with()