Discard ignored email

Create IgnoredEmail model
This commit is contained in:
Son NK 2021-06-22 17:52:24 +02:00
parent 3ed9c3d6fe
commit b84eb13ab5
4 changed files with 69 additions and 2 deletions

View File

@ -2293,3 +2293,10 @@ class Payout(db.Model, ModelMixin):
comment = db.Column(db.Text)
user = db.relationship(User)
class IgnoredEmail(db.Model, ModelMixin):
"""If an email has mail_from and rcpt_to present in this table, discard it by returning 250 status."""
mail_from = db.Column(db.String(512), nullable=False)
rcpt_to = db.Column(db.String(512), nullable=False)

View File

@ -120,6 +120,7 @@ from app.models import (
Mailbox,
Bounce,
TransactionalEmail,
IgnoredEmail,
)
from app.pgp_utils import PGPException, sign_data_with_pgpy, sign_data
from app.utils import sanitize_email
@ -1526,6 +1527,17 @@ def handle_bounce(envelope, email_log: EmailLog, msg: Message) -> str:
return "550 SL E26 Email cannot be forwarded to mailbox"
def should_ignore(mail_from: str, rcpt_tos: List[str]) -> bool:
if len(rcpt_tos) != 1:
return False
rcpt_to = rcpt_tos[0]
if IgnoredEmail.get_by(mail_from=mail_from, rcpt_to=rcpt_to):
return True
return False
def handle(envelope: Envelope) -> str:
"""Return SMTP status"""
@ -1535,6 +1547,10 @@ def handle(envelope: Envelope) -> str:
envelope.mail_from = mail_from
envelope.rcpt_tos = rcpt_tos
if should_ignore(mail_from, rcpt_tos):
LOG.e("Ignore email mail_from=%s rcpt_to=%s", mail_from, rcpt_tos)
return "250 email can't be sent from a reverse-alias"
msg = email.message_from_bytes(envelope.original_content)
postfix_queue_id = get_queue_id(msg)
if postfix_queue_id:

View File

@ -0,0 +1,36 @@
"""empty message
Revision ID: 29ea13ed76f9
Revises: a5e643d562c9
Create Date: 2021-06-22 17:51:27.343947
"""
import sqlalchemy_utils
from alembic import op
import sqlalchemy as sa
# revision identifiers, used by Alembic.
revision = '29ea13ed76f9'
down_revision = 'a5e643d562c9'
branch_labels = None
depends_on = None
def upgrade():
# ### commands auto generated by Alembic - please adjust! ###
op.create_table('ignored_email',
sa.Column('id', sa.Integer(), autoincrement=True, nullable=False),
sa.Column('created_at', sqlalchemy_utils.types.arrow.ArrowType(), nullable=False),
sa.Column('updated_at', sqlalchemy_utils.types.arrow.ArrowType(), nullable=True),
sa.Column('mail_from', sa.String(length=512), nullable=False),
sa.Column('rcpt_to', sa.String(length=512), nullable=False),
sa.PrimaryKeyConstraint('id')
)
# ### end Alembic commands ###
def downgrade():
# ### commands auto generated by Alembic - please adjust! ###
op.drop_table('ignored_email')
# ### end Alembic commands ###

View File

@ -1,5 +1,5 @@
from app.models import User, Alias, AuthorizedAddress
from email_handler import get_mailbox_from_mail_from
from app.models import User, Alias, AuthorizedAddress, IgnoredEmail
from email_handler import get_mailbox_from_mail_from, should_ignore
def test_get_mailbox_from_mail_from(flask_client):
@ -32,3 +32,11 @@ def test_get_mailbox_from_mail_from(flask_client):
)
mb = get_mailbox_from_mail_from("unauthorized@gmail.com", alias)
assert mb.email == "a@b.c"
def test_should_ignore(flask_client):
assert should_ignore("mail_from", []) is False
assert not should_ignore("mail_from", ["rcpt_to"])
IgnoredEmail.create(mail_from="mail_from", rcpt_to="rcpt_to", commit=True)
assert should_ignore("mail_from", ["rcpt_to"])