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
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:
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)
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:
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: