Support alias having multiple mailboxes in forward phase

This commit is contained in:
Son NK 2020-05-10 16:57:47 +02:00
parent 7f6ba313fd
commit 4b479defa8
2 changed files with 40 additions and 6 deletions

View File

@ -643,6 +643,14 @@ class Alias(db.Model, ModelMixin):
user = db.relationship(User) user = db.relationship(User)
mailbox = db.relationship("Mailbox") mailbox = db.relationship("Mailbox")
@property
def mailboxes(self):
ret = [self.mailbox]
for m in self._mailboxes:
ret.append(m)
return ret
@classmethod @classmethod
def create(cls, **kw): def create(cls, **kw):
r = cls(**kw) r = cls(**kw)

View File

@ -40,6 +40,7 @@ from email.mime.multipart import MIMEMultipart
from email.utils import parseaddr, formataddr from email.utils import parseaddr, formataddr
from io import BytesIO from io import BytesIO
from smtplib import SMTP from smtplib import SMTP
from typing import List, Tuple
import arrow import arrow
import spf import spf
@ -310,7 +311,9 @@ def prepare_pgp_message(orig_msg: Message, pgp_fingerprint: str):
return msg return msg
def handle_forward(envelope, smtp: SMTP, msg: Message, rcpt_to: str) -> (bool, str): def handle_forward(
envelope, smtp: SMTP, msg: Message, rcpt_to: str
) -> List[Tuple[bool, str]]:
"""return whether an email has been delivered and """return whether an email has been delivered and
the smtp status ("250 Message accepted", "550 Non-existent email address", etc) the smtp status ("250 Message accepted", "550 Non-existent email address", etc)
""" """
@ -322,7 +325,7 @@ def handle_forward(envelope, smtp: SMTP, msg: Message, rcpt_to: str) -> (bool, s
alias = try_auto_create(address) alias = try_auto_create(address)
if not alias: if not alias:
LOG.d("alias %s cannot be created on-the-fly, return 550", address) LOG.d("alias %s cannot be created on-the-fly, return 550", address)
return False, "550 SL E3" return [(False, "550 SL E3")]
contact = get_or_create_contact(msg["From"], alias) contact = get_or_create_contact(msg["From"], alias)
email_log = EmailLog.create(contact_id=contact.id, user_id=contact.user_id) email_log = EmailLog.create(contact_id=contact.id, user_id=contact.user_id)
@ -333,11 +336,32 @@ def handle_forward(envelope, smtp: SMTP, msg: Message, rcpt_to: str) -> (bool, s
db.session.commit() db.session.commit()
# do not return 5** to allow user to receive emails later when alias is enabled # do not return 5** to allow user to receive emails later when alias is enabled
return True, "250 Message accepted for delivery" return [(True, "250 Message accepted for delivery")]
mailbox = alias.mailbox
user = alias.user user = alias.user
ret = []
for mailbox in alias.mailboxes:
ret.append(
forward_email_to_mailbox(
alias, msg, email_log, contact, envelope, smtp, mailbox, user
)
)
return ret
def forward_email_to_mailbox(
alias,
msg: Message,
email_log: EmailLog,
contact: Contact,
envelope,
smtp: SMTP,
mailbox,
user,
) -> (bool, str):
LOG.d("Forward %s -> %s -> %s", contact, alias, mailbox)
spam_check = True spam_check = True
# create PGP email if needed # create PGP email if needed
@ -927,7 +951,9 @@ def handle(envelope: Envelope, smtp: SMTP) -> str:
res.append((is_delivered, smtp_status)) res.append((is_delivered, smtp_status))
else: # Forward case else: # Forward case
LOG.debug(">>> Forward phase %s -> %s", envelope.mail_from, rcpt_to) LOG.debug(">>> Forward phase %s -> %s", envelope.mail_from, rcpt_to)
is_delivered, smtp_status = handle_forward(envelope, smtp, msg, rcpt_to) for is_delivered, smtp_status in handle_forward(
envelope, smtp, msg, rcpt_to
):
res.append((is_delivered, smtp_status)) res.append((is_delivered, smtp_status))
for (is_success, smtp_status) in res: for (is_success, smtp_status) in res: