summaryrefslogtreecommitdiff
path: root/addons/mail/models
diff options
context:
space:
mode:
authorRémy Voet (ryv) <ryv@odoo.com>2019-12-18 12:01:37 +0000
committerThibault Delavallée <tde@odoo.com>2020-03-12 13:54:32 +0000
commitc5e6511e8d35a206e966658325ac8dce6a097a48 (patch)
tree821939459ad332fbab22766517e6b98e949d1e9f /addons/mail/models
parent974f512f5f5d3b9f80a8c3fcde290e4f55cf1230 (diff)
[IMP] mail: ease bounce email content update based on alias security
PURPOSE When incoming emails bounce due to alias security bounce email is quite generic. Purpose of this task is to ease its customization and update. SPECIFICATIONS In order to improve the flexibility of alias, add a customizable html field on the alias model. This html content will be send as bounce email core content in case of bounced/unauthorized mail received for this alias, Obviously it has no effect on 'everyone' security setting as no email will bounce due to that issue. If it is not set a default generic mail will be send depending on security setting. It allows to keep void html fields when no specific bounce content is required In HR, an old template allowing some light customization for employee based security option is removed as it is completely replaced by the new feature. Also add references message-id of the mail received to the answer so that threads are correctly set. LINKS Task ID 2126509
Diffstat (limited to 'addons/mail/models')
-rw-r--r--addons/mail/models/mail_alias.py51
-rw-r--r--addons/mail/models/mail_channel.py4
-rw-r--r--addons/mail/models/mail_thread.py24
3 files changed, 48 insertions, 31 deletions
diff --git a/addons/mail/models/mail_alias.py b/addons/mail/models/mail_alias.py
index 839123896c8..43c2350fdb3 100644
--- a/addons/mail/models/mail_alias.py
+++ b/addons/mail/models/mail_alias.py
@@ -7,7 +7,7 @@ import re
from odoo import _, api, fields, models
from odoo.exceptions import ValidationError
-from odoo.tools import remove_accents
+from odoo.tools import remove_accents, is_html_empty
_logger = logging.getLogger(__name__)
@@ -68,6 +68,9 @@ 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_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.")
_sql_constraints = [
('alias_unique', 'UNIQUE(alias_name)', 'Unfortunately this email alias is already used, please choose a unique one')
@@ -171,6 +174,36 @@ class Alias(models.Model):
'type': 'ir.actions.act_window',
}
+ def _get_alias_bounced_body_fallback(self, message_dict):
+ return _("""Hi,<br/>
+The following email sent to %s cannot be accepted because this is a private email address.
+Only allowed people can contact us at this address.""" % message_dict.get('to'))
+
+ def _get_alias_bounced_body(self, message_dict):
+ """Get the body of the email return in case of bounced email.
+
+ :param message_dict: dictionary of mail values
+ """
+ lang_author = False
+ if message_dict.get('author_id'):
+ try:
+ lang_author = self.env['res.partner'].browse(message_dict['author_id']).lang
+ except:
+ pass
+
+ if lang_author:
+ self = self.with_context(lang=lang_author)
+
+ if not is_html_empty(self.alias_bounced_content):
+ body = self.alias_bounced_content
+ else:
+ body = self._get_alias_bounced_body_fallback(message_dict)
+ template = self.env.ref('mail.mail_bounce_alias_security', raise_if_not_found=True)
+ return template.render({
+ 'body': body,
+ 'message': message_dict
+ }, engine='ir.qweb', minimal_qcontext=True)
+
class AliasMixin(models.AbstractModel):
""" A mixin for models that inherits mail.alias. This mixin initializes the
@@ -255,20 +288,12 @@ class AliasMixin(models.AbstractModel):
author = self.env['res.partner'].browse(message_dict.get('author_id', False))
if alias.alias_contact == 'followers':
if not record.ids:
- return {
- 'error_message': _('incorrectly configured alias (unknown reference record)'),
- }
+ return _('incorrectly configured alias (unknown reference record)')
if not hasattr(record, "message_partner_ids") or not hasattr(record, "message_channel_ids"):
- return {
- 'error_message': _('incorrectly configured alias'),
- }
+ return _('incorrectly configured alias')
accepted_partner_ids = record.message_partner_ids | record.message_channel_ids.mapped('channel_partner_ids')
if not author or author not in accepted_partner_ids:
- return {
- 'error_message': _('restricted to followers'),
- }
+ return _('restricted to followers')
elif alias.alias_contact == 'partners' and not author:
- return {
- 'error_message': _('restricted to known authors')
- }
+ return _('restricted to known authors')
return True
diff --git a/addons/mail/models/mail_channel.py b/addons/mail/models/mail_channel.py
index 72779279b68..04642b70126 100644
--- a/addons/mail/models/mail_channel.py
+++ b/addons/mail/models/mail_channel.py
@@ -383,9 +383,7 @@ class Channel(models.Model):
if alias.alias_contact == 'followers' and self.ids:
author = self.env['res.partner'].browse(message_dict.get('author_id', False))
if not author or author not in self.channel_partner_ids:
- return {
- 'error_message': _('restricted to channel members'),
- }
+ return _('restricted to channel members')
return True
return super(Channel, self)._alias_check_contact(message, message_dict, alias)
diff --git a/addons/mail/models/mail_thread.py b/addons/mail/models/mail_thread.py
index 748cf08ec71..90aebbff672 100644
--- a/addons/mail/models/mail_thread.py
+++ b/addons/mail/models/mail_thread.py
@@ -30,7 +30,7 @@ from odoo import _, api, exceptions, fields, models, tools, registry, SUPERUSER_
from odoo.exceptions import MissingError
from odoo.osv import expression
-from odoo.tools import pycompat, ustr
+from odoo.tools import ustr
from odoo.tools.misc import clean_context, split_every
_logger = logging.getLogger(__name__)
@@ -820,7 +820,6 @@ class MailThread(models.AbstractModel):
fallback on a message_new by resetting thread_id
2 - check that message_update exists if thread_id is set; or at least
that message_new exist
- [ - find author_id if udpate_author is set]
3 - if there is an alias, check alias_contact:
'followers' and thread_id:
check on target document that the author is in the followers
@@ -848,12 +847,6 @@ class MailThread(models.AbstractModel):
model, thread_id, alias = route[0], route[1], route[4]
record_set = None
- _generic_bounce_body_html = """<div>
-<p>Hello,</p>
-<p>The following email sent to %s cannot be accepted because this is a private email address.
- Only allowed people can contact us at this address.</p>
-</div><blockquote>%s</blockquote>""" % (message_dict.get('to'), message_dict.get('body'))
-
# Wrong model
if not model:
self._routing_warn(_('target model unspecified'), message_id, route, raise_exception)
@@ -877,7 +870,7 @@ class MailThread(models.AbstractModel):
self._routing_warn(_('model %s does not accept document creation') % model, message_id, route, raise_exception)
return ()
- # Update message author if asked. We do it now because we need it for aliases (contact settings)
+ # Update message author. We do it now because we need it for aliases (contact settings)
if not author_id:
if record_set:
authors = self._mail_find_partner_from_emails([email_from], records=record_set)
@@ -898,12 +891,13 @@ class MailThread(models.AbstractModel):
else:
obj = self.env[model]
if hasattr(obj, '_alias_check_contact'):
- check_result = obj._alias_check_contact(message, message_dict, alias)
+ error_code = obj._alias_check_contact(message, message_dict, alias)
else:
- check_result = self.env['mail.alias.mixin']._alias_check_contact_on_record(obj, message, message_dict, alias)
- if check_result is not True:
- self._routing_warn(_('alias %s: %s') % (alias.alias_name, check_result.get('error_message', _('unknown error'))), message_id, route, False)
- self._routing_create_bounce_email(email_from, check_result.get('error_template', _generic_bounce_body_html), message)
+ error_code = self.env['mail.alias.mixin']._alias_check_contact_on_record(obj, message, message_dict, alias)
+ if error_code is not True:
+ self._routing_warn(_('alias %s: %s') % (alias.alias_name, error_code or _('unknown error')), message_id, route, False)
+ body = alias._get_alias_bounced_body(message_dict)
+ self._routing_create_bounce_email(email_from, body, message, references=message_id)
return False
return (model, thread_id, route[2], route[3], route[4])
@@ -1055,7 +1049,7 @@ class MailThread(models.AbstractModel):
body = self.env.ref('mail.mail_bounce_catchall').render({
'message': message,
}, engine='ir.qweb')
- self._routing_create_bounce_email(email_from, body, message, reply_to=self.env.company.email)
+ 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)])