From 0039b4c3017adc3f26d9cdeb1da656338c0a3836 Mon Sep 17 00:00:00 2001 From: Son NK <> Date: Fri, 16 Apr 2021 17:57:16 +0200 Subject: [PATCH] disable an alias if the user has too many bounces recently --- app/email_utils.py | 28 ++++++++++++++++++++++++++++ tests/test_email_utils.py | 30 ++++++++++++++++++++++++++++++ 2 files changed, 58 insertions(+) diff --git a/app/email_utils.py b/app/email_utils.py index 3f84cba7..1d251bef 100644 --- a/app/email_utils.py +++ b/app/email_utils.py @@ -12,6 +12,7 @@ from email.mime.multipart import MIMEMultipart from email.mime.text import MIMEText from email.utils import make_msgid, formatdate, parseaddr from smtplib import SMTP, SMTPServerDisconnected +from typing import Tuple, List import arrow import dkim @@ -1009,6 +1010,7 @@ def should_disable(alias: Alias) -> bool: ) return True else: + # alias level # if bounces at least 9 days in the last 10 days -> disable alias query = ( db.session.query( @@ -1032,6 +1034,32 @@ def should_disable(alias: Alias) -> bool: ) return True + # account level + query = ( + db.session.query( + func.date(EmailLog.created_at).label("date"), + func.count(EmailLog.id).label("count"), + ) + .filter(EmailLog.user_id == alias.user_id) + .filter( + EmailLog.created_at > arrow.now().shift(days=-10), + EmailLog.bounced.is_(True), + EmailLog.is_reply.is_(False), + ) + .group_by("date") + ) + + # if an account has more than 10 bounces every day for at least 4 days in the last 10 days, disable alias + date_bounces: List[Tuple[arrow.Arrow, int]] = list(query) + if len(date_bounces) > 4: + if all([v > 10 for _, v in date_bounces]): + LOG.d( + "+10 bounces for +4 days in the last 10 days on %s, disable alias %s", + alias.user, + alias, + ) + return True + return False diff --git a/tests/test_email_utils.py b/tests/test_email_utils.py index f7e37e4d..fb31a160 100644 --- a/tests/test_email_utils.py +++ b/tests/test_email_utils.py @@ -648,6 +648,36 @@ def test_should_disable_bounces_every_day(flask_client): assert should_disable(alias) +def test_should_disable_bounces_account(flask_client): + """if an account has more than 10 bounces every day for at least 5 days in the last 10 days, disable alias""" + user = login(flask_client) + alias = Alias.create_new_random(user) + + db.session.commit() + + # create a lot of bounces on alias + contact = Contact.create( + user_id=user.id, + alias_id=alias.id, + website_email="contact@example.com", + reply_email="rep@sl.local", + commit=True, + ) + + for day in range(6): + for _ in range(10): + EmailLog.create( + user_id=user.id, + contact_id=contact.id, + commit=True, + bounced=True, + created_at=arrow.now().shift(days=-day), + ) + + alias2 = Alias.create_new_random(user) + assert should_disable(alias2) + + def test_should_disable_bounce_consecutive_days(flask_client): user = login(flask_client) alias = Alias.create_new_random(user)