[FW][IMP] test_mail: test models with type do not mess with attachment types

Purpose of this commit is to highlight an issue that may happens easily with
`crm` that is made generic here within `test_mail`.

`crm` alters the context when creating a new record adding in this case
`default_type` to it][1]. The returned record contains that altered context.
his results in other records created from it trying to assign that same default
value for `type`. This is a very common name for fields, and happens to exist
in `ir.attachment` too.

If you create an alias for incoming leads in your DB with default values
`{"type": "lead"}` (something very common) and then an email comes to that
alias that contains an inlined base64 image, the attachment creation process
would simply fail.

Obtained error is ``ValueError: Wrong value for ir.attachment.type: 'lead'`` .

[1]: https://github.com/odoo/odoo/blob/272602193f5647f7f2270ed6ec68777625a139dd/addons/crm/models/crm_lead.py#L310-L311

X-original-commit: 99434b2e8528c10fcc9cb6860765e0ddcaa364c8
Part-of: odoo/odoo#77005
Co-authored-by: Thibault Delavallee <tde@odoo.com>
This commit is contained in:
Jairo Llopis
2021-09-22 19:25:55 +00:00
committed by Thibault Delavallée
co-authored by Thibault Delavallee
parent 223b51c462
commit 1efeffd297
6 changed files with 129 additions and 5 deletions
+10 -4
View File
@@ -109,20 +109,26 @@ class MockEmail(common.BaseCase):
def format(self, template, to='groups@example.com, other@gmail.com', subject='Frogs',
email_from='Sylvie Lelitre <test.sylvie.lelitre@agrolait.com>', return_path='', cc='',
extra='', msg_id='<1198923581.41972151344608186760.JavaMail@agrolait.com>'):
extra='', msg_id='<1198923581.41972151344608186760.JavaMail@agrolait.com>',
**kwargs):
return template.format(
subject=subject, to=to, cc=cc,
email_from=email_from, return_path=return_path,
extra=extra, msg_id=msg_id)
extra=extra, msg_id=msg_id,
**kwargs)
def format_and_process(self, template, email_from, to, subject='Frogs', cc='',
return_path='', extra='', msg_id=False,
model=None, target_model='mail.test.gateway', target_field='name'):
model=None, target_model='mail.test.gateway', target_field='name',
**kwargs):
self.assertFalse(self.env[target_model].search([(target_field, '=', subject)]))
if not msg_id:
msg_id = "<%.7f-test@iron.sky>" % (time.time())
mail = self.format(template, to=to, subject=subject, cc=cc, return_path=return_path, extra=extra, email_from=email_from, msg_id=msg_id)
mail = self.format(template, to=to, subject=subject, cc=cc,
return_path=return_path, extra=extra,
email_from=email_from, msg_id=msg_id,
**kwargs)
self.env['mail.thread'].message_process(model, mail)
return self.env[target_model].search([(target_field, '=', subject)])
+44
View File
@@ -43,6 +43,50 @@ Content-Transfer-Encoding: quoted-printable
------=_Part_4200734_24778174.1344608186754--
"""
MAIL_TEMPLATE_EXTRA_HTML = """Return-Path: <whatever-2a840@postmaster.twitter.com>
To: {to}
cc: {cc}
Received: by mail1.openerp.com (Postfix, from userid 10002)
id 5DF9ABFB2A; Fri, 10 Aug 2012 16:16:39 +0200 (CEST)
From: {email_from}
Subject: {subject}
MIME-Version: 1.0
Content-Type: multipart/alternative;
boundary="----=_Part_4200734_24778174.1344608186754"
Date: Fri, 10 Aug 2012 14:16:26 +0000
Message-ID: {msg_id}
{extra}
------=_Part_4200734_24778174.1344608186754
Content-Type: text/plain; charset=utf-8
Content-Transfer-Encoding: quoted-printable
Please call me as soon as possible this afternoon!
--
Sylvie
------=_Part_4200734_24778174.1344608186754
Content-Type: text/html; charset=utf-8
Content-Transfer-Encoding: quoted-printable
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
<html>
<head>=20
<meta http-equiv=3D"Content-Type" content=3D"text/html; charset=3Dutf-8" />
</head>=20
<body style=3D"margin: 0; padding: 0; background: #ffffff;-webkit-text-size-adjust: 100%;">=20
<p>Please call me as soon as possible this afternoon!</p>
{extra_html}
<p>--<br/>
Sylvie
<p>
</body>
</html>
------=_Part_4200734_24778174.1344608186754--
"""
MAIL_TEMPLATE_PLAINTEXT = """Return-Path: <whatever-2a840@postmaster.twitter.com>
To: {to}
Received: by mail1.openerp.com (Postfix, from userid 10002)
+2 -1
View File
@@ -1,5 +1,6 @@
# -*- coding: utf-8 -*-
# Part of Odoo. See LICENSE file for full copyright and licensing details.
from . import test_mail_models
from . import test_mail_corner_case_models
from . import test_mail_models
from . import test_mail_thread_models
@@ -32,6 +32,28 @@ class MailPerformanceTracking(models.Model):
field_2 = fields.Char(tracking=True)
class MailTestFieldType(models.Model):
""" Test default values, notably type, messing through models during gateway
processing (i.e. lead.type versus attachment.type). """
_description = 'Test Field Type'
_name = 'mail.test.field.type'
_inherit = ['mail.thread']
name = fields.Char()
email_from = fields.Char()
datetime = fields.Datetime(default=fields.Datetime.now)
customer_id = fields.Many2one('res.partner', 'Customer')
type = fields.Selection([('first', 'First'), ('second', 'Second')])
user_id = fields.Many2one('res.users', 'Responsible', tracking=True)
@api.model_create_multi
def create(self, vals_list):
# Emulate an addon that alters the creation context, such as `crm`
if not self._context.get('default_type'):
self = self.with_context(default_type='first')
return super(MailTestFieldType, self).create(vals_list)
class MailTestLang(models.Model):
""" A simple chatter model with lang-based capabilities, allowing to
test translations. """
@@ -9,6 +9,8 @@ access_mail_test_track_portal,mail.test.track.portal,model_mail_test_track,base.
access_mail_test_track_user,mail.test.track.user.employee,model_mail_test_track,base.group_user,1,1,1,1
access_mail_test_activity_portal,mail.test.activity.portal,model_mail_test_activity,base.group_portal,1,0,0,0
access_mail_test_activity_user,mail.test.activity.user,model_mail_test_activity,base.group_user,1,1,1,1
access_mail_test_field_type_portal,mail.test.field.type.portal,model_mail_test_field_type,base.group_portal,0,0,0,0
access_mail_test_field_type_user,mail.test.field.type.user,model_mail_test_field_type,base.group_user,1,1,1,1
access_mail_test_ticket_portal,mail.test.ticket.portal,model_mail_test_ticket,base.group_portal,0,0,0,0
access_mail_test_ticket_user,mail.test.ticket.user,model_mail_test_ticket,base.group_user,1,1,1,1
access_mail_test_composer_mixin_all,mail.test.composer.mixin.all,model_mail_test_composer_mixin,,0,0,0,0
1 id name model_id:id group_id:id perm_read perm_write perm_create perm_unlink
9 access_mail_test_track_user mail.test.track.user.employee model_mail_test_track base.group_user 1 1 1 1
10 access_mail_test_activity_portal mail.test.activity.portal model_mail_test_activity base.group_portal 1 0 0 0
11 access_mail_test_activity_user mail.test.activity.user model_mail_test_activity base.group_user 1 1 1 1
12 access_mail_test_field_type_portal mail.test.field.type.portal model_mail_test_field_type base.group_portal 0 0 0 0
13 access_mail_test_field_type_user mail.test.field.type.user model_mail_test_field_type base.group_user 1 1 1 1
14 access_mail_test_ticket_portal mail.test.ticket.portal model_mail_test_ticket base.group_portal 0 0 0 0
15 access_mail_test_ticket_user mail.test.ticket.user model_mail_test_ticket base.group_user 1 1 1 1
16 access_mail_test_composer_mixin_all mail.test.composer.mixin.all model_mail_test_composer_mixin 0 0 0 0
@@ -1140,6 +1140,55 @@ class TestMailgateway(TestMailCommon):
self.assertFalse(incoming_msg.parent_id)
self.assertTrue(incoming_msg.res_id == res_test.id)
# --------------------------------------------------
# Gateway / Record synchronization
# --------------------------------------------------
@mute_logger('odoo.addons.mail.models.mail_thread', 'odoo.models')
def test_gateway_values_base64_image(self):
"""New record with mail that contains base64 inline image."""
target_model = "mail.test.field.type"
alias = self.env["mail.alias"].create({
"alias_name": "base64-lover",
"alias_model_id": self.env["ir.model"]._get(target_model).id,
"alias_defaults": "{}",
"alias_contact": "everyone",
})
record = self.format_and_process(
test_mail_data.MAIL_TEMPLATE_EXTRA_HTML, self.email_from,
'%s@%s' % (alias.alias_name, self.alias_catchall),
subject='base64 image to alias',
target_model=target_model,
extra_html='<img src="data:image/png;base64,iV/+OkI=">',
)
self.assertEqual(record.type, "first")
self.assertEqual(len(record.message_ids[0].attachment_ids), 1)
self.assertEqual(record.message_ids[0].attachment_ids[0].name, "image0")
self.assertEqual(record.message_ids[0].attachment_ids[0].type, "binary")
@mute_logger('odoo.addons.mail.models.mail_thread', 'odoo.models')
def test_gateway_values_base64_image_walias(self):
"""New record with mail that contains base64 inline image + default values
coming from alias."""
target_model = "mail.test.field.type"
alias = self.env["mail.alias"].create({
"alias_name": "base64-lover",
"alias_model_id": self.env["ir.model"]._get(target_model).id,
"alias_defaults": "{'type': 'second'}",
"alias_contact": "everyone",
})
record = self.format_and_process(
test_mail_data.MAIL_TEMPLATE_EXTRA_HTML, self.email_from,
'%s@%s' % (alias.alias_name, self.alias_catchall),
subject='base64 image to alias',
target_model=target_model,
extra_html='<img src="data:image/png;base64,iV/+OkI=">',
)
self.assertEqual(record.type, "second")
self.assertEqual(len(record.message_ids[0].attachment_ids), 1)
self.assertEqual(record.message_ids[0].attachment_ids[0].name, "image0")
self.assertEqual(record.message_ids[0].attachment_ids[0].type, "binary")
# --------------------------------------------------
# Thread formation: mail gateway corner cases
# --------------------------------------------------