Пример #1
0
    def _test_login_and_proto(self, email, settings):
        event = Event(data={})

        if settings['protocol'].startswith('smtp'):
            try:
                assert(SendMail(self.session, None,
                                [(email,
                                  [email, '*****@*****.**'], None,
                                  [event])],
                                test_only=True, test_route=settings))
                return True, True
            except (IOError, OSError, AssertionError, SendMailError):
                pass

        if settings['protocol'].startswith('imap'):
            from mailpile.mail_source.imap import TestImapSettings
            if TestImapSettings(self.session, settings, event):
                return True, True

        if settings['protocol'].startswith('pop3'):
            from mailpile.mail_source.pop3 import TestPop3Settings
            if TestPop3Settings(self.session, settings, event):
                return True, True

        if ('connection' in event.data and
                event.data['connection']['error'][0] == 'auth'):
            return False, True

        if ('last_error' in event.data and event.data.get('auth')):
            return False, True

        return False, False
Пример #2
0
    def command(self, emails=None):
        session, config, idx = self.session, self.session.config, self._idx()
        args = list(self.args)

        bounce_to = []
        while args and '@' in args[-1]:
            bounce_to.append(args.pop(-1))
        for rcpt in (self.data.get('to', []) +
                     self.data.get('cc', []) +
                     self.data.get('bcc', [])):
            bounce_to.extend(ExtractEmails(rcpt))

        if not emails:
            args.extend(['=%s' % mid for mid in self.data.get('mid', [])])
            mids = self._choose_messages(args)
            emails = [Email(idx, i) for i in mids]

        # Process one at a time so we don't eat too much memory
        sent = []
        missing_keys = []
        for email in emails:
            try:
                msg_mid = email.get_msg_info(idx.MSG_MID)
                # FIXME: We are failing to capture error states with sufficient
                #        granularity, messages may be delivered to some
                #        recipients but not all...
                SendMail(session, [PrepareMessage(config,
                                                  email.get_msg(pgpmime=False),
                                                  rcpts=(bounce_to or None))])
                sent.append(email)
            except KeyLookupError, kle:
                session.ui.warning(_('Missing keys %s') % kle.missing)
                missing_keys.extend(kle.missing)
                self._ignore_exception()
            except:
Пример #3
0
    def setup_command(self, session):

        if self.args:
            route_id = self.args[0]
        elif 'route_id' in self.data:
            route_id = self.data['route_id'][0]
        else:
            route_id = None

        if route_id:
            route = self.session.config.routes[route_id]
            assert(route)
        else:
            route = {}
            for k in CONFIG_RULES['routes'][1]:
                if k not in self.data:
                    pass
                elif CONFIG_RULES['routes'][1][k][1] in (int, 'int'):
                    route[k] = int(self.data[k][0])
                else:
                    route[k] = self.data[k][0]

        fromaddr = route.get('username', '')
        if '@' not in fromaddr:
            fromaddr = self.session.config.get_profile()['email']
        if not fromaddr or '@' not in fromaddr:
            fromaddr = '%s@%s' % (route.get('username', 'test'),
                                  route.get('host', 'example.com'))
        assert(fromaddr)

        error_info = {'error': _('Unknown error')}
        try:
            assert(SendMail(self.session, None,
                            [(fromaddr,
                              [fromaddr, '*****@*****.**'],
                              None,
                              [self.event])],
                            test_only=True, test_route=route))
            return self._success(_('Route is working'),
                                 result=route)
        except OSError:
            error_info = {'error': _('Invalid command'),
                          'invalid_command': True}
        except SendMailError, e:
            error_info = {'error': e.message,
                          'sendmail_error': True}
            error_info.update(e.error_info)
Пример #4
0
    def command(self, emails=None):
        session, config, idx = self.session, self.session.config, self._idx()
        args = list(self.args)

        if self.session.config.sys.lockdown:
            return self._error(_('In lockdown, doing nothing.'))

        bounce_to = []
        while args and '@' in args[-1]:
            bounce_to.append(args.pop(-1))
        for rcpt in (self.data.get('to', []) + self.data.get('cc', []) +
                     self.data.get('bcc', [])):
            bounce_to.extend(ExtractEmails(rcpt))

        if not emails:
            args.extend(['=%s' % mid for mid in self.data.get('mid', [])])
            mids = self._choose_messages(args)
            emails = [Email(idx, i) for i in mids]

        # Process one at a time so we don't eat too much memory
        sent = []
        missing_keys = []
        for email in emails:
            events = []
            try:
                msg_mid = email.get_msg_info(idx.MSG_MID)

                # This is a unique sending-ID. This goes in the public (meant
                # for debugging help) section of the event-log, so we take
                # care to not reveal details about the message or recipients.
                msg_sid = sha1b64(email.get_msg_info(idx.MSG_ID),
                                  *sorted(bounce_to))[:8]

                # We load up any incomplete events for sending this message
                # to this set of recipients. If nothing is in flight, create
                # a new event for tracking this operation.
                events = list(
                    config.event_log.incomplete(source=self.EVENT_SOURCE,
                                                data_mid=msg_mid,
                                                data_sid=msg_sid))
                if not events:
                    events.append(
                        config.event_log.log(source=self.EVENT_SOURCE,
                                             flags=Event.RUNNING,
                                             message=_('Sending message'),
                                             data={
                                                 'mid': msg_mid,
                                                 'sid': msg_sid
                                             }))

                SendMail(session, msg_mid, [
                    PrepareMessage(config,
                                   email.get_msg(pgpmime=False),
                                   rcpts=(bounce_to or None),
                                   events=events)
                ])
                for ev in events:
                    ev.flags = Event.COMPLETE
                    config.event_log.log_event(ev)
                sent.append(email)
            except KeyLookupError, kle:
                # This is fatal, we don't retry
                message = _('Missing keys %s') % kle.missing
                for ev in events:
                    ev.flags = Event.COMPLETE
                    ev.message = message
                    config.event_log.log_event(ev)
                session.ui.warning(message)
                missing_keys.extend(kle.missing)
                self._ignore_exception()
            # FIXME: Also fatal, when the SMTP server REJECTS the mail
            except:
Пример #5
0
    def command(self, emails=None):
        session, config, idx = self.session, self.session.config, self._idx()
        args = list(self.args)

        bounce_to = []
        while args and '@' in args[-1]:
            bounce_to.append(args.pop(-1))
        for rcpt in (self.data.get('to', []) + self.data.get('cc', []) +
                     self.data.get('bcc', [])):
            bounce_to.extend(ExtractEmails(rcpt))

        sender = self.data.get('from', [None])[0]
        if not sender and bounce_to:
            sender = idx.config.get_profile().get('email', None)

        if not emails:
            args.extend(['=%s' % mid for mid in self.data.get('mid', [])])
            emails = [
                self._actualize_ephemeral(i)
                for i in self._choose_messages(args, allow_ephemeral=True)
            ]

        # First make sure the draft tags are all gone, so other edits either
        # fail or complete while we wait for the lock.
        with GLOBAL_EDITING_LOCK:
            self._tag_drafts(emails, untag=True)
            self._tag_blank(emails, untag=True)

        # Process one at a time so we don't eat too much memory
        sent = []
        missing_keys = []
        locked_keys = []
        for email in emails:
            events = []
            try:
                msg_mid = email.get_msg_info(idx.MSG_MID)

                # This is a unique sending-ID. This goes in the public (meant
                # for debugging help) section of the event-log, so we take
                # care to not reveal details about the message or recipients.
                msg_sid = sha1b64(email.get_msg_info(idx.MSG_ID),
                                  *sorted(bounce_to))[:8]

                # We load up any incomplete events for sending this message
                # to this set of recipients. If nothing is in flight, create
                # a new event for tracking this operation.
                events = list(
                    config.event_log.incomplete(source=self.EVENT_SOURCE,
                                                data_mid=msg_mid,
                                                data_sid=msg_sid))
                if not events:
                    events.append(
                        config.event_log.log(source=self.EVENT_SOURCE,
                                             flags=Event.RUNNING,
                                             message=_('Sending message'),
                                             data={
                                                 'mid': msg_mid,
                                                 'sid': msg_sid
                                             }))

                SendMail(session, msg_mid, [
                    PrepareMessage(config,
                                   email.get_msg(pgpmime=False),
                                   sender=sender,
                                   rcpts=(bounce_to or None),
                                   bounce=(True if bounce_to else False),
                                   events=events)
                ])
                for ev in events:
                    ev.flags = Event.COMPLETE
                    config.event_log.log_event(ev)
                sent.append(email)

            # Encryption related failures are fatal, don't retry
            except (KeyLookupError, EncryptionFailureError,
                    SignatureFailureError), exc:
                message = unicode(exc)
                session.ui.warning(message)
                if hasattr(exc, 'missing_keys'):
                    missing_keys.extend(exc.missing)
                if hasattr(exc, 'from_key'):
                    # FIXME: We assume signature failures happen because
                    # the key is locked. Are there any other reasons?
                    locked_keys.append(exc.from_key)
                for ev in events:
                    ev.flags = Event.COMPLETE
                    ev.message = message
                    config.event_log.log_event(ev)
                self._ignore_exception()

            # FIXME: Also fatal, when the SMTP server REJECTS the mail
            except: