parent
3ed9c3d6fe
commit
b84eb13ab5
|
@ -2293,3 +2293,10 @@ class Payout(db.Model, ModelMixin):
|
||||||
comment = db.Column(db.Text)
|
comment = db.Column(db.Text)
|
||||||
|
|
||||||
user = db.relationship(User)
|
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)
|
||||||
|
|
|
@ -120,6 +120,7 @@ from app.models import (
|
||||||
Mailbox,
|
Mailbox,
|
||||||
Bounce,
|
Bounce,
|
||||||
TransactionalEmail,
|
TransactionalEmail,
|
||||||
|
IgnoredEmail,
|
||||||
)
|
)
|
||||||
from app.pgp_utils import PGPException, sign_data_with_pgpy, sign_data
|
from app.pgp_utils import PGPException, sign_data_with_pgpy, sign_data
|
||||||
from app.utils import sanitize_email
|
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"
|
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:
|
def handle(envelope: Envelope) -> str:
|
||||||
"""Return SMTP status"""
|
"""Return SMTP status"""
|
||||||
|
|
||||||
|
@ -1535,6 +1547,10 @@ def handle(envelope: Envelope) -> str:
|
||||||
envelope.mail_from = mail_from
|
envelope.mail_from = mail_from
|
||||||
envelope.rcpt_tos = rcpt_tos
|
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)
|
msg = email.message_from_bytes(envelope.original_content)
|
||||||
postfix_queue_id = get_queue_id(msg)
|
postfix_queue_id = get_queue_id(msg)
|
||||||
if postfix_queue_id:
|
if postfix_queue_id:
|
||||||
|
|
|
@ -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 ###
|
|
@ -1,5 +1,5 @@
|
||||||
from app.models import User, Alias, AuthorizedAddress
|
from app.models import User, Alias, AuthorizedAddress, IgnoredEmail
|
||||||
from email_handler import get_mailbox_from_mail_from
|
from email_handler import get_mailbox_from_mail_from, should_ignore
|
||||||
|
|
||||||
|
|
||||||
def test_get_mailbox_from_mail_from(flask_client):
|
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)
|
mb = get_mailbox_from_mail_from("unauthorized@gmail.com", alias)
|
||||||
assert mb.email == "a@b.c"
|
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"])
|
||||||
|
|
Loading…
Reference in New Issue