From 43d70a670a0d28d5ccd6d000ea2ef2d70d227889 Mon Sep 17 00:00:00 2001 From: Veronika Kotovich Date: Sat, 14 Mar 2020 14:30:51 +0000 Subject: [PATCH] [FIX] mail: prepare mail header References to avoid line breaks When Odoo routes incoming emails it is looking for existing messages in database using Message Ids which are coming from e-mail header References. In Odoo the message id looks pretty long like 743570479975566.1584086032.522504091262817-openerp-message-notify@ip-172-31-45-160 As it declared in [RFC2822] long header bodies can be "folded" using CRLF+WSP. And some mail clients do that very thing. They split References header body which contains Message Ids by "\n ". The example of mail client where it can be reproduced is apps.rackspace.com We created Sales Order in Odoo, sent this quotation to the client email. He replied with e-mail, and this email can't be matched with any existing message id and as result it's not attached to the Sales Order. RFC2882: https://tools.ietf.org/html/rfc2822#section-2.2.3 closes odoo/odoo#68077 X-original-commit: 559f6cf62711ad45557eddec3af7c66616724eb5 Signed-off-by: Julien Castiaux --- addons/mail/models/mail_thread.py | 6 +++++- addons/test_mail/tests/test_mail_gateway.py | 21 +++++++++++++++++++++ doc/cla/individual/veryberry.md | 11 +++++++++++ 3 files changed, 37 insertions(+), 1 deletion(-) create mode 100644 doc/cla/individual/veryberry.md diff --git a/addons/mail/models/mail_thread.py b/addons/mail/models/mail_thread.py index 98349aa5308..5e606a5c473 100644 --- a/addons/mail/models/mail_thread.py +++ b/addons/mail/models/mail_thread.py @@ -861,7 +861,11 @@ class MailThread(models.AbstractModel): # compute references to find if message is a reply to an existing thread thread_references = message_dict['references'] or message_dict['in_reply_to'] - msg_references = [ref for ref in tools.mail_header_msgid_re.findall(thread_references) if 'reply_to' not in ref] + msg_references = [ + re.sub(r'[\r\n\t ]+', r'', ref) # "Unfold" buggy references + for ref in tools.mail_header_msgid_re.findall(thread_references) + if 'reply_to' not in ref + ] mail_messages = self.env['mail.message'].sudo().search([('message_id', 'in', msg_references)], limit=1, order='id desc, message_id') is_a_reply = bool(mail_messages) reply_model, reply_thread_id = mail_messages.model, mail_messages.res_id diff --git a/addons/test_mail/tests/test_mail_gateway.py b/addons/test_mail/tests/test_mail_gateway.py index f7969cc1ac6..35597ee1299 100644 --- a/addons/test_mail/tests/test_mail_gateway.py +++ b/addons/test_mail/tests/test_mail_gateway.py @@ -931,6 +931,27 @@ class TestMailgateway(TestMailCommon): self.assertEqual(len(self.test_record.message_ids), init_msg_count + 1) self.assertEqual(self.fake_email.child_ids, self.test_record.message_ids[0]) + @mute_logger('odoo.addons.mail.models.mail_thread') + def test_message_process_references_external_buggy_message_id(self): + """ + Incoming email being a reply to an external email processed by + odoo should update thread accordingly. Special case when the + external mail service wrongly folds the message_id on several + lines. + """ + new_message_id = '' + buggy_message_id = new_message_id.replace('MonsterEmail', 'Monster\r\n Email') + self.fake_email.write({ + 'message_id': new_message_id + }) + init_msg_count = len(self.test_record.message_ids) + self.format_and_process( + MAIL_TEMPLATE, self.email_from, 'erroneous@test.com', + extra='References: <2233@a.com>\r\n\t<3edss_dsa@b.com> %s' % buggy_message_id) + + self.assertEqual(len(self.test_record.message_ids), init_msg_count + 1) + self.assertEqual(self.fake_email.child_ids, self.test_record.message_ids[0]) + @mute_logger('odoo.addons.mail.models.mail_thread') def test_message_process_references_forward(self): """ Incoming email using references but with alias forward should not go into references destination """ diff --git a/doc/cla/individual/veryberry.md b/doc/cla/individual/veryberry.md new file mode 100644 index 00000000000..b923b1f2c29 --- /dev/null +++ b/doc/cla/individual/veryberry.md @@ -0,0 +1,11 @@ +Belarus, 2021-03-16 + +I hereby agree to the terms of the Odoo Individual Contributor License +Agreement v1.0. + +I declare that I am authorized and able to make this agreement and sign this +declaration. + +Signed, + +Veronika Kotovich veronika.kotovich@gmail.com https://github.com/veryberry