summaryrefslogtreecommitdiff
path: root/src/leap/bitmask/services/mail
diff options
context:
space:
mode:
Diffstat (limited to 'src/leap/bitmask/services/mail')
-rw-r--r--src/leap/bitmask/services/mail/conductor.py64
-rw-r--r--src/leap/bitmask/services/mail/imap.py39
-rw-r--r--src/leap/bitmask/services/mail/imapcontroller.py68
-rw-r--r--src/leap/bitmask/services/mail/plumber.py16
-rw-r--r--src/leap/bitmask/services/mail/smtpbootstrapper.py7
-rw-r--r--src/leap/bitmask/services/mail/smtpconfig.py4
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):