mirror of
https://github.com/simple-login/app.git
synced 2024-09-20 06:55:59 +08:00
refactor: use headers.py
This commit is contained in:
parent
9bb83fe3e2
commit
5821294ae9
|
@ -3,3 +3,21 @@ MESSAGE_ID = "Message-ID"
|
|||
IN_REPLY_TO = "In-Reply-To"
|
||||
REFERENCES = "References"
|
||||
DATE = "date"
|
||||
SUBJECT = "Subject"
|
||||
FROM = "From"
|
||||
TO = "To"
|
||||
CONTENT_TYPE = "Content-Type"
|
||||
MIME_VERSION = "Mime-Version"
|
||||
REPLY_TO = "Reply-To"
|
||||
RECEIVED = "Received"
|
||||
CC = "Cc"
|
||||
DKIM_SIGNATURE = "DKIM-Signature"
|
||||
X_SPAM_STATUS = "X-Spam-Status"
|
||||
|
||||
# headers used to DKIM sign in order of preference
|
||||
DKIM_HEADERS = [
|
||||
[MESSAGE_ID.encode(), DATE.encode(), SUBJECT.encode(), FROM.encode(), TO.encode()],
|
||||
[FROM.encode(), TO.encode()],
|
||||
[MESSAGE_ID.encode(), DATE.encode()],
|
||||
[FROM.encode()],
|
||||
]
|
||||
|
|
|
@ -54,6 +54,7 @@ from app.config import (
|
|||
ALIAS_AUTOMATIC_DISABLE,
|
||||
)
|
||||
from app.dns_utils import get_mx_domains
|
||||
from app.email import headers
|
||||
from app.extensions import db
|
||||
from app.log import LOG
|
||||
from app.models import (
|
||||
|
@ -275,15 +276,15 @@ def send_email(
|
|||
html = plaintext.replace("\n", "<br>")
|
||||
msg.attach(MIMEText(html, "html"))
|
||||
|
||||
msg["Subject"] = subject
|
||||
msg["From"] = f"{SUPPORT_NAME} <{SUPPORT_EMAIL}>"
|
||||
msg["To"] = to_email
|
||||
msg[headers.SUBJECT] = subject
|
||||
msg[headers.FROM] = f"{SUPPORT_NAME} <{SUPPORT_EMAIL}>"
|
||||
msg[headers.TO] = to_email
|
||||
|
||||
msg_id_header = make_msgid()
|
||||
msg["Message-ID"] = msg_id_header
|
||||
msg[headers.MESSAGE_ID] = msg_id_header
|
||||
|
||||
date_header = formatdate()
|
||||
msg["Date"] = date_header
|
||||
msg[headers.DATE] = date_header
|
||||
|
||||
if unsubscribe_link:
|
||||
add_or_replace_header(msg, "List-Unsubscribe", f"<{unsubscribe_link}>")
|
||||
|
@ -408,17 +409,8 @@ def get_email_domain_part(address):
|
|||
return address[address.find("@") + 1 :]
|
||||
|
||||
|
||||
# headers used to DKIM sign in order of preference
|
||||
_DKIM_HEADERS = [
|
||||
[b"Message-ID", b"Date", b"Subject", b"From", b"To"],
|
||||
[b"From", b"To"],
|
||||
[b"Message-ID", b"Date"],
|
||||
[b"From"],
|
||||
]
|
||||
|
||||
|
||||
def add_dkim_signature(msg: Message, email_domain: str):
|
||||
for dkim_headers in _DKIM_HEADERS:
|
||||
for dkim_headers in headers.DKIM_HEADERS:
|
||||
try:
|
||||
add_dkim_signature_with_header(msg, email_domain, dkim_headers)
|
||||
return
|
||||
|
@ -457,7 +449,7 @@ def add_dkim_signature_with_header(
|
|||
|
||||
# remove linebreaks from sig
|
||||
sig = sig.replace("\n", " ").replace("\r", "")
|
||||
msg["DKIM-Signature"] = sig[len("DKIM-Signature: ") :]
|
||||
msg[headers.DKIM_SIGNATURE] = sig[len("DKIM-Signature: ") :]
|
||||
|
||||
|
||||
def add_or_replace_header(msg: Message, header: str, value: str):
|
||||
|
@ -686,7 +678,7 @@ def get_spam_info(msg: Message, max_score=None) -> (bool, str):
|
|||
DKIM_VALID_AU,RCVD_IN_DNSWL_BLOCKED,RCVD_IN_MSPIKE_H2,SPF_PASS,
|
||||
URIBL_BLOCKED autolearn=unavailable autolearn_force=no version=3.4.2```
|
||||
"""
|
||||
spamassassin_status = msg["X-Spam-Status"]
|
||||
spamassassin_status = msg[headers.X_SPAM_STATUS]
|
||||
if not spamassassin_status:
|
||||
return False, ""
|
||||
|
||||
|
@ -1164,7 +1156,7 @@ def spf_pass(
|
|||
r[0],
|
||||
ip,
|
||||
)
|
||||
subject = get_header_unicode(msg["Subject"])
|
||||
subject = get_header_unicode(msg[headers.SUBJECT])
|
||||
send_email_with_rate_control(
|
||||
user,
|
||||
ALERT_SPF,
|
||||
|
@ -1214,9 +1206,9 @@ def sl_sendmail(
|
|||
if NOT_SEND_EMAIL:
|
||||
LOG.d(
|
||||
"send email with subject '%s', from '%s' to '%s'",
|
||||
msg["Subject"],
|
||||
msg["From"],
|
||||
msg["To"],
|
||||
msg[headers.SUBJECT],
|
||||
msg[headers.FROM],
|
||||
msg[headers.TO],
|
||||
)
|
||||
return
|
||||
|
||||
|
@ -1236,9 +1228,9 @@ def sl_sendmail(
|
|||
"Sendmail mail_from:%s, rcpt_to:%s, header_from:%s, header_to:%s, header_cc:%s",
|
||||
from_addr,
|
||||
to_addr,
|
||||
msg["From"],
|
||||
msg["To"],
|
||||
msg["Cc"],
|
||||
msg[headers.FROM],
|
||||
msg[headers.TO],
|
||||
msg[headers.CC],
|
||||
)
|
||||
smtp.sendmail(
|
||||
from_addr,
|
||||
|
@ -1266,7 +1258,7 @@ def sl_sendmail(
|
|||
|
||||
def get_queue_id(msg: Message) -> Optional[str]:
|
||||
"""Get the Postfix queue-id from a message"""
|
||||
received_header = str(msg["Received"])
|
||||
received_header = str(msg[headers.RECEIVED])
|
||||
if not received_header:
|
||||
return
|
||||
|
||||
|
|
|
@ -445,13 +445,13 @@ def prepare_pgp_message(
|
|||
_MIME_HEADERS,
|
||||
)
|
||||
|
||||
if clone_msg["Content-Type"] is None:
|
||||
if clone_msg[headers.CONTENT_TYPE] is None:
|
||||
LOG.d("Content-Type missing")
|
||||
clone_msg["Content-Type"] = "text/plain"
|
||||
clone_msg[headers.CONTENT_TYPE] = "text/plain"
|
||||
|
||||
if clone_msg["Mime-Version"] is None:
|
||||
if clone_msg[headers.MIME_VERSION] is None:
|
||||
LOG.d("Mime-Version missing")
|
||||
clone_msg["Mime-Version"] = "1.0"
|
||||
clone_msg[headers.MIME_VERSION] = "1.0"
|
||||
|
||||
first = MIMEApplication(
|
||||
_subtype="pgp-encrypted", _encoder=encoders.encode_7or8bit, _data=""
|
||||
|
@ -581,13 +581,13 @@ def handle_forward(envelope, msg: Message, rcpt_to: str) -> List[Tuple[bool, str
|
|||
handle_email_sent_to_ourself(alias, mb, msg, user)
|
||||
return [(True, status.E209)]
|
||||
|
||||
from_header = get_header_unicode(msg["From"])
|
||||
from_header = get_header_unicode(msg[headers.FROM])
|
||||
LOG.d("Create or get contact for from_header:%s", from_header)
|
||||
contact = get_or_create_contact(from_header, envelope.mail_from, alias)
|
||||
|
||||
reply_to_contact = None
|
||||
if msg["Reply-To"]:
|
||||
reply_to = get_header_unicode(msg["Reply-To"])
|
||||
if msg[headers.REPLY_TO]:
|
||||
reply_to = get_header_unicode(msg[headers.REPLY_TO])
|
||||
LOG.d("Create or get contact for from_header:%s", reply_to)
|
||||
# ignore when reply-to = alias
|
||||
if reply_to == alias.email:
|
||||
|
@ -766,7 +766,7 @@ def forward_email_to_mailbox(
|
|||
LOG.d("Encrypt message using mailbox %s", mailbox)
|
||||
if mailbox.generic_subject:
|
||||
LOG.d("Use a generic subject for %s", mailbox)
|
||||
orig_subject = msg["Subject"]
|
||||
orig_subject = msg[headers.SUBJECT]
|
||||
orig_subject = get_header_unicode(orig_subject)
|
||||
add_or_replace_header(msg, "Subject", mailbox.generic_subject)
|
||||
msg = add_header(
|
||||
|
@ -806,13 +806,13 @@ def forward_email_to_mailbox(
|
|||
# change the from header so the sender comes from a reverse-alias
|
||||
# so it can pass DMARC check
|
||||
# replace the email part in from: header
|
||||
contact_from_header = msg["From"]
|
||||
contact_from_header = msg[headers.FROM]
|
||||
new_from_header = contact.new_addr()
|
||||
add_or_replace_header(msg, "From", new_from_header)
|
||||
LOG.d("From header, new:%s, old:%s", new_from_header, contact_from_header)
|
||||
|
||||
if reply_to_contact:
|
||||
reply_to_header = msg["Reply-To"]
|
||||
reply_to_header = msg[headers.REPLY_TO]
|
||||
new_reply_to_header = reply_to_contact.new_addr()
|
||||
add_or_replace_header(msg, "Reply-To", new_reply_to_header)
|
||||
LOG.d("Reply-To header, new:%s, old:%s", new_reply_to_header, reply_to_header)
|
||||
|
@ -1048,11 +1048,11 @@ def handle_reply(envelope, msg: Message, rcpt_to: str) -> (bool, str):
|
|||
LOG.d("make message id %s", message_id)
|
||||
add_or_replace_header(
|
||||
msg,
|
||||
"Message-ID",
|
||||
headers.MESSAGE_ID,
|
||||
message_id,
|
||||
)
|
||||
date_header = formatdate()
|
||||
msg["Date"] = date_header
|
||||
msg[headers.DATE] = date_header
|
||||
|
||||
msg[_DIRECTION] = "Reply"
|
||||
msg[_EMAIL_LOG_ID_HEADER] = str(email_log.id)
|
||||
|
@ -1133,7 +1133,7 @@ def handle_unknown_mailbox(
|
|||
"Reply email can only be used by mailbox. "
|
||||
"Actual mail_from: %s. msg from header: %s, reverse-alias %s, %s %s %s",
|
||||
envelope.mail_from,
|
||||
msg["From"],
|
||||
msg[headers.FROM],
|
||||
reply_email,
|
||||
alias,
|
||||
user,
|
||||
|
@ -1315,7 +1315,7 @@ def handle_hotmail_complaint(msg: Message) -> bool:
|
|||
Return True if the complaint can be handled, False otherwise
|
||||
"""
|
||||
orig_msg = get_orig_message_from_hotmail_complaint(msg)
|
||||
to_header = orig_msg["To"]
|
||||
to_header = orig_msg[headers.TO]
|
||||
if not to_header:
|
||||
LOG.e("cannot find the alias")
|
||||
return False
|
||||
|
@ -1355,7 +1355,7 @@ def handle_yahoo_complaint(msg: Message) -> bool:
|
|||
Return True if the complaint can be handled, False otherwise
|
||||
"""
|
||||
orig_msg = get_orig_message_from_yahoo_complaint(msg)
|
||||
to_header = orig_msg["To"]
|
||||
to_header = orig_msg[headers.TO]
|
||||
if not to_header:
|
||||
LOG.e("cannot find the alias")
|
||||
return False
|
||||
|
@ -1559,7 +1559,7 @@ def handle_spam(
|
|||
def handle_unsubscribe(envelope: Envelope, msg: Message) -> str:
|
||||
"""return the SMTP status"""
|
||||
# format: alias_id:
|
||||
subject = msg["Subject"]
|
||||
subject = msg[headers.SUBJECT]
|
||||
try:
|
||||
# subject has the format {alias.id}=
|
||||
if subject.endswith("="):
|
||||
|
@ -1574,7 +1574,7 @@ def handle_unsubscribe(envelope: Envelope, msg: Message) -> str:
|
|||
|
||||
alias = Alias.get(alias_id)
|
||||
except Exception:
|
||||
LOG.w("Cannot parse alias from subject %s", msg["Subject"])
|
||||
LOG.w("Cannot parse alias from subject %s", msg[headers.SUBJECT])
|
||||
return status.E507
|
||||
|
||||
if not alias:
|
||||
|
@ -1746,7 +1746,7 @@ def handle(envelope: Envelope) -> str:
|
|||
if postfix_queue_id:
|
||||
set_message_id(postfix_queue_id)
|
||||
else:
|
||||
LOG.d("Cannot parse Postfix queue ID from %s", msg["Received"])
|
||||
LOG.d("Cannot parse Postfix queue ID from %s", msg[headers.RECEIVED])
|
||||
|
||||
if should_ignore(mail_from, rcpt_tos):
|
||||
LOG.w("Ignore email mail_from=%s rcpt_to=%s", mail_from, rcpt_tos)
|
||||
|
@ -1763,10 +1763,10 @@ def handle(envelope: Envelope) -> str:
|
|||
"cc:%s, reply-to:%s, mail_options:%s, rcpt_options:%s",
|
||||
mail_from,
|
||||
rcpt_tos,
|
||||
msg["From"],
|
||||
msg["To"],
|
||||
msg["Cc"],
|
||||
msg["Reply-To"],
|
||||
msg[headers.FROM],
|
||||
msg[headers.TO],
|
||||
msg[headers.CC],
|
||||
msg[headers.REPLY_TO],
|
||||
envelope.mail_options,
|
||||
envelope.rcpt_options,
|
||||
)
|
||||
|
@ -1854,7 +1854,7 @@ def handle(envelope: Envelope) -> str:
|
|||
return handle_bounce(envelope, email_log, msg)
|
||||
|
||||
# case where From: header is a reverse alias which should never happen
|
||||
from_header = get_header_unicode(msg["From"])
|
||||
from_header = get_header_unicode(msg[headers.FROM])
|
||||
if from_header:
|
||||
try:
|
||||
_, from_header_address = parse_full_address(from_header)
|
||||
|
@ -1926,14 +1926,16 @@ def handle(envelope: Envelope) -> str:
|
|||
# Reply case
|
||||
# recipient starts with "reply+" or "ra+" (ra=reverse-alias) prefix
|
||||
if is_reply_email(rcpt_to):
|
||||
LOG.d("Reply phase %s(%s) -> %s", mail_from, copy_msg["From"], rcpt_to)
|
||||
LOG.d(
|
||||
"Reply phase %s(%s) -> %s", mail_from, copy_msg[headers.FROM], rcpt_to
|
||||
)
|
||||
is_delivered, smtp_status = handle_reply(envelope, copy_msg, rcpt_to)
|
||||
res.append((is_delivered, smtp_status))
|
||||
else: # Forward case
|
||||
LOG.d(
|
||||
"Forward phase %s(%s) -> %s",
|
||||
mail_from,
|
||||
copy_msg["From"],
|
||||
copy_msg[headers.FROM],
|
||||
rcpt_to,
|
||||
)
|
||||
for is_delivered, smtp_status in handle_forward(
|
||||
|
|
Loading…
Reference in a new issue