diff --git a/addons/account/tests/test_account_incoming_supplier_invoice.py b/addons/account/tests/test_account_incoming_supplier_invoice.py
index 40fac722805..ac88ef5145b 100644
--- a/addons/account/tests/test_account_incoming_supplier_invoice.py
+++ b/addons/account/tests/test_account_incoming_supplier_invoice.py
@@ -12,8 +12,6 @@ class TestAccountIncomingSupplierInvoice(AccountTestInvoicingCommon):
def setUpClass(cls, chart_template_ref=None):
super().setUpClass(chart_template_ref=chart_template_ref)
- cls.env['ir.config_parameter'].sudo().set_param('mail.catchall.domain', 'test.mycompany.com')
-
cls.internal_user = cls.env['res.users'].create({
'name': 'Internal User',
'login': 'internal.user@test.odoo.com',
diff --git a/addons/google_calendar/tests/test_sync_google2odoo.py b/addons/google_calendar/tests/test_sync_google2odoo.py
index 4560ac9e692..4459d3763a2 100644
--- a/addons/google_calendar/tests/test_sync_google2odoo.py
+++ b/addons/google_calendar/tests/test_sync_google2odoo.py
@@ -1345,7 +1345,6 @@ class TestSyncGoogle2Odoo(TestSyncGoogle):
@patch_api
def test_alias_email_sync_recurrence(self):
- self.env['ir.config_parameter'].sudo().set_param('mail.catchall.domain', 'test.mycompany.com')
alias_model = self.env['ir.model'].search([('model', '=', 'calendar.event')])
mail_alias = self.env['mail.alias'].create({'alias_name': 'sale', 'alias_model_id': alias_model.id})
diff --git a/addons/mail/models/ir_config_parameter.py b/addons/mail/models/ir_config_parameter.py
index 5bf36e62605..9112fd6ed27 100644
--- a/addons/mail/models/ir_config_parameter.py
+++ b/addons/mail/models/ir_config_parameter.py
@@ -25,6 +25,6 @@ class IrConfigParameter(models.Model):
value = self.env['mail.alias']._sanitize_alias_name(value)
# sanitize and normalize allowed catchall domains
elif key == 'mail.catchall.domain.allowed' and value:
- value = self.env['mail.alias']._clean_and_check_mail_catchall_allowed_domains(value)
+ value = self.env['mail.alias']._sanitize_allowed_domains(value)
return super().set_param(key, value)
diff --git a/addons/mail/models/mail_alias.py b/addons/mail/models/mail_alias.py
index 590b86a7dd0..7e62142b6a3 100644
--- a/addons/mail/models/mail_alias.py
+++ b/addons/mail/models/mail_alias.py
@@ -81,6 +81,7 @@ class Alias(models.Model):
"- everyone: everyone can post\n"
"- partners: only authenticated partners\n"
"- followers: only followers of the related document or members of following channels\n")
+ alias_incoming_local = fields.Boolean('Local-part based incoming detection', default=False)
alias_bounced_content = fields.Html(
"Custom Bounced Message", translate=True,
help="If set, this content will automatically be sent out to unauthorized users instead of the default message.")
@@ -288,18 +289,6 @@ class Alias(models.Model):
return super().write(vals)
- def _clean_and_check_mail_catchall_allowed_domains(self, value):
- """ The purpose of this system parameter is to avoid the creation
- of records from incoming emails with a domain != alias_domain
- but that have a pattern matching an internal mail.alias . """
- value = [domain.strip().lower() for domain in value.split(',') if domain.strip()]
- if not value:
- raise ValidationError(
- _("Value for `mail.catchall.domain.allowed` cannot be validated.\n"
- "It should be a comma separated list of domains e.g. example.com,example.org.")
- )
- return ",".join(value)
-
def _check_unique(self, alias_names, alias_domains):
""" Check unicity constraint won't be raised, otherwise raise a UserError
with a complete error message. Also check unicity against alias config
@@ -359,6 +348,20 @@ class Alias(models.Model):
msg_end = _('Choose another value or change it on the other document.')
raise UserError(f'{msg_begin} {msg_end}')
+ @api.model
+ def _sanitize_allowed_domains(self, allowed_domains):
+ """ When having aliases checked on email left-part only we may define
+ an allowed list for right-part filtering, allowing more fine-grain than
+ either alias domain, either everything. This method sanitized its value. """
+ value = [domain.strip().lower() for domain in allowed_domains.split(',') if domain.strip()]
+ if not value:
+ raise ValidationError(_(
+ "Value %(allowed_domains)s for `mail.catchall.domain.allowed` cannot be validated.\n"
+ "It should be a comma separated list of domains e.g. example.com,example.org.",
+ allowed_domains=allowed_domains
+ ))
+ return ",".join(value)
+
@api.model
def _sanitize_alias_name(self, name):
""" Cleans and sanitizes the alias name """
diff --git a/addons/mail/models/mail_thread.py b/addons/mail/models/mail_thread.py
index a73e458bf57..e56c23f4578 100644
--- a/addons/mail/models/mail_thread.py
+++ b/addons/mail/models/mail_thread.py
@@ -345,22 +345,23 @@ class MailThread(models.AbstractModel):
that adds alias information. """
model = self._context.get('empty_list_help_model')
res_id = self._context.get('empty_list_help_id')
- catchall_domain = self.env['ir.config_parameter'].sudo().get_param("mail.catchall.domain")
document_name = self._context.get('empty_list_help_document_name', _('document'))
nothing_here = is_html_empty(help_message)
alias = None
- if catchall_domain and model and res_id: # specific res_id -> find its alias (i.e. section_id specified)
+ # specific res_id -> find its alias (i.e. section_id specified)
+ if model and res_id:
record = self.env[model].sudo().browse(res_id)
# check that the alias effectively creates new records
- if record.alias_id and record.alias_id.alias_name and \
- record.alias_id.alias_model_id and \
- record.alias_id.alias_model_id.model == self._name and \
- record.alias_id.alias_force_thread_id == 0:
+ if ('alias_id' in record and record.alias_id and
+ record.alias_id.alias_name and record.alias_id.alias_domain and
+ record.alias_id.alias_model_id.model == self._name and
+ record.alias_id.alias_force_thread_id == 0):
alias = record.alias_id
- if not alias and catchall_domain and model: # no res_id or res_id not linked to an alias -> generic help message, take a generic alias of the model
- Alias = self.env['mail.alias']
- aliases = Alias.search([
+ # no res_id or res_id not linked to an alias -> generic help message, take a generic alias of the model
+ if not alias and model and self.env.company.alias_domain_id:
+ aliases = self.env['mail.alias'].search([
+ ("alias_domain_id", "=", self.env.company.alias_domain_id.id),
("alias_parent_model_id.model", "=", model),
("alias_name", "!=", False),
('alias_force_thread_id', '=', False),
@@ -695,13 +696,19 @@ class MailThread(models.AbstractModel):
'email_to': bounce_to,
'auto_delete': True,
}
- bounce_from = tools.email_normalize(self.env['ir.mail_server']._get_default_bounce_address() or '')
- if bounce_from:
- bounce_mail_values['email_from'] = tools.formataddr(('MAILER-DAEMON', bounce_from))
- elif self.env['ir.config_parameter'].sudo().get_param("mail.catchall.alias") not in message['To']:
- bounce_mail_values['email_from'] = tools.decode_message_header(message, 'To')
- else:
- bounce_mail_values['email_from'] = tools.formataddr(('MAILER-DAEMON', self.env.user.email_normalized))
+
+ # find an email_from for the bounce email
+ email_from = False
+ if bounce_from := self.env.company.bounce_email:
+ email_from = tools.formataddr(('MAILER-DAEMON', bounce_from))
+ if not email_from:
+ catchall_aliases = self.env['mail.alias.domain'].search([]).mapped('catchall_email')
+ if not any(catchall_email in message['To'] for catchall_email in catchall_aliases):
+ email_from = tools.decode_message_header(message, 'To')
+ if not email_from:
+ email_from = tools.formataddr(('MAILER-DAEMON', self.env.user.email_normalized))
+
+ bounce_mail_values['email_from'] = email_from
bounce_mail_values.update(mail_values)
self.env['mail.mail'].sudo().create(bounce_mail_values).send()
@@ -885,13 +892,12 @@ class MailThread(models.AbstractModel):
we also need to verify if the message come from "mailer-daemon"
"""
# detection based on email_to
- bounce_alias = self.env['ir.config_parameter'].sudo().get_param("mail.bounce.alias")
- email_to = message_dict['to']
- email_to_localparts = [
- e.split('@', 1)[0].lower()
- for e in (tools.email_split(email_to) or [''])
+ bounce_aliases = self.env['mail.alias.domain'].search([]).mapped('bounce_email')
+ email_to_list = [
+ tools.email_normalize(e) or e
+ for e in (tools.email_split(message_dict['to']) or [''])
]
- if bounce_alias and bounce_alias in email_to_localparts:
+ if bounce_aliases and any(email in bounce_aliases for email in email_to_list):
return True
email_from = message_dict['email_from']
@@ -1001,16 +1007,15 @@ class MailThread(models.AbstractModel):
@api.model
def _detect_write_to_catchall(self, msg_dict):
"""Return True if directly contacts catchall."""
- catchall_alias = self.env['ir.config_parameter'].sudo().get_param("mail.catchall.alias")
- email_to = msg_dict['to']
- email_to_localparts = [
- e.split('@', 1)[0].lower()
- for e in (tools.email_split(email_to) or [''])
+ catchall_aliases = self.env['mail.alias.domain'].search([]).mapped('catchall_email')
+ email_to_list = [
+ tools.email_normalize(e) or e
+ for e in (tools.email_split(msg_dict['to']) or [''])
]
# check it does not directly contact catchall
return (
- catchall_alias and email_to_localparts and
- all(email_localpart == catchall_alias for email_localpart in email_to_localparts)
+ catchall_aliases and email_to_list and
+ all(email_to in catchall_aliases for email_to in email_to_list)
)
@api.model
@@ -1050,10 +1055,19 @@ class MailThread(models.AbstractModel):
"""
if not isinstance(message, EmailMessage):
raise TypeError('message must be an email.message.EmailMessage at this point')
- catchall_domain_lowered = self.env["ir.config_parameter"].sudo().get_param("mail.catchall.domain", "").strip().lower()
- catchall_domains_allowed = self.env["ir.config_parameter"].sudo().get_param("mail.catchall.domain.allowed")
- if catchall_domain_lowered and catchall_domains_allowed:
- catchall_domains_allowed = catchall_domains_allowed.split(',') + [catchall_domain_lowered]
+ catchall_domains_allowed = list(filter(None, (self.env["ir.config_parameter"].sudo().get_param(
+ "mail.catchall.domain.allowed") or '').split(',')))
+ if catchall_domains_allowed:
+ catchall_domains_allowed += self.env['mail.alias.domain'].search([]).mapped('name')
+
+ def _filter_excluded_local_part(email):
+ left, _at, domain = email.partition('@')
+ if not domain:
+ return False
+ if catchall_domains_allowed and domain not in catchall_domains_allowed:
+ return False
+ return left
+
fallback_model = model
# handle bounce: verify whether this is a bounced email and use it to
@@ -1080,19 +1094,13 @@ class MailThread(models.AbstractModel):
# author and recipients
email_from = message_dict['email_from']
- email_to = message_dict['to']
- email_to_localparts = [
- e.split('@', 1)[0].lower()
- for e in (tools.email_split(email_to) or [''])
- ]
+ email_to_list = [e.lower() for e in (tools.email_split(message_dict['to']) or [''])]
+ email_to_localparts = list(filter(None, (_filter_excluded_local_part(email_to) for email_to in email_to_list)))
# Delivered-To is a safe bet in most modern MTAs, but we have to fallback on To + Cc values
# for all the odd MTAs out there, as there is no standard header for the envelope's `rcpt_to` value.
- rcpt_tos_localparts = []
- for recipient in tools.email_split(message_dict['recipients']):
- to_local, to_domain = recipient.split('@', maxsplit=1)
- if not catchall_domains_allowed or to_domain.lower() in catchall_domains_allowed:
- rcpt_tos_localparts.append(to_local.lower())
- rcpt_tos_valid_localparts = [to for to in rcpt_tos_localparts]
+ rcpt_tos_list = [e.lower() for e in (tools.email_split(message_dict['recipients']) or [''])]
+ rcpt_tos_localparts = list(filter(None, (_filter_excluded_local_part(email_to) for email_to in rcpt_tos_list)))
+ rcpt_tos_valid_list = list(rcpt_tos_list)
# 1. Handle reply
# if destination = alias with different model -> consider it is a forward and not a reply
@@ -1100,20 +1108,32 @@ class MailThread(models.AbstractModel):
if reply_model and reply_thread_id:
reply_model_id = self.env['ir.model']._get_id(reply_model)
other_model_aliases = self.env['mail.alias'].search([
- '&', '&',
- ('alias_name', '!=', False),
- ('alias_name', 'in', email_to_localparts),
+ '&',
('alias_model_id', '!=', reply_model_id),
+ '|',
+ ('alias_full_name', 'in', email_to_list),
+ '&', ('alias_name', 'in', email_to_localparts), ('alias_incoming_local', '=', True),
])
if other_model_aliases:
is_a_reply, reply_model, reply_thread_id = False, False, False
- rcpt_tos_valid_localparts = [to for to in rcpt_tos_valid_localparts if to in other_model_aliases.mapped('alias_name')]
+ rcpt_tos_valid_list = [
+ to
+ for to in rcpt_tos_valid_list
+ if (
+ to in other_model_aliases.mapped('alias_full_name')
+ or to.split('@', 1)[0] in other_model_aliases.filtered('alias_incoming_local').mapped('alias_name')
+ )
+ ]
+ rcpt_tos_valid_localparts = list(filter(None, (_filter_excluded_local_part(email_to) for email_to in rcpt_tos_valid_list)))
if is_a_reply and reply_model:
reply_model_id = self.env['ir.model']._get_id(reply_model)
dest_aliases = self.env['mail.alias'].search([
- ('alias_name', 'in', rcpt_tos_localparts),
- ('alias_model_id', '=', reply_model_id)
+ '&',
+ ('alias_model_id', '=', reply_model_id),
+ '|',
+ ('alias_full_name', 'in', rcpt_tos_list),
+ '&', ('alias_name', 'in', rcpt_tos_localparts), ('alias_incoming_local', '=', True),
], limit=1)
user_id = self._mail_find_user_for_gateway(email_from, alias=dest_aliases).id or self._uid
@@ -1124,27 +1144,31 @@ class MailThread(models.AbstractModel):
if route:
_logger.info(
'Routing mail from %s to %s with Message-Id %s: direct reply to msg: model: %s, thread_id: %s, custom_values: %s, uid: %s',
- email_from, email_to, message_id, reply_model, reply_thread_id, custom_values, self._uid)
+ email_from, message_dict['to'], message_id, reply_model, reply_thread_id, custom_values, self._uid)
return [route]
if route is False:
return []
# 2. Handle new incoming email by checking aliases and applying their settings
- if rcpt_tos_localparts:
+ if rcpt_tos_list:
# no route found for a matching reference (or reply), so parent is invalid
message_dict.pop('parent_id', None)
# check it does not directly contact catchall
if self._detect_write_to_catchall(message_dict):
_logger.info('Routing mail from %s to %s with Message-Id %s: direct write to catchall, bounce',
- email_from, email_to, message_id)
+ email_from, message_dict['to'], message_id)
body = self.env['ir.qweb']._render('mail.mail_bounce_catchall', {
'message': message,
})
self._routing_create_bounce_email(email_from, body, message, references=message_id, reply_to=self.env.company.email)
return []
- dest_aliases = self.env['mail.alias'].search([('alias_name', 'in', rcpt_tos_valid_localparts)])
+ dest_aliases = self.env['mail.alias'].search([
+ '|',
+ ('alias_full_name', 'in', rcpt_tos_valid_list),
+ '&', ('alias_name', 'in', rcpt_tos_valid_localparts), ('alias_incoming_local', '=', True),
+ ])
if dest_aliases:
routes = []
for alias in dest_aliases:
@@ -1154,7 +1178,7 @@ class MailThread(models.AbstractModel):
if route:
_logger.info(
'Routing mail from %s to %s with Message-Id %s: direct alias match: %r',
- email_from, email_to, message_id, route)
+ email_from, message_dict['to'], message_id, route)
routes.append(route)
return routes
@@ -1170,14 +1194,14 @@ class MailThread(models.AbstractModel):
if route:
_logger.info(
'Routing mail from %s to %s with Message-Id %s: fallback to model:%s, thread_id:%s, custom_values:%s, uid:%s',
- email_from, email_to, message_id, fallback_model, thread_id, custom_values, user_id)
+ email_from, message_dict['to'], message_id, fallback_model, thread_id, custom_values, user_id)
return [route]
# ValueError if no routes found and if no bounce occurred
raise ValueError(
'No possible route found for incoming message from %s to %s (Message-Id %s:). '
'Create an appropriate mail.alias or force the destination model.' %
- (email_from, email_to, message_id)
+ (email_from, message_dict['to'], message_id)
)
@api.model
@@ -1842,12 +1866,8 @@ class MailThread(models.AbstractModel):
if not normalized_email:
return self.env['res.users']
- catchall_domain = self.env['ir.config_parameter'].sudo().get_param("mail.catchall.domain")
- if catchall_domain:
- left_part = normalized_email.split('@')[0] if normalized_email.split('@')[1] == catchall_domain.lower() else False
- if left_part:
- if self.env['mail.alias'].sudo().search_count([('alias_name', '=', left_part)]):
- return self.env['res.users']
+ if self.env['mail.alias'].sudo().search_count([('alias_full_name', '=', email_value)]):
+ return self.env['res.users']
if alias and alias.alias_parent_model_id and alias.alias_parent_thread_id:
followers = self.env['mail.followers'].search([
@@ -1895,7 +1915,6 @@ class MailThread(models.AbstractModel):
followers = records.mapped('message_partner_ids')
else:
followers = self.env['res.partner']
- catchall_domain = self.env['ir.config_parameter'].sudo().get_param("mail.catchall.domain")
# first, build a normalized email list and remove those linked to aliases
# to avoid adding aliases as partners. In case of multi-email input, use
@@ -1904,11 +1923,9 @@ class MailThread(models.AbstractModel):
for email_normalized in (tools.email_normalize(contact, strict=False) for contact in emails)
if email_normalized
]
- if catchall_domain:
- domain_left_parts = [email.split('@')[0] for email in normalized_emails if email and email.split('@')[1] == catchall_domain.lower()]
- if domain_left_parts:
- found_alias_names = self.env['mail.alias'].sudo().search([('alias_name', 'in', domain_left_parts)]).mapped('alias_name')
- normalized_emails = [email for email in normalized_emails if email.split('@')[0] not in found_alias_names]
+ matching_aliases = self.env['mail.alias'].sudo().search([('alias_full_name', 'in', normalized_emails)])
+ if matching_aliases:
+ normalized_emails = [email for email in normalized_emails if email not in matching_aliases.mapped('alias_full_name')]
done_partners = [follower for follower in followers if follower.email_normalized in normalized_emails]
remaining = [email for email in normalized_emails if email not in [partner.email_normalized for partner in done_partners]]
diff --git a/addons/mail/views/mail_alias_views.xml b/addons/mail/views/mail_alias_views.xml
index e3cb6ab6deb..294a648a17b 100644
--- a/addons/mail/views/mail_alias_views.xml
+++ b/addons/mail/views/mail_alias_views.xml
@@ -42,6 +42,7 @@
+
@@ -66,6 +67,7 @@
+
consider as a forward """
@@ -806,6 +843,7 @@ class TestMailgateway(MailCommon):
# test@.. will cause the creation of new mail.test
new_alias_2 = self.env['mail.alias'].create({
+ 'alias_domain_id': self.mail_alias_domain.id,
'alias_name': 'test',
'alias_model_id': self.env['ir.model']._get('mail.test.container').id,
'alias_contact': 'everyone',
@@ -832,6 +870,7 @@ class TestMailgateway(MailCommon):
# test@.. will cause the creation of new mail.test
new_alias_2 = self.env['mail.alias'].create({
+ 'alias_domain_id': self.mail_alias_domain.id,
'alias_name': 'test',
'alias_model_id': self.env['ir.model']._get('mail.test.container').id,
'alias_contact': 'everyone',
@@ -861,6 +900,7 @@ class TestMailgateway(MailCommon):
# test@.. will cause the creation of new mail.test
new_alias_2 = self.env['mail.alias'].create({
+ 'alias_domain_id': self.mail_alias_domain.id,
'alias_name': 'test',
'alias_model_id': self.env['ir.model']._get('mail.test.container').id,
'alias_contact': 'everyone',
@@ -886,6 +926,7 @@ class TestMailgateway(MailCommon):
""" Incoming email: write to two aliases creating records: both should be activated """
# test@.. will cause the creation of new mail.test
new_alias_2 = self.env['mail.alias'].create({
+ 'alias_domain_id': self.mail_alias_domain.id,
'alias_name': 'test',
'alias_model_id': self.env['ir.model']._get('mail.test.container').id,
'alias_contact': 'everyone',
@@ -907,9 +948,11 @@ class TestMailgateway(MailCommon):
""" Incoming email: check that if domains are set in the optional system
parameter `mail.catchall.domain.allowed` only incoming emails from these
domains will generate records."""
- # test@.. will cause the creation of new mail.test
+ # test@.. will cause the creation of new mail.test.container
new_alias_2 = self.env['mail.alias'].create({
'alias_contact': 'everyone',
+ 'alias_domain_id': self.mail_alias_domain_c2.id,
+ 'alias_incoming_local': True,
'alias_model_id': self.env['ir.model']._get_id('mail.test.container.mc'),
'alias_name': 'test',
})
@@ -917,6 +960,8 @@ class TestMailgateway(MailCommon):
test_domain = 'hello.com'
for (alias_right_part, allowed_domain), container_created in zip(
[
+ # Test a valid alias domain, standard case
+ (self.mail_alias_domain_c2.name, ""),
# Test with 'mail.catchall.domain.allowed' not set in system parameters
# and with a domain not allowed
('bonjour.com', ""),
@@ -926,7 +971,7 @@ class TestMailgateway(MailCommon):
# Test with 'mail.catchall.domain.allowed' set in system parameters
# and with a domain allowed
(test_domain, test_domain),
- ], [True, False, True]):
+ ], [True, True, False, True]):
with self.subTest(alias_right_part=alias_right_part, allowed_domain=allowed_domain):
self.env['ir.config_parameter'].set_param('mail.catchall.domain.allowed', allowed_domain)
@@ -1437,6 +1482,7 @@ class TestMailgateway(MailCommon):
def test_message_process_references_forward(self):
""" Incoming email using references but with alias forward should not go into references destination """
self.env['mail.alias'].create({
+ 'alias_domain_id': self.mail_alias_domain.id,
'alias_name': 'test.alias',
'alias_model_id': self.env['ir.model']._get('mail.test.container').id,
'alias_contact': 'everyone',
@@ -1457,6 +1503,7 @@ class TestMailgateway(MailCommon):
def test_message_process_references_forward_same_model(self):
""" Incoming email using references but with alias forward on same model should be considered as a reply """
self.env['mail.alias'].create({
+ 'alias_domain_id': self.mail_alias_domain.id,
'alias_name': 'test.alias',
'alias_model_id': self.env['ir.model']._get('mail.test.gateway').id,
'alias_contact': 'everyone',
@@ -1476,6 +1523,7 @@ class TestMailgateway(MailCommon):
def test_message_process_references_forward_cc(self):
""" Incoming email using references but with alias forward in CC should be considered as a repy (To > Cc) """
self.env['mail.alias'].create({
+ 'alias_domain_id': self.mail_alias_domain.id,
'alias_name': 'test.alias',
'alias_model_id': self.env['ir.model']._get('mail.test.container').id,
'alias_contact': 'everyone',
@@ -1549,6 +1597,7 @@ class TestMailgateway(MailCommon):
"""New record with mail that contains base64 inline image."""
target_model = "mail.test.field.type"
alias = self.env["mail.alias"].create({
+ 'alias_domain_id': self.mail_alias_domain.id,
"alias_name": "base64-lover",
"alias_model_id": self.env["ir.model"]._get(target_model).id,
"alias_defaults": "{}",
@@ -1572,6 +1621,7 @@ class TestMailgateway(MailCommon):
coming from alias."""
target_model = "mail.test.field.type"
alias = self.env["mail.alias"].create({
+ 'alias_domain_id': self.mail_alias_domain.id,
"alias_name": "base64-lover",
"alias_model_id": self.env["ir.model"]._get(target_model).id,
"alias_defaults": "{'type': 'second'}",
@@ -1698,6 +1748,7 @@ class TestMailgateway(MailCommon):
])
alias = self.env['mail.alias'].create({
+ 'alias_domain_id': self.mail_alias_domain.id,
'alias_name': 'test',
'alias_model_id': self.env['ir.model']._get('mail.test.container').id,
'alias_contact': 'everyone',
@@ -1828,6 +1879,7 @@ class TestMailgateway(MailCommon):
})
self.env['mail.alias'].create({
+ 'alias_domain_id': self.mail_alias_domain.id,
'alias_name': 'test',
'alias_model_id': self.env['ir.model']._get('mail.test.gateway').id,
})
@@ -1852,6 +1904,7 @@ class TestMailThreadCC(MailCommon):
cls.email_from = 'Sylvie Lelitre '
cls.alias = cls.env['mail.alias'].create({
'alias_contact': 'everyone',
+ 'alias_domain_id': cls.mail_alias_domain.id,
'alias_model_id': cls.env['ir.model']._get('mail.test.cc').id,
'alias_name': 'cc_record',
})
diff --git a/odoo/addons/base/tests/test_ir_mail_server.py b/odoo/addons/base/tests/test_ir_mail_server.py
index 7557421649a..b9c328f5f91 100644
--- a/odoo/addons/base/tests/test_ir_mail_server.py
+++ b/odoo/addons/base/tests/test_ir_mail_server.py
@@ -294,7 +294,6 @@ class TestIrMailServer(TransactionCase, MockSmtplibCase):
@mute_logger('odoo.models.unlink')
def test_mail_server_send_email_IDNA(self):
""" Test that the mail from / recipient envelop are encoded using IDNA """
- self.env['ir.config_parameter'].sudo().set_param('mail.catchall.domain', 'ééééééé.com')
with self.mock_smtplib_connection():
message = self._build_email(mail_from='test@ééééééé.com')
self.env['ir.mail_server'].send_email(message)