diff options
Diffstat (limited to 'src')
| -rw-r--r-- | src/leap/bitmask/core/mail_services.py | 78 | ||||
| -rw-r--r-- | src/leap/bitmask/core/service.py | 85 | ||||
| -rw-r--r-- | src/leap/bitmask/mail/imap/service/imap.py | 5 | ||||
| -rw-r--r-- | src/leap/bitmask/mail/incoming/service.py | 10 | ||||
| -rw-r--r-- | src/leap/bitmask/mail/smtp/__init__.py | 9 | 
5 files changed, 110 insertions, 77 deletions
| diff --git a/src/leap/bitmask/core/mail_services.py b/src/leap/bitmask/core/mail_services.py index 04306b4..d2967f8 100644 --- a/src/leap/bitmask/core/mail_services.py +++ b/src/leap/bitmask/core/mail_services.py @@ -457,10 +457,11 @@ class StandardMailService(service.MultiService, HookableService):          self.addService(IncomingMailService(self))      def startService(self): -        log.msg('Starting Mail Service...') +        log.msg('starting mail service')          super(StandardMailService, self).startService()      def stopService(self): +        log.msg('stopping mail service')          super(StandardMailService, self).stopService()      def startInstance(self, userid, soledad, keymanager): @@ -485,9 +486,6 @@ class StandardMailService(service.MultiService, HookableService):          d.addCallback(self._write_tokens_file, userid)          return d -    def stopInstance(self): -        pass -      # hooks      def hook_on_new_keymanager_instance(self, **kw): @@ -564,20 +562,26 @@ class IMAPService(service.Service):      name = 'imap'      def __init__(self, soledad_sessions): -        port, factory = imap.run_service(soledad_sessions) - -        self._port = port -        self._factory = factory          self._soledad_sessions = soledad_sessions +        self._port = None +        self._factory = None          super(IMAPService, self).__init__()      def startService(self): -        log.msg('Starting IMAP Service') +        log.msg('starting imap service') +        port, factory = imap.run_service( +            self._soledad_sessions, factory=self._factory) +        self._port = port +        self._factory = factory          super(IMAPService, self).startService()      def stopService(self): -        self._port.stopListening() -        self._factory.doStop() +        log.msg("stopping imap service") +        if self._port: +            self._port.stopListening() +            self._port = None +        if self._factory: +            self._factory.doStop()          super(IMAPService, self).stopService() @@ -589,35 +593,47 @@ class SMTPService(service.Service):                   basedir=DEFAULT_BASEDIR):          self._basedir = os.path.expanduser(basedir) -        port, factory = smtp.run_service( -            soledad_sessions, keymanager_sessions, sendmail_opts) -        self._port = port -        self._factory = factory          self._soledad_sessions = soledad_sessions          self._keymanager_sessions = keymanager_sessions          self._sendmail_opts = sendmail_opts +        self._port = None +        self._factory = None          super(SMTPService, self).__init__()      def startService(self): -        log.msg('Starting SMTP Service') +        log.msg('starting smtp service') +        port, factory = smtp.run_service( +            self._soledad_sessions, +            self._keymanager_sessions, +            self._sendmail_opts, +            factory=self._factory) +        self._port = port +        self._factory = factory          super(SMTPService, self).startService()      def stopService(self): -        # TODO cleanup all instances +        log.msg('stopping smtp service') +        if self._port: +            self._port.stopListening() +            self._port = None +        if self._factory: +            self._factory.doStop()          super(SMTPService, self).stopService() -class IncomingMailService(service.Service): +class IncomingMailService(service.MultiService): +    """ +    Manage child services that check for incoming mail for individual users. +    """      name = 'incoming_mail'      def __init__(self, mail_service):          super(IncomingMailService, self).__init__()          self._mail = mail_service -        self._instances = {}      def startService(self): -        log.msg('Starting IncomingMail Service') +        log.msg('starting incoming mail service')          super(IncomingMailService, self).startService()      def stopService(self): @@ -625,25 +641,14 @@ class IncomingMailService(service.Service):      # Individual accounts -    # TODO IncomingMail *IS* already a service. -    # I think we should better model the current Service -    # as a startInstance inside a container, and get this -    # multi-tenant service inside the leap.mail.incoming.service. -    # ... or just simply make it a multiService and set per-user -    # instances as Child of this parent. -      def startInstance(self, userid):          soledad = self._mail.get_soledad_session(userid)          keymanager = self._mail.get_keymanager_session(userid) -        log.msg('Starting Incoming Mail instance for %s' % userid) +        log.msg('setting up incoming mail service for %s' % userid)          self._start_incoming_mail_instance(              keymanager, soledad, userid) -    def stopInstance(self, userid): -        # TODO toggle offline! -        pass -      def _start_incoming_mail_instance(self, keymanager, soledad,                                        userid, start_sync=True): @@ -652,18 +657,13 @@ class IncomingMailService(service.Service):                  keymanager, soledad,                  inbox, userid,                  check_period=INCOMING_CHECK_PERIOD) -            return incoming_mail - -        def registerInstance(incoming_instance): -            self._instances[userid] = incoming_instance -            if start_sync: -                incoming_instance.startService() +            incoming_mail.setName(userid) +            self.addService(incoming_mail)          acc = Account(soledad, userid)          d = acc.callWhenReady(              lambda _: acc.get_collection_by_mailbox(INBOX_NAME))          d.addCallback(setUpIncomingMail) -        d.addCallback(registerInstance)          d.addErrback(log.err)          return d diff --git a/src/leap/bitmask/core/service.py b/src/leap/bitmask/core/service.py index e449a8c..de99ea5 100644 --- a/src/leap/bitmask/core/service.py +++ b/src/leap/bitmask/core/service.py @@ -19,10 +19,9 @@ Bitmask-core Service.  """  import json  import resource -from os.path import join, abspath  from twisted.internet import reactor -from twisted.python import log, logfile +from twisted.python import log  from leap.bitmask import __version__  from leap.bitmask.core import configurable @@ -61,21 +60,19 @@ class BitmaskBackend(configurable.ConfigurableService):          on_start(self.init_bonafide)          if enabled('mail'): -            on_start(self.init_soledad) -            on_start(self.init_keymanager) -            on_start(self.init_mail) +            on_start(self._init_mail_services)          if enabled('eip'): -            on_start(self.init_eip) +            on_start(self._init_eip)          if enabled('zmq'): -            on_start(self.init_zmq) +            on_start(self._init_zmq)          if enabled('web'): -            on_start(self.init_web) +            on_start(self._init_web)          if enabled('websockets'): -            on_start(self.init_websockets) +            on_start(self._init_websockets)      def init_events(self):          event_server.ensure_server() @@ -93,47 +90,75 @@ class BitmaskBackend(configurable.ConfigurableService):          bf.register_hook('on_bonafide_auth', listener='keymanager')          bf.register_hook('on_bonafide_auth', listener='mail') -    def init_soledad(self): +    def _start_child_service(self, name): +        log.msg('starting backend child service: %s' % name) +        service = self.getServiceNamed(name) +        if service: +            service.startService() + +    def _stop_child_service(self, name): +        log.msg('stopping backend child service: %s' % name) +        service = self.getServiceNamed(name) +        if service: +            service.stopService() + +    def _init_mail_services(self): +            self._init_soledad() +            self._init_keymanager() +            self._init_mail() + +    def _start_mail_services(self): +        self._start_child_service('soledad') +        self._start_child_service('keymanager') +        self._start_child_service('mail') + +    def _stop_mail_services(self): +        self._stop_child_service('mail') +        self._stop_child_service('keymanager') +        self._stop_child_service('soledad') + +    def _init_soledad(self):          service = mail_services.SoledadService -        sol = self._maybe_start_service( +        sol = self._maybe_init_service(              'soledad', service, self.basedir)          if sol:              sol.register_hook(                  'on_new_soledad_instance', listener='keymanager') -    def init_keymanager(self): +    def _init_keymanager(self):          service = mail_services.KeymanagerService -        km = self._maybe_start_service( +        km = self._maybe_init_service(              'keymanager', service, self.basedir)          if km:              km.register_hook('on_new_keymanager_instance', listener='mail') -    def init_mail(self): +    def _init_mail(self):          service = mail_services.StandardMailService -        self._maybe_start_service('mail', service, self.basedir) +        self._maybe_init_service('mail', service, self.basedir) -    def init_eip(self): +    def _init_eip(self):          # FIXME -- land EIP into leap.vpn          pass -        # self._maybe_start_service('eip', EIPService) +        # self._maybe_init_service('eip', EIPService) -    def init_zmq(self): +    def _init_zmq(self):          zs = _zmq.ZMQServerService(self)          zs.setServiceParent(self) -    def init_web(self): +    def _init_web(self):          service = _web.HTTPDispatcherService -        self._maybe_start_service('web', service, self) +        self._maybe_init_service('web', service, self) -    def init_websockets(self): +    def _init_websockets(self):          from leap.bitmask.core import websocket          ws = websocket.WebSocketsDispatcherService(self)          ws.setServiceParent(self) -    def _maybe_start_service(self, label, klass, *args, **kw): +    def _maybe_init_service(self, label, klass, *args, **kw):          try:              self.getServiceNamed(label)          except KeyError: +            log.msg("initializing service: %s" % label)              service = klass(*args, **kw)              service.setName(label)              service.setServiceParent(self) @@ -158,24 +183,26 @@ class BitmaskBackend(configurable.ConfigurableService):          self.set_config('services', service, 'True')          if service == 'mail': -            self.init_soledad() -            self.init_keymanager() -            self.init_mail() +            self._init_mail_services() +            self._start_mail_services()          elif service == 'eip': -            self.init_eip() +            self._init_eip()          elif service == 'zmq': -            self.init_zmq() +            self._init_zmq()          elif service == 'web': -            self.init_web() +            self._init_web()          return {'enabled': 'ok'}      def do_disable_service(self, service):          assert service in self.service_names -        # TODO -- should stop also? + +        if service == 'mail': +            self._stop_mail_services() +          self.set_config('services', service, 'False')          return {'disabled': 'ok'} diff --git a/src/leap/bitmask/mail/imap/service/imap.py b/src/leap/bitmask/mail/imap/service/imap.py index aac49b6..9ccff4a 100644 --- a/src/leap/bitmask/mail/imap/service/imap.py +++ b/src/leap/bitmask/mail/imap/service/imap.py @@ -158,7 +158,7 @@ class LeapIMAPFactory(ServerFactory):          return ServerFactory.doStop(self) -def run_service(soledad_sessions, port=IMAP_PORT): +def run_service(soledad_sessions, port=IMAP_PORT, factory=None):      """      Main entry point to run the service from the client. @@ -169,7 +169,8 @@ def run_service(soledad_sessions, port=IMAP_PORT):                the factory for the protocol.      :rtype: tuple      """ -    factory = LeapIMAPFactory(soledad_sessions) +    if not factory: +        factory = LeapIMAPFactory(soledad_sessions)      try:          interface = "localhost" diff --git a/src/leap/bitmask/mail/incoming/service.py b/src/leap/bitmask/mail/incoming/service.py index 05f9bb5..b4cdfcf 100644 --- a/src/leap/bitmask/mail/incoming/service.py +++ b/src/leap/bitmask/mail/incoming/service.py @@ -29,12 +29,15 @@ from StringIO import StringIO  from urlparse import urlparse  from twisted.application.service import Service +from twisted.application.service import IService  from twisted.logger import Logger  from twisted.python.failure import Failure  from twisted.internet import defer, reactor  from twisted.internet.task import LoopingCall  from twisted.internet.task import deferLater +from zope.interface import implements +  from leap.common.events import emit_async, catalog  from leap.common.check import leap_assert, leap_assert_type  from leap.common.mail import get_email_charset @@ -47,7 +50,7 @@ from leap.soledad.common.crypto import ENC_SCHEME_KEY, ENC_JSON_KEY  from leap.soledad.common.errors import InvalidAuthTokenError -logger = Logger() +logger = Logger(__name__)  MULTIPART_ENCRYPTED = "multipart/encrypted"  MULTIPART_SIGNED = "multipart/signed" @@ -79,7 +82,8 @@ class IncomingMail(Service):      This loop will sync the soledad db with the remote server and      process all the documents found tagged as incoming mail.      """ -    # TODO implements IService? + +    implements(IService)      name = "IncomingMail" @@ -227,7 +231,7 @@ class IncomingMail(Service):          def _signal_invalid_auth(failure):              failure.trap(InvalidAuthTokenError) -            logger.info('sync failed: %r' % failure) +            logger.warn('sync failed because token has expired: %r' % failure)              # if the token is invalid, send an event so the GUI can              # disable mail and show an error message.              emit_async(catalog.SOLEDAD_INVALID_AUTH_TOKEN, self._userid) diff --git a/src/leap/bitmask/mail/smtp/__init__.py b/src/leap/bitmask/mail/smtp/__init__.py index 4e0ac89..f8b8e65 100644 --- a/src/leap/bitmask/mail/smtp/__init__.py +++ b/src/leap/bitmask/mail/smtp/__init__.py @@ -32,7 +32,7 @@ SMTP_PORT = 2013  def run_service(soledad_sessions, keymanager_sessions, sendmail_opts, -                port=SMTP_PORT): +                port=SMTP_PORT, factory=None):      """      Main entry point to run the service from the client. @@ -46,8 +46,9 @@ def run_service(soledad_sessions, keymanager_sessions, sendmail_opts,                the factory for the protocol.      :rtype: tuple      """ -    factory = SMTPFactory(soledad_sessions, keymanager_sessions, -                          sendmail_opts) +    if not factory: +        factory = SMTPFactory(soledad_sessions, keymanager_sessions, +                              sendmail_opts)      try:          interface = "localhost" @@ -60,7 +61,7 @@ def run_service(soledad_sessions, keymanager_sessions, sendmail_opts,          tport = reactor.listenTCP(port, factory, interface=interface)          emit_async(catalog.SMTP_SERVICE_STARTED, str(port)) -        return factory, tport +        return tport, factory      except CannotListenError:          logger.error("SMTP Service failed to start: "                       "cannot listen in port %s" % port) | 
