diff options
Diffstat (limited to 'mail/src')
| -rw-r--r-- | mail/src/leap/mail/imap/fetch.py | 70 | ||||
| -rw-r--r-- | mail/src/leap/mail/imap/service/imap-server.tac | 79 | 
2 files changed, 30 insertions, 119 deletions
| diff --git a/mail/src/leap/mail/imap/fetch.py b/mail/src/leap/mail/imap/fetch.py index bcd8901..60ae387 100644 --- a/mail/src/leap/mail/imap/fetch.py +++ b/mail/src/leap/mail/imap/fetch.py @@ -1,12 +1,8 @@  import json -import os -#import hmac - -from xdg import BaseDirectory  from twisted.python import log -from leap.common.check import leap_assert +from leap.common.check import leap_assert, leap_assert_type  from leap.soledad import Soledad  from leap.common.keymanager import openpgp @@ -16,61 +12,30 @@ class LeapIncomingMail(object):      """      Fetches mail from the incoming queue.      """ -    def __init__(self, keymanager, user_uuid, soledad_pass, server_url, -                 server_pemfile, token, imap_account, -                 **kwargs): +    def __init__(self, keymanager, soledad, imap_account): +          """          Initialize LeapIMAP. -        :param user: The user adress in the form C{user@provider}. -        :type user: str - -        :param soledad_pass: The password for the local database replica. -        :type soledad_pass: str - -        :param server_url: The URL of the remote server to sync against. -        :type couch_url: str - -        :param server_pemfile: The pemfile for the remote sync server TLS -                               handshake. -        :type server_pemfile: str - -        :param token: a session token valid for this user. -        :type token: str +        :param keymanager: a keymanager instance +        :type keymanager: keymanager.KeyManager -        :param imap_account: a SoledadBackedAccount instance to which -                             the incoming mail will be saved to +        :param soledad: a soledad instance +        :type soledad: Soledad -        :param **kwargs: Used to pass arguments to Soledad instance. Maybe -            Soledad instantiation could be factored out from here, and maybe -            we should have a standard for all client code. +        :param imap_account: the account to fetch periodically +        :type imap_account: SoledadBackedAccount          """ -        leap_assert(user_uuid, "need an user uuid to initialize") -        self._keymanager = keymanager -        self._user_uuid = user_uuid -        self._server_url = server_url -        self._soledad_pass = soledad_pass - -        base_config = BaseDirectory.xdg_config_home -        secret_path = os.path.join( -            base_config, "leap", "soledad", "%s.secret" % user_uuid) -        soledad_path = os.path.join( -            base_config, "leap", "soledad", "%s-incoming.u1db" % user_uuid) +        leap_assert(keymanager, "need a keymanager to initialize") +        leap_assert_type(soledad, Soledad) +        self._keymanager = keymanager +        self._soledad = soledad          self.imapAccount = imap_account -        self._soledad = Soledad( -            user_uuid, -            soledad_pass, -            secret_path, -            soledad_path, -            server_url, -            server_pemfile, -            token)          self._pkey = self._keymanager.get_all_keys_in_local_db(              private=True).pop() -        log.msg('fetcher got soledad instance')      def fetch(self):          """ @@ -78,16 +43,12 @@ class LeapIncomingMail(object):          user account, and remove from the incoming db.          """          self._soledad.sync() - -        #log.msg('getting all docs')          gen, doclist = self._soledad.get_all_docs()          #log.msg("there are %s docs" % (len(doclist),))          if doclist:              inbox = self.imapAccount.getMailbox('inbox') -        #import ipdb; ipdb.set_trace() -          key = self._pkey          for doc in doclist:              keys = doc.content.keys() @@ -99,10 +60,11 @@ class LeapIncomingMail(object):                  encdata = doc.content['_enc_json']                  decrdata = openpgp.decrypt_asym(                      encdata, key, -                    passphrase=self._soledad_pass) +                    # XXX get from public method instead +                    passphrase=self._soledad._passphrase)                  if decrdata:                      self.process_decrypted(doc, decrdata, inbox) -        # XXX launch sync callback +        # XXX launch sync callback / defer      def process_decrypted(self, doc, data, inbox):          """ diff --git a/mail/src/leap/mail/imap/service/imap-server.tac b/mail/src/leap/mail/imap/service/imap-server.tac index 362b536..1a4661b 100644 --- a/mail/src/leap/mail/imap/service/imap-server.tac +++ b/mail/src/leap/mail/imap/service/imap-server.tac @@ -1,7 +1,5 @@  import ConfigParser -import datetime  import os -from functools import partial  from xdg import BaseDirectory @@ -10,20 +8,21 @@ from twisted.internet.protocol import ServerFactory  from twisted.mail import imap4  from twisted.python import log -from leap.common.check import leap_assert +from leap.common.check import leap_assert, leap_assert_type  from leap.mail.imap.server import SoledadBackedAccount  from leap.mail.imap.fetch import LeapIncomingMail  from leap.soledad import Soledad -#from leap.soledad import SoledadCrypto  # Some constants +# XXX Should be passed to initializer too. +  # ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -# The port in which imap service will run  IMAP_PORT = 9930 +# The port in which imap service will run +INCOMING_CHECK_PERIOD = 10  # The period between succesive checks of the incoming mail  # queue (in seconds) -INCOMING_CHECK_PERIOD = 10  # ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ @@ -35,8 +34,8 @@ class LeapIMAPServer(imap4.IMAP4Server):          # pop extraneous arguments          soledad = kwargs.pop('soledad', None)          user = kwargs.pop('user', None) -        gpg = kwargs.pop('gpg', None)          leap_assert(soledad, "need a soledad instance") +        leap_assert_type(soledad, Soledad)          leap_assert(user, "need a user in the initialization")          # initialize imap server! @@ -67,7 +66,7 @@ class LeapIMAPServer(imap4.IMAP4Server):  class IMAPAuthRealm(object):      """ -    dummy authentication realm +    Dummy authentication realm. Do not use in production!      """      theAccount = None @@ -81,42 +80,25 @@ class LeapIMAPFactory(ServerFactory):      capabilities.      """ -    def __init__(self, user, soledad, gpg=None): +    def __init__(self, user, soledad):          self._user = user          self._soledad = soledad -        self._gpg = gpg          theAccount = SoledadBackedAccount(              user, soledad=soledad) - -        # --------------------------------- -        # XXX pre-populate acct for tests!! -        # populate_test_account(theAccount) -        # ---------------------------------          self.theAccount = theAccount      def buildProtocol(self, addr):          "Return a protocol suitable for the job."          imapProtocol = LeapIMAPServer(              user=self._user, -            soledad=self._soledad, -            gpg=self._gpg) +            soledad=self._soledad)          imapProtocol.theAccount = self.theAccount          imapProtocol.factory = self          return imapProtocol -# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -# -# Let's rock... -# -# XXX initialize gpg - -#from leap.mail.imap.tests import PUBLIC_KEY -#from leap.mail.imap.tests import PRIVATE_KEY -#from leap.soledad.util import GPGWrapper - -def initialize_mailbox_soledad(user_uuid, soledad_pass, server_url, +def initialize_soledad_mailbox(user_uuid, soledad_pass, server_url,                                 server_pemfile, token):      """      Initializes soledad by hand @@ -129,7 +111,6 @@ def initialize_mailbox_soledad(user_uuid, soledad_pass, server_url,      :rtype: Soledad instance      """ -    #XXX do we need a separate instance for the mailbox db?      base_config = BaseDirectory.xdg_config_home      secret_path = os.path.join( @@ -145,33 +126,9 @@ def initialize_mailbox_soledad(user_uuid, soledad_pass, server_url,          server_url,          server_pemfile,          token) -    #_soledad._init_dirs() -    #_soledad._crypto = SoledadCrypto(_soledad) -    #_soledad._shared_db = None -    #_soledad._init_keys() -    #_soledad._init_db()      return _soledad -''' -mail_sample = open('rfc822.message').read() -def populate_test_account(acct): -    """ -    Populates inbox for testing purposes -    """ -    print "populating test account!" -    inbox = acct.getMailbox('inbox') -    inbox.addMessage(mail_sample, ("\\Foo", "\\Recent",), date="Right now2") -''' - - -def incoming_check(fetcher): -    """ -    Check incoming queue. To be called periodically. -    """ -    #log.msg("checking incoming queue...") -    fetcher.fetch() -  #######################################################################  # XXX STUBBED! We need to get this in the instantiation from the client @@ -188,13 +145,12 @@ d = {}  for key in ('uid', 'passphrase', 'server', 'pemfile', 'token'):      d[key] = config.get('mail', key) -soledad = initialize_mailbox_soledad( +soledad = initialize_soledad_mailbox(      d['uid'],      d['passphrase'],      d['server'],      d['pemfile'],      d['token']) -gpg = None  # import the private key ---- should sync it from remote!  from leap.common.keymanager.openpgp import OpenPGPScheme @@ -204,10 +160,8 @@ opgp.put_ascii_key(privkey)  from leap.common.keymanager import KeyManager  keym = KeyManager(userID, nickserver_url, soledad, d['token']) -#import ipdb; ipdb.set_trace() - -factory = LeapIMAPFactory(userID, soledad, gpg) +factory = LeapIMAPFactory(userID, soledad)  application = service.Application("LEAP IMAP4 Local Service")  imapService = internet.TCPServer(IMAP_PORT, factory) @@ -215,15 +169,10 @@ imapService.setServiceParent(application)  fetcher = LeapIncomingMail(      keym, -    d['uid'], -    d['passphrase'], -    d['server'], -    d['pemfile'], -    d['token'], +    soledad,      factory.theAccount) -incoming_check_for_acct = partial(incoming_check, fetcher)  internet.TimerService(      INCOMING_CHECK_PERIOD, -    incoming_check_for_acct).setServiceParent(application) +    fetcher.fetch).setServiceParent(application) | 
