From be7ae3021a2ed9ccd825fd3d8d0f07f8a3c2e203 Mon Sep 17 00:00:00 2001 From: Son Date: Tue, 19 Oct 2021 12:14:16 +0200 Subject: [PATCH] rename is_reply_email -> is_reverse_alias, make sure reverse-alias must end with EMAIL_DOMAIN --- app/email/rate_limit.py | 4 ++-- app/email_utils.py | 4 ++-- email_handler.py | 8 ++++---- tests/api/test_alias.py | 13 ++++++++----- 4 files changed, 16 insertions(+), 13 deletions(-) diff --git a/app/email/rate_limit.py b/app/email/rate_limit.py index 918db145..d5b5bb8a 100644 --- a/app/email/rate_limit.py +++ b/app/email/rate_limit.py @@ -6,7 +6,7 @@ from app.config import ( MAX_ACTIVITY_DURING_MINUTE_PER_MAILBOX, ) from app.db import Session -from app.email_utils import is_reply_email +from app.email_utils import is_reverse_alias from app.log import LOG from app.models import Alias, EmailLog, Contact @@ -97,7 +97,7 @@ def rate_limited(mail_from: str, rcpt_tos: [str]) -> bool: return False for rcpt_to in rcpt_tos: - if is_reply_email(rcpt_to): + if is_reverse_alias(rcpt_to): if rate_limited_reply_phase(rcpt_to): return True else: diff --git a/app/email_utils.py b/app/email_utils.py index 5cf5ee20..8d929afe 100644 --- a/app/email_utils.py +++ b/app/email_utils.py @@ -1032,8 +1032,8 @@ def generate_reply_email(contact_email: str, user: User) -> str: raise Exception("Cannot generate reply email") -def is_reply_email(address: str) -> bool: - return address.startswith("reply+") or address.startswith("ra+") +def is_reverse_alias(address: str) -> bool: + return address.endswith(f"@{EMAIL_DOMAIN}") and (address.startswith("reply+") or address.startswith("ra+")) # allow also + and @ that are present in a reply address diff --git a/email_handler.py b/email_handler.py index a61eb81e..5d3245e0 100644 --- a/email_handler.py +++ b/email_handler.py @@ -109,7 +109,7 @@ from app.email_utils import ( add_header, get_header_unicode, generate_reply_email, - is_reply_email, + is_reverse_alias, normalize_reply_email, is_valid_email, replace, @@ -1937,7 +1937,7 @@ def handle(envelope: Envelope) -> str: except ValueError: LOG.d("cannot parse the From header %s", from_header) else: - if is_reply_email(from_header_address): + if is_reverse_alias(from_header_address): LOG.e("email sent from a reverse alias %s", from_header_address) # get more info for debug contact = Contact.get_by(reply_email=from_header_address) @@ -1975,7 +1975,7 @@ def handle(envelope: Envelope) -> str: # Handle "out of office" auto notice. An automatic response is sent for every forwarded email # todo: remove logging - if len(rcpt_tos) == 1 and is_reply_email(rcpt_tos[0]) and mail_from == "<>": + if len(rcpt_tos) == 1 and is_reverse_alias(rcpt_tos[0]) and mail_from == "<>": LOG.w( "out-of-office email to reverse alias %s. %s", rcpt_tos[0], msg.as_string() ) @@ -2001,7 +2001,7 @@ def handle(envelope: Envelope) -> str: # Reply case # recipient starts with "reply+" or "ra+" (ra=reverse-alias) prefix - if is_reply_email(rcpt_to): + if is_reverse_alias(rcpt_to): LOG.d( "Reply phase %s(%s) -> %s", mail_from, copy_msg[headers.FROM], rcpt_to ) diff --git a/tests/api/test_alias.py b/tests/api/test_alias.py index a64022ec..827ca3e1 100644 --- a/tests/api/test_alias.py +++ b/tests/api/test_alias.py @@ -2,7 +2,7 @@ from flask import url_for from app.config import PAGE_LIMIT from app.db import Session -from app.email_utils import is_reply_email +from app.email_utils import is_reverse_alias from app.models import User, ApiKey, Alias, Contact, EmailLog, Mailbox from tests.utils import login @@ -649,7 +649,10 @@ def test_get_alias(flask_client): assert "pinned" in res -def test_is_reply_email(flask_client): - assert is_reply_email("ra+abcd@test.org") - assert is_reply_email("reply+abcd@test.org") - assert not is_reply_email("abcd@test.org") +def test_is_reverse_alias(flask_client): + assert is_reverse_alias("ra+abcd@sl.local") + assert is_reverse_alias("reply+abcd@sl.local") + + assert not is_reverse_alias("ra+abcd@test.org") + assert not is_reverse_alias("reply+abcd@test.org") + assert not is_reverse_alias("abcd@test.org")