From 441746d0119b72125b0338f5cfb97db0b10c399c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Thibault=20Delavall=C3=A9e?= <tde@odoo.com> Date: Mon, 11 Apr 2022 12:44:54 +0200 Subject: [PATCH] [FIX] mail: avoid multi-emails in outgoing emails 'from' PURPOSE Be defensive when dealing with email fields, notably when having multi-emails or email field containing an already-formatted email. SPECIFICATIONS When building the final 'from' of outgoing emails using 'formataddr' we have issues if email contains multi emails or formatted email. Having a wrongly formatted email in 'email_from' leads to issues as it is badly recognized by email providers, could be considered as being phishing and also breaks reply_to mechanism. Main fix of this commit is to extract emails and rebuild the 'email_from' based on found emails. 'from' of sent emails is now the first found email in 'email_from' field of related <mail.mail> record like -> before: email_from: '"Raoul" <raoul@raoul.fr>, raoul2@raoul.fr' -> after: email_from: '"Raoul" <raoul@raoul.fr>' and raoul2 is ignored Task-2612945 (Mail: Defensive email formatting) Part-of: odoo/odoo#74474 --- addons/mail/models/mail_mail.py | 6 +++++- addons/test_mail/tests/test_mail_composer.py | 11 ++++++----- 2 files changed, 11 insertions(+), 6 deletions(-) diff --git a/addons/mail/models/mail_mail.py b/addons/mail/models/mail_mail.py index 399f82722beb..b29ccc946c90 100644 --- a/addons/mail/models/mail_mail.py +++ b/addons/mail/models/mail_mail.py @@ -361,11 +361,15 @@ class MailMail(models.Model): # see rev. 56596e5240ef920df14d99087451ce6f06ac6d36 notifs.flush(fnames=['notification_status', 'failure_type', 'failure_reason'], records=notifs) + # protect against ill-formatted email_from when formataddr was used on an already formatted email + emails_from = tools.email_split_and_format(mail.email_from) + email_from = emails_from[0] if emails_from else mail.email_from + # build an RFC2822 email.message.Message object and send it without queuing res = None for email in email_list: msg = IrMailServer.build_email( - email_from=mail.email_from, + email_from=email_from, email_to=email.get('email_to'), subject=mail.subject, body=email.get('body'), diff --git a/addons/test_mail/tests/test_mail_composer.py b/addons/test_mail/tests/test_mail_composer.py index 807b8f1000a7..2a7cf12f3201 100644 --- a/addons/test_mail/tests/test_mail_composer.py +++ b/addons/test_mail/tests/test_mail_composer.py @@ -721,8 +721,8 @@ class TestComposerResultsComment(TestMailComposer): author=self.partner_employee, email_values={ 'body_content': f'TemplateBody {self.test_record.name}', - # currently holding multi-email 'from' - 'email_from': formataddr((self.user_employee.name, 'email.from.1@test.example.com,email.from.2@test.example.com')), + # single email event if email field is multi-email + 'email_from': formataddr((self.user_employee.name, 'email.from.1@test.example.com')), 'subject': f'TemplateSubject {self.test_record.name}', }, fields_values={ @@ -740,7 +740,8 @@ class TestComposerResultsComment(TestMailComposer): ] + [[email] for email in mailed_new_partners.mapped('email_formatted')], email_values={ 'body_content': f'TemplateBody {self.test_record.name}', - 'email_from': formataddr((self.user_employee.name, 'email.from.1@test.example.com,email.from.2@test.example.com')), + # single email event if email field is multi-email + 'email_from': formataddr((self.user_employee.name, 'email.from.1@test.example.com')), 'subject': f'TemplateSubject {self.test_record.name}', }, fields_values={ @@ -1175,8 +1176,8 @@ class TestComposerResultsMass(TestMailComposer): ] + [[email] for email in mailed_new_partners.mapped('email_formatted')], email_values={ 'body_content': f'TemplateBody {record.name}', - # currently holding multi-email 'email_from' - 'email_from': self.partner_employee.email_formatted, + # single email event if email field is multi-email + 'email_from': formataddr((self.user_employee.name, 'email.from.1@test.example.com')), 'reply_to': formataddr(( f'{self.env.user.company_id.name} {record.name}', f'{self.alias_catchall}@{self.alias_domain}' -- GitLab