[IMP] tools, mail : adds email normalization method in mail tools
In order to normalize email independently from the mail.address.mixin model.
This commit is contained in:
@@ -31,16 +31,7 @@ class MailAddressMixin(models.AbstractModel):
|
||||
self._assert_primary_email()
|
||||
[email_field] = self._primary_email
|
||||
for record in self:
|
||||
record.email_normalized = self._normalize_email(record[email_field])
|
||||
|
||||
def _normalize_email(self, email):
|
||||
""" Sanitize and standardize email address entries: all emails should be
|
||||
only real email extracted from strings (A <a@a> -> a@a) and should be
|
||||
lower case. """
|
||||
emails = tools.email_split(email)
|
||||
if not emails or len(emails) != 1:
|
||||
return False
|
||||
return emails[0].lower()
|
||||
record.email_normalized = tools.email_normalize(record[email_field])
|
||||
|
||||
def _assert_primary_email(self):
|
||||
if not hasattr(self, "_primary_email") or \
|
||||
|
||||
@@ -30,7 +30,7 @@ class MailBlackList(models.Model):
|
||||
new_values = []
|
||||
all_emails = []
|
||||
for value in values:
|
||||
email = self._normalize_email(value.get('email'))
|
||||
email = tools.email_normalize(value.get('email'))
|
||||
if not email:
|
||||
raise UserError(_('Invalid email address %r') % value['email'])
|
||||
if email in all_emails:
|
||||
@@ -53,7 +53,7 @@ class MailBlackList(models.Model):
|
||||
@api.multi
|
||||
def write(self, values):
|
||||
if 'email' in values:
|
||||
values['email'] = self._normalize_email(values['email'])
|
||||
values['email'] = tools.email_normalize(values['email'])
|
||||
return super(MailBlackList, self).write(values)
|
||||
|
||||
def _search(self, args, offset=0, limit=None, order=None, count=False, access_rights_uid=None):
|
||||
@@ -63,7 +63,7 @@ class MailBlackList(models.Model):
|
||||
new_args = []
|
||||
for arg in args:
|
||||
if isinstance(arg, (list, tuple)) and arg[0] == 'email' and isinstance(arg[2], tools.pycompat.text_type):
|
||||
normalized = self._normalize_email(arg[2])
|
||||
normalized = tools.email_normalize(arg[2])
|
||||
if normalized:
|
||||
new_args.append([arg[0], arg[1], normalized])
|
||||
else:
|
||||
@@ -75,7 +75,7 @@ class MailBlackList(models.Model):
|
||||
return super(MailBlackList, self)._search(new_args, offset=offset, limit=limit, order=order, count=count, access_rights_uid=access_rights_uid)
|
||||
|
||||
def _add(self, email):
|
||||
normalized = self._normalize_email(email)
|
||||
normalized = tools.email_normalize(email)
|
||||
record = self.env["mail.blacklist"].with_context(active_test=False).search([('email', '=', normalized)])
|
||||
if len(record) > 0:
|
||||
record.write({'active': True})
|
||||
@@ -84,7 +84,7 @@ class MailBlackList(models.Model):
|
||||
return record
|
||||
|
||||
def _remove(self, email):
|
||||
normalized = self._normalize_email(email)
|
||||
normalized = tools.email_normalize(email)
|
||||
record = self.env["mail.blacklist"].with_context(active_test=False).search([('email', '=', normalized)])
|
||||
if len(record) > 0:
|
||||
record.write({'active': False})
|
||||
@@ -92,15 +92,6 @@ class MailBlackList(models.Model):
|
||||
record = record.create({'email': email, 'active': False})
|
||||
return record
|
||||
|
||||
def _normalize_email(self, email):
|
||||
""" Sanitize and standardize email address entries: all emails should be
|
||||
only real email extracted from strings (A <a@a> -> a@a) and should be
|
||||
lower case. """
|
||||
emails = tools.email_split(email)
|
||||
if not emails or len(emails) != 1:
|
||||
return False
|
||||
return emails[0].lower()
|
||||
|
||||
|
||||
class MailBlackListMixin(models.AbstractModel):
|
||||
""" Mixin that is inherited by all model with opt out.
|
||||
|
||||
@@ -4,7 +4,7 @@ import base64
|
||||
|
||||
import werkzeug
|
||||
|
||||
from odoo import _, exceptions, http
|
||||
from odoo import _, exceptions, http, tools
|
||||
from odoo.http import request
|
||||
from odoo.tools import consteq
|
||||
|
||||
@@ -39,7 +39,7 @@ class MassMailController(http.Controller):
|
||||
# Unsubscribe directly + Let the user choose his subscriptions
|
||||
mailing.update_opt_out(email, mailing.contact_list_ids.ids, True)
|
||||
|
||||
contacts = request.env['mail.mass_mailing.contact'].sudo().search([('email_normalized', '=', email)])
|
||||
contacts = request.env['mail.mass_mailing.contact'].sudo().search([('email_normalized', '=', tools.email_normalize(email))])
|
||||
subscription_list_ids = contacts.mapped('subscription_list_ids')
|
||||
# In many user are found : if user is opt_out on the list with contact_id 1 but not with contact_id 2,
|
||||
# assume that the user is not opt_out on both
|
||||
@@ -115,7 +115,7 @@ class MassMailController(http.Controller):
|
||||
if not self._valid_unsubscribe_token(mailing_id, res_id, email, token):
|
||||
return 'unauthorized'
|
||||
if email:
|
||||
record = request.env['mail.blacklist'].sudo().with_context(active_test=False).search([('email', '=', email)])
|
||||
record = request.env['mail.blacklist'].sudo().with_context(active_test=False).search([('email', '=', tools.email_normalize(email))])
|
||||
if record['active']:
|
||||
return True
|
||||
return False
|
||||
@@ -152,7 +152,7 @@ class MassMailController(http.Controller):
|
||||
if not self._valid_unsubscribe_token(mailing_id, res_id, email, token):
|
||||
return 'unauthorized'
|
||||
model = request.env[mailing.mailing_model_real]
|
||||
records = model.sudo().search([('email_normalized', '=', email)])
|
||||
records = model.sudo().search([('email_normalized', '=', tools.email_normalize(email))])
|
||||
for record in records:
|
||||
record.sudo().message_post(body=_("Feedback from %s: %s" % (email, feedback)))
|
||||
return bool(records)
|
||||
|
||||
@@ -230,7 +230,7 @@ class MassMailingContact(models.Model):
|
||||
@api.depends('email')
|
||||
def _compute_is_email_valid(self):
|
||||
for record in self:
|
||||
normalized = self._normalize_email(record.email)
|
||||
normalized = tools.email_normalize(record.email)
|
||||
record.is_email_valid = normalized if not normalized else True
|
||||
|
||||
@api.model
|
||||
@@ -646,7 +646,7 @@ class MassMailing(models.Model):
|
||||
def update_opt_out(self, email, list_ids, value):
|
||||
if len(list_ids) > 0:
|
||||
model = self.env['mail.mass_mailing.contact'].with_context(active_test=False)
|
||||
records = model.search([('email_normalized', '=', email)])
|
||||
records = model.search([('email_normalized', '=', tools.email_normalize(email))])
|
||||
opt_out_records = self.env['mail.mass_mailing.list_contact_rel'].search([
|
||||
('contact_id', 'in', records.ids),
|
||||
('list_id', 'in', list_ids),
|
||||
|
||||
@@ -502,6 +502,21 @@ def email_split_and_format(text):
|
||||
if addr[1]
|
||||
if '@' in addr[1]]
|
||||
|
||||
def email_normalize(text):
|
||||
""" Sanitize and standardize email address entries.
|
||||
A normalized email is considered as :
|
||||
- having a left part + @ + a right part (the domain can be without '.something')
|
||||
- being lower case
|
||||
- having no name before the address. Typically, having no 'Name <>'
|
||||
Ex:
|
||||
- Possible Input Email : 'Name <NaMe@DoMaIn.CoM>'
|
||||
- Normalized Output Email : 'name@domain.com'
|
||||
"""
|
||||
emails = email_split(text)
|
||||
if not emails or len(emails) != 1:
|
||||
return False
|
||||
return emails[0].lower()
|
||||
|
||||
def email_escape_char(email_address):
|
||||
""" Escape problematic characters in the given email address string"""
|
||||
return email_address.replace('\\', '\\\\').replace('%', '\\%').replace('_', '\\_')
|
||||
|
||||
Reference in New Issue
Block a user