diff options
author | Kali Kaneko <kali@leap.se> | 2015-08-31 14:54:52 -0400 |
---|---|---|
committer | Kali Kaneko <kali@leap.se> | 2015-08-31 14:54:52 -0400 |
commit | f4547479fc050f338845f4f546d8dd7c0e4512eb (patch) | |
tree | 0f737c7f102674230f5467ecaf17720e1d28f6eb /src/leap/bitmask/services/mail | |
parent | dd43dad4b150adb66e571a56a8a5c053dec858d0 (diff) | |
parent | fd27f48a35736d8ba186c423a7de15ffee5143dd (diff) |
Merge tag '0.9.0rc2' into debian/experimental
Tag leap.bitmask version 0.9.0rc2
Diffstat (limited to 'src/leap/bitmask/services/mail')
-rw-r--r-- | src/leap/bitmask/services/mail/conductor.py | 64 | ||||
-rw-r--r-- | src/leap/bitmask/services/mail/imap.py | 39 | ||||
-rw-r--r-- | src/leap/bitmask/services/mail/imapcontroller.py | 68 | ||||
-rw-r--r-- | src/leap/bitmask/services/mail/plumber.py | 16 | ||||
-rw-r--r-- | src/leap/bitmask/services/mail/smtpbootstrapper.py | 7 | ||||
-rw-r--r-- | src/leap/bitmask/services/mail/smtpconfig.py | 4 |
6 files changed, 115 insertions, 83 deletions
diff --git a/src/leap/bitmask/services/mail/conductor.py b/src/leap/bitmask/services/mail/conductor.py index 0fb9f4fa..68197d9d 100644 --- a/src/leap/bitmask/services/mail/conductor.py +++ b/src/leap/bitmask/services/mail/conductor.py @@ -17,18 +17,17 @@ """ Mail Services Conductor """ -import logging - from leap.bitmask.config import flags +from leap.bitmask.logs.utils import get_logger from leap.bitmask.gui import statemachines from leap.bitmask.services.mail import connection as mail_connection from leap.bitmask.services.mail.emailfirewall import get_email_firewall -from leap.common.events import events_pb2 as leap_events +from leap.common.events import catalog from leap.common.events import register as leap_register -logger = logging.getLogger(__name__) +logger = get_logger() class IMAPControl(object): @@ -42,15 +41,12 @@ class IMAPControl(object): self.imap_machine = None self.imap_connection = None - leap_register(signal=leap_events.IMAP_SERVICE_STARTED, - callback=self._handle_imap_events, - reqcbk=lambda req, resp: None) - leap_register(signal=leap_events.IMAP_SERVICE_FAILED_TO_START, - callback=self._handle_imap_events, - reqcbk=lambda req, resp: None) - leap_register(signal=leap_events.IMAP_CLIENT_LOGIN, - callback=self._handle_imap_events, - reqcbk=lambda req, resp: None) + leap_register(event=catalog.IMAP_SERVICE_STARTED, + callback=self._handle_imap_events) + leap_register(event=catalog.IMAP_SERVICE_FAILED_TO_START, + callback=self._handle_imap_events) + leap_register(event=catalog.IMAP_CLIENT_LOGIN, + callback=self._handle_imap_events) def set_imap_connection(self, imap_connection): """ @@ -77,25 +73,29 @@ class IMAPControl(object): self._backend.imap_stop_service() - def _handle_imap_events(self, req): + def _handle_imap_events(self, event, content): """ Callback handler for the IMAP events - :param req: Request type - :type req: leap.common.events.events_pb2.SignalRequest + :param event: The event that triggered the callback. + :type event: str + :param content: The content of the event. + :type content: list """ - if req.event == leap_events.IMAP_SERVICE_STARTED: + if event == catalog.IMAP_SERVICE_STARTED: self._on_imap_connected() - elif req.event == leap_events.IMAP_SERVICE_FAILED_TO_START: + elif event == catalog.IMAP_SERVICE_FAILED_TO_START: self._on_imap_failed() - elif req.event == leap_events.IMAP_CLIENT_LOGIN: + elif event == catalog.IMAP_CLIENT_LOGIN: self._on_mail_client_logged_in() def _on_mail_client_logged_in(self): """ On mail client logged in, fetch incoming mail. """ - self._controller.imap_service_fetch() + # XXX needs to be adapted to the new-ish incoming mail service. + # Doing nothing for now, this could be moved to mail package itself. + logger.debug("A MUA has logged in, should react by forcing a fetch.") def _on_imap_connecting(self): """ @@ -124,12 +124,10 @@ class SMTPControl(object): self.smtp_connection = None self.smtp_machine = None - leap_register(signal=leap_events.SMTP_SERVICE_STARTED, - callback=self._handle_smtp_events, - reqcbk=lambda req, resp: None) - leap_register(signal=leap_events.SMTP_SERVICE_FAILED_TO_START, - callback=self._handle_smtp_events, - reqcbk=lambda req, resp: None) + leap_register(event=catalog.SMTP_SERVICE_STARTED, + callback=self._handle_smtp_events) + leap_register(event=catalog.SMTP_SERVICE_FAILED_TO_START, + callback=self._handle_smtp_events) def set_smtp_connection(self, smtp_connection): """ @@ -158,16 +156,18 @@ class SMTPControl(object): self.smtp_connection.qtsigs.disconnecting_signal.emit() self._backend.smtp_stop_service() - def _handle_smtp_events(self, req): + def _handle_smtp_events(self, event, content): """ Callback handler for the SMTP events. - :param req: Request type - :type req: leap.common.events.events_pb2.SignalRequest + :param event: The event that triggered the callback. + :type event: str + :param content: The content of the event. + :type content: list """ - if req.event == leap_events.SMTP_SERVICE_STARTED: + if event == catalog.SMTP_SERVICE_STARTED: self.on_smtp_connected() - elif req.event == leap_events.SMTP_SERVICE_FAILED_TO_START: + elif event == catalog.SMTP_SERVICE_FAILED_TO_START: self.on_smtp_failed() def on_smtp_connecting(self): @@ -262,7 +262,7 @@ class MailConductor(IMAPControl, SMTPControl): if self._firewall is not None: self._firewall.start() if not offline: - logger.debug("not starting smtp in offline mode") + logger.debug("Starting smtp service...") self.start_smtp_service(download_if_needed=download_if_needed) self.start_imap_service() diff --git a/src/leap/bitmask/services/mail/imap.py b/src/leap/bitmask/services/mail/imap.py index 5db18cb9..5934756d 100644 --- a/src/leap/bitmask/services/mail/imap.py +++ b/src/leap/bitmask/services/mail/imap.py @@ -17,14 +17,16 @@ """ Initialization of imap service """ -import logging import os import sys +from leap.bitmask.logs.utils import get_logger +from leap.mail.constants import INBOX_NAME from leap.mail.imap.service import imap +from leap.mail.incoming.service import IncomingMail, INCOMING_CHECK_PERIOD from twisted.python import log -logger = logging.getLogger(__name__) +logger = get_logger() # The name of the environment variable that has to be # set to override the default time value, in seconds. @@ -49,6 +51,9 @@ def get_mail_check_period(): logger.warning("Unhandled error while getting %s: %r" % ( INCOMING_CHECK_PERIOD_ENV, exc)) + + if period is None: + period = INCOMING_CHECK_PERIOD return period @@ -61,12 +66,34 @@ def start_imap_service(*args, **kwargs): from leap.bitmask.config import flags logger.debug('Launching imap service') - override_period = get_mail_check_period() - if override_period: - kwargs['check_period'] = override_period - if flags.MAIL_LOGFILE: log.startLogging(open(flags.MAIL_LOGFILE, 'w')) log.startLogging(sys.stdout) return imap.run_service(*args, **kwargs) + + +def start_incoming_mail_service(keymanager, soledad, imap_factory, userid): + """ + Initalizes and starts the incomming mail service. + + :returns: a Deferred that will be fired with the IncomingMail instance + """ + def setUpIncomingMail(inbox): + incoming_mail = IncomingMail( + keymanager, + soledad, + inbox.collection, + userid, + check_period=get_mail_check_period()) + return incoming_mail + + # XXX: do I really need to know here how to get a mailbox?? + # XXX: ideally, the parent service in mail would take care of initializing + # the account, and passing the mailbox to the incoming service. + # In an even better world, we just would subscribe to a channel that would + # pass us the serialized object to be inserted. + acc = imap_factory.theAccount + d = acc.callWhenReady(lambda _: acc.getMailbox(INBOX_NAME)) + d.addCallback(setUpIncomingMail) + return d diff --git a/src/leap/bitmask/services/mail/imapcontroller.py b/src/leap/bitmask/services/mail/imapcontroller.py index d0bf4c34..e5313477 100644 --- a/src/leap/bitmask/services/mail/imapcontroller.py +++ b/src/leap/bitmask/services/mail/imapcontroller.py @@ -17,12 +17,10 @@ """ IMAP service controller. """ -import logging - +from leap.bitmask.logs.utils import get_logger from leap.bitmask.services.mail import imap - -logger = logging.getLogger(__name__) +logger = get_logger() class IMAPController(object): @@ -43,9 +41,12 @@ class IMAPController(object): self._soledad = soledad self._keymanager = keymanager - self.imap_service = None + # XXX: this should live in its own controller + # or, better, just be managed by a composite Mail Service in + # leap.mail. self.imap_port = None self.imap_factory = None + self.incoming_mail_service = None def start_imap_service(self, userid, offline=False): """ @@ -58,46 +59,53 @@ class IMAPController(object): """ logger.debug('Starting imap service') - self.imap_service, self.imap_port, \ - self.imap_factory = imap.start_imap_service( - self._soledad, - self._keymanager, - userid=userid, - offline=offline) + self.imap_port, self.imap_factory = imap.start_imap_service( + self._soledad, + userid=userid) + + def start_incoming_service(incoming_mail): + d = incoming_mail.startService() + d.addCallback(lambda started: incoming_mail) + return d + + def assign_incoming_service(incoming_mail): + self.incoming_mail_service = incoming_mail + return incoming_mail if offline is False: - logger.debug("Starting loop") - self.imap_service.start_loop() + d = imap.start_incoming_mail_service( + self._keymanager, + self._soledad, + self.imap_factory, + userid) + d.addCallback(start_incoming_service) + d.addCallback(assign_incoming_service) + d.addErrback(lambda f: logger.error(f.printTraceback())) - def stop_imap_service(self, cv): + def stop_imap_service(self): """ Stop IMAP service (fetcher, factory and port). - - :param cv: A condition variable to which we can signal when imap - indeed stops. - :type cv: threading.Condition """ - if self.imap_service is not None: + if self.incoming_mail_service is not None: # Stop the loop call in the fetcher - self.imap_service.stop() - self.imap_service = None + # XXX BUG -- the deletion of the reference should be made + # after stopService() triggers its deferred (ie, cleanup has been + # made) + self.incoming_mail_service.stopService() + self.incoming_mail_service = None + + if self.imap_port is not None: # Stop listening on the IMAP port self.imap_port.stopListening() # Stop the protocol - self.imap_factory.theAccount.closed = True - self.imap_factory.doStop(cv) - else: - # Release the condition variable so the caller doesn't have to wait - cv.acquire() - cv.notify() - cv.release() + self.imap_factory.doStop() def fetch_incoming_mail(self): """ Fetch incoming mail. """ - if self.imap_service: + if self.incoming_mail_service is not None: logger.debug('Client connected, fetching mail...') - self.imap_service.fetch() + self.incoming_mail_service.fetch() diff --git a/src/leap/bitmask/services/mail/plumber.py b/src/leap/bitmask/services/mail/plumber.py index 1af65c5d..43203f0c 100644 --- a/src/leap/bitmask/services/mail/plumber.py +++ b/src/leap/bitmask/services/mail/plumber.py @@ -17,6 +17,8 @@ """ Utils for manipulating local mailboxes. """ +# TODO --- this module has not yet catched up with 0.9.0 + import getpass import logging import os @@ -28,17 +30,15 @@ from twisted.internet import defer from leap.bitmask.backend.settings import Settings from leap.bitmask.config.providerconfig import ProviderConfig +from leap.bitmask.logs.utils import get_logger from leap.bitmask.provider import get_provider_path from leap.bitmask.services.soledad.soledadbootstrapper import get_db_paths from leap.bitmask.util import flatten, get_path_prefix -from leap.mail.imap.account import SoledadBackedAccount -from leap.mail.imap.memorystore import MemoryStore -from leap.mail.imap.soledadstore import SoledadStore +from leap.mail.imap.account import IMAPAccount from leap.soledad.client import Soledad -logger = logging.getLogger(__name__) -logger.setLevel(logging.DEBUG) +logger = get_logger() def initialize_soledad(uuid, email, passwd, @@ -140,11 +140,7 @@ class MBOXPlumber(object): self.sol = initialize_soledad( self.uuid, self.userid, self.passwd, secrets, localdb, "/tmp", "/tmp") - memstore = MemoryStore( - permanent_store=SoledadStore(self.sol), - write_period=5) - self.acct = SoledadBackedAccount(self.userid, self.sol, - memstore=memstore) + self.acct = IMAPAccount(self.userid, self.sol) return True # diff --git a/src/leap/bitmask/services/mail/smtpbootstrapper.py b/src/leap/bitmask/services/mail/smtpbootstrapper.py index 9dd61488..cd871803 100644 --- a/src/leap/bitmask/services/mail/smtpbootstrapper.py +++ b/src/leap/bitmask/services/mail/smtpbootstrapper.py @@ -17,11 +17,11 @@ """ SMTP bootstrapping """ -import logging import os from leap.bitmask.config.providerconfig import ProviderConfig from leap.bitmask.crypto.certs import download_client_cert +from leap.bitmask.logs.utils import get_logger from leap.bitmask.services import download_service_config from leap.bitmask.services.abstractbootstrapper import AbstractBootstrapper from leap.bitmask.services.mail.smtpconfig import SMTPConfig @@ -31,7 +31,7 @@ from leap.common import certs as leap_certs from leap.common.check import leap_assert from leap.common.files import check_and_fix_urw_only -logger = logging.getLogger(__name__) +logger = get_logger() class NoSMTPHosts(Exception): @@ -120,6 +120,7 @@ class SMTPBootstrapper(AbstractBootstrapper): self._provider_config, about_to_download=True) from leap.mail.smtp import setup_smtp_gateway + self._smtp_service, self._smtp_port = setup_smtp_gateway( port=2013, userid=self._userid, @@ -152,7 +153,7 @@ class SMTPBootstrapper(AbstractBootstrapper): self._provider_config = ProviderConfig.get_provider_config(domain) self._keymanager = keymanager self._smtp_config = SMTPConfig() - self._userid = userid + self._userid = str(userid) self._download_if_needed = download_if_needed try: diff --git a/src/leap/bitmask/services/mail/smtpconfig.py b/src/leap/bitmask/services/mail/smtpconfig.py index 09f90314..2d8de411 100644 --- a/src/leap/bitmask/services/mail/smtpconfig.py +++ b/src/leap/bitmask/services/mail/smtpconfig.py @@ -17,16 +17,16 @@ """ SMTP configuration """ -import logging import os from leap.bitmask.config.providerconfig import ProviderConfig +from leap.bitmask.logs.utils import get_logger from leap.bitmask.services import ServiceConfig from leap.bitmask.services.mail.smtpspec import get_schema from leap.bitmask.util import get_path_prefix from leap.common.check import leap_assert, leap_assert_type -logger = logging.getLogger(__name__) +logger = get_logger() class SMTPConfig(ServiceConfig): |