From 8457a46cb3175f3ab25907bcb50d2e2e6011667b Mon Sep 17 00:00:00 2001 From: Carlos Quintana <74399022+cquintana92@users.noreply.github.com> Date: Mon, 28 Oct 2024 09:50:25 +0100 Subject: [PATCH] Fix/none or object deleted crashes (#2295) * fix: handle None-case when get_or_create contact * chore: use already-calculated fields in order not to depend on the instance --- app/contact_utils.py | 8 +++++--- email_handler.py | 10 ++++++++-- 2 files changed, 13 insertions(+), 5 deletions(-) diff --git a/app/contact_utils.py b/app/contact_utils.py index e2bb62e3..d7fc89eb 100644 --- a/app/contact_utils.py +++ b/app/contact_utils.py @@ -91,6 +91,7 @@ def create_contact( alias_id = alias.id try: flags = Contact.FLAG_PARTNER_CREATED if from_partner else 0 + is_invalid_email = email == "" contact = Contact.create( user_id=alias.user_id, alias_id=alias.id, @@ -100,9 +101,10 @@ def create_contact( mail_from=mail_from, automatic_created=automatic_created, flags=flags, - invalid_email=email == "", + invalid_email=is_invalid_email, commit=True, ) + contact_id = contact.id if automatic_created: trail = ". Automatically created" else: @@ -110,11 +112,11 @@ def create_contact( emit_alias_audit_log( alias=alias, action=AliasAuditLogAction.CreateContact, - message=f"Created contact {contact.id} ({contact.email}){trail}", + message=f"Created contact {contact_id} ({email}){trail}", commit=True, ) LOG.d( - f"Created contact {contact} for alias {alias} with email {email} invalid_email={contact.invalid_email}" + f"Created contact {contact} for alias {alias} with email {email} invalid_email={is_invalid_email}" ) return ContactCreateResult(contact, created=True, error=None) except IntegrityError: diff --git a/email_handler.py b/email_handler.py index 38fa8ab4..59f203b3 100644 --- a/email_handler.py +++ b/email_handler.py @@ -177,7 +177,9 @@ from init_app import load_pgp_public_keys from server import create_light_app -def get_or_create_contact(from_header: str, mail_from: str, alias: Alias) -> Contact: +def get_or_create_contact( + from_header: str, mail_from: str, alias: Alias +) -> Optional[Contact]: """ contact_from_header is the RFC 2047 format FROM header """ @@ -208,6 +210,8 @@ def get_or_create_contact(from_header: str, mail_from: str, alias: Alias) -> Con automatic_created=True, from_partner=False, ) + if contact_result.error: + LOG.w(f"Error creating contact: {contact_result.error.value}") return contact_result.contact @@ -558,7 +562,7 @@ def handle_forward(envelope, msg: Message, rcpt_to: str) -> List[Tuple[bool, str if not user.is_active(): LOG.w(f"User {user} has been soft deleted") - return False, status.E502 + return [(False, status.E502)] if not user.can_send_or_receive(): LOG.i(f"User {user} cannot receive emails") @@ -579,6 +583,8 @@ def handle_forward(envelope, msg: Message, rcpt_to: str) -> List[Tuple[bool, str 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) + if not contact: + return [(False, status.E504)] alias = ( contact.alias ) # In case the Session was closed in the get_or_create we re-fetch the alias