refactor email-handler: move handle_forward, handle_reply to outside of MailHandler class

This commit is contained in:
Son NK 2020-02-19 22:17:13 +07:00
parent fc09f911a4
commit e4e1429aae
1 changed files with 254 additions and 256 deletions

View File

@ -176,42 +176,13 @@ def try_auto_create(alias: str) -> Optional[GenEmail]:
return gen_email
class MailHandler:
async def handle_DATA(self, server, session, envelope):
LOG.debug(">>> New message <<<")
LOG.debug("Mail from %s", envelope.mail_from)
LOG.debug("Rcpt to %s", envelope.rcpt_tos)
message_data = envelope.content.decode("utf8", errors="replace")
smtp = SMTP(POSTFIX_SERVER, 25)
msg = Parser(policy=SMTPUTF8).parsestr(message_data)
for rcpt_to in envelope.rcpt_tos:
# Reply case
# recipient starts with "reply+" or "ra+" (ra=reverse-alias) prefix
if rcpt_to.startswith("reply+") or rcpt_to.startswith("ra+"):
LOG.debug("Reply phase")
app = new_app()
with app.app_context():
return self.handle_reply(envelope, smtp, msg, rcpt_to)
else: # Forward case
LOG.debug("Forward phase")
app = new_app()
with app.app_context():
return self.handle_forward(envelope, smtp, msg, rcpt_to)
def handle_forward(self, envelope, smtp: SMTP, msg: Message, rcpt_to: str) -> str:
def handle_forward(envelope, smtp: SMTP, msg: Message, rcpt_to: str) -> str:
"""return *status_code message*"""
alias = rcpt_to.lower() # alias@SL
gen_email = GenEmail.get_by(email=alias)
if not gen_email:
LOG.d(
"alias %s not exist. Try to see if it can be created on the fly", alias
)
LOG.d("alias %s not exist. Try to see if it can be created on the fly", alias)
gen_email = try_auto_create(alias)
if not gen_email:
LOG.d("alias %s cannot be created on-the-fly, return 510", alias)
@ -310,7 +281,8 @@ class MailHandler:
db.session.commit()
return "250 Message accepted for delivery"
def handle_reply(self, envelope, smtp: SMTP, msg: Message, rcpt_to: str) -> str:
def handle_reply(envelope, smtp: SMTP, msg: Message, rcpt_to: str) -> str:
reply_email = rcpt_to.lower()
# reply_email must end with EMAIL_DOMAIN
@ -420,9 +392,7 @@ class MailHandler:
# add List-Unsubscribe header
unsubscribe_link = f"{URL}/dashboard/unsubscribe/{forward_email.gen_email_id}"
add_or_replace_header(msg, "List-Unsubscribe", f"<{unsubscribe_link}>")
add_or_replace_header(
msg, "List-Unsubscribe-Post", "List-Unsubscribe=One-Click"
)
add_or_replace_header(msg, "List-Unsubscribe-Post", "List-Unsubscribe=One-Click")
# Received-SPF is injected by postfix-policyd-spf-python can reveal user original email
delete_header(msg, "Received-SPF")
@ -458,6 +428,34 @@ class MailHandler:
return "250 Message accepted for delivery"
class MailHandler:
async def handle_DATA(self, server, session, envelope):
LOG.debug(">>> New message <<<")
LOG.debug("Mail from %s", envelope.mail_from)
LOG.debug("Rcpt to %s", envelope.rcpt_tos)
message_data = envelope.content.decode("utf8", errors="replace")
smtp = SMTP(POSTFIX_SERVER, 25)
msg = Parser(policy=SMTPUTF8).parsestr(message_data)
for rcpt_to in envelope.rcpt_tos:
# Reply case
# recipient starts with "reply+" or "ra+" (ra=reverse-alias) prefix
if rcpt_to.startswith("reply+") or rcpt_to.startswith("ra+"):
LOG.debug("Reply phase")
app = new_app()
with app.app_context():
return handle_reply(envelope, smtp, msg, rcpt_to)
else: # Forward case
LOG.debug("Forward phase")
app = new_app()
with app.app_context():
return handle_forward(envelope, smtp, msg, rcpt_to)
if __name__ == "__main__":
controller = Controller(MailHandler(), hostname="0.0.0.0", port=20381)