new changes to squash after review:

- fix misspellings errors in documentation
- add unit test to avoid github checkers red status in codecov tests.
- add validation of email from and domain whitelist fields.
- update documentation remove roadmap for already updated functionalities.
- update translations
This commit is contained in:
Katherine Zaoral 2020-09-04 17:45:56 -03:00 committed by Maksym Yankin
parent 7a9fcb44e3
commit 201e35d24e
9 changed files with 132 additions and 67 deletions

View File

@ -31,17 +31,17 @@ being appended into the proper Sender header instead. To accomplish this we:
* Add a domain whitelist field in the mail server model. This one represent an * Add a domain whitelist field in the mail server model. This one represent an
allowed Domains list separated by commas. If there is not given SMTP server allowed Domains list separated by commas. If there is not given SMTP server
it will let us to search the proper mail server to be used to sent themessages it will let us to search the proper mail server to be used to send the messages
where the message 'From' email domain match with the domain whitelist. If where the message 'From' email domain match with the domain whitelist. If
there is not mail sever that match then will use the default mail server to there is not mail server that matches then will use the default mail server to
sent the message. send the message.
* Add a Email From field that will let us to email from a specific address taking * Add a Email From field that will let us to email from a specific address taking
into account this conditions: into account this conditions:
1) If the sender domain match with the domain whitelist then the original 1) If the sender domain match with the domain whitelist then the original
message's 'From' will remain as it is and will not be changed because the message's 'From' will remain as it is and will not be changed because the
mail server is able to sent in the name of the sender domain. mail server is able to send in the name of the sender domain.
2) If the original message's 'From' does not match with the domain whitelist 2) If the original message's 'From' does not match with the domain whitelist
then the email From is replaced with the Email From field value. then the email From is replaced with the Email From field value.
@ -62,12 +62,6 @@ Usage
* Set the `Email From` option to an email address * Set the `Email From` option to an email address
* Set the `Domain Whitelist` option with the domain whitelist * Set the `Domain Whitelist` option with the domain whitelist
Known issues / Roadmap
======================
* Add validation of smtp_from field to ensure that is a valid email address
* Add validation of domain_whitelist field to ensure that they are valid domains
Bug Tracker Bug Tracker
=========== ===========

View File

@ -15,6 +15,16 @@ msgstr ""
"Content-Transfer-Encoding: \n" "Content-Transfer-Encoding: \n"
"Plural-Forms: \n" "Plural-Forms: \n"
#. module: mail_outbound_static
#: code:addons/mail_outbound_static/models/ir_mail_server.py:0
#, python-format
msgid ""
"%s is not a valid domain. Please define a list of valid domains separated by"
" comma"
msgstr ""
"%s no es un dominio válido. Por favor defina una lista de dominios validos separados por"
" comas"
#. module: mail_outbound_static #. module: mail_outbound_static
#: model:ir.model.fields,help:mail_outbound_static.field_ir_mail_server__domain_whitelist #: model:ir.model.fields,help:mail_outbound_static.field_ir_mail_server__domain_whitelist
msgid "" msgid ""
@ -23,10 +33,10 @@ msgid ""
"messages where the message 'From' email domain match with the domain " "messages where the message 'From' email domain match with the domain "
"whitelist." "whitelist."
msgstr "" msgstr ""
"Lista de dominios permitidos separados por comas. Si no se ha seleccionado un servidor SMTP " "Lista de dominios permitidos separados por comas. Si no se ha seleccionado "
"nos permitirá seleccionar el servidor de mail apropiado para enviar los " "un servidor SMTP nos permitirá seleccionar el servidor de mail apropiado "
"mensajes donde el dominio del email del 'De' coincida con la lista blanca " "para enviar los mensajes donde el dominio del email del 'De' coincida con la"
"de dominios." " lista blanca de dominios."
#. module: mail_outbound_static #. module: mail_outbound_static
#: model:ir.model.fields,field_description:mail_outbound_static.field_ir_mail_server__domain_whitelist #: model:ir.model.fields,field_description:mail_outbound_static.field_ir_mail_server__domain_whitelist
@ -46,8 +56,8 @@ msgstr "Servidor de correo"
#. module: mail_outbound_static #. module: mail_outbound_static
#: code:addons/mail_outbound_static/models/ir_mail_server.py:0 #: code:addons/mail_outbound_static/models/ir_mail_server.py:0
#, python-format #, python-format
msgid "Please define a list of domains separate by comma" msgid "Not a valid Email From"
msgstr "Por favor defina una lista de dominios separados por coma" msgstr "No es un Email De válido"
#. module: mail_outbound_static #. module: mail_outbound_static
#: model:ir.model.fields,help:mail_outbound_static.field_ir_mail_server__smtp_from #: model:ir.model.fields,help:mail_outbound_static.field_ir_mail_server__smtp_from
@ -57,7 +67,7 @@ msgid ""
"replaced with this value. If does match with the domain whitelist then the " "replaced with this value. If does match with the domain whitelist then the "
"original message's 'From' will not change" "original message's 'From' will not change"
msgstr "" msgstr ""
"Definalo para usar un dirección de correo 'De' especifica. Si el 'De' del mensaje " "Definalo para usar un dirección de correo 'De' especifica. Si el 'De' del "
"original no coincide con la lista blanca de dominios entonces este será " "mensaje original no coincide con la lista blanca de dominios entonces este "
"remplazado con este valor. Si coincide con la lista blanca de dominios entonces " "será remplazado con este valor. Si coincide con la lista blanca de dominios "
"el 'De' del mensajee original no cambiará" "entonces el 'De' del mensajee original no cambiará"

View File

@ -20,6 +20,14 @@ msgstr ""
msgid "Display Name" msgid "Display Name"
msgstr "" msgstr ""
#: code:addons/mail_outbound_static/models/ir_mail_server.py:0
#, python-format
msgid ""
"%s is not a valid domain. Please define a list of valid domains separated by"
" comma"
msgstr ""
#. module: mail_outbound_static
#: model:ir.model.fields,help:mail_outbound_static.field_ir_mail_server__domain_whitelist #: model:ir.model.fields,help:mail_outbound_static.field_ir_mail_server__domain_whitelist
msgid "" msgid ""
"Allowed Domains list separated by commas. If there is not given SMTP server " "Allowed Domains list separated by commas. If there is not given SMTP server "
@ -56,7 +64,7 @@ msgstr ""
#. module: mail_outbound_static #. module: mail_outbound_static
#: code:addons/mail_outbound_static/models/ir_mail_server.py:0 #: code:addons/mail_outbound_static/models/ir_mail_server.py:0
#, python-format #, python-format
msgid "Please define a list of domains separate by comma" msgid "Not a valid Email From"
msgstr "" msgstr ""
#. module: mail_outbound_static #. module: mail_outbound_static

View File

@ -1,6 +1,7 @@
# Copyright 2017 LasLabs Inc. # Copyright 2017 LasLabs Inc.
# License LGPL-3.0 or later (http://www.gnu.org/licenses/lgpl.html). # License LGPL-3.0 or later (http://www.gnu.org/licenses/lgpl.html).
import re
from email.utils import formataddr, parseaddr from email.utils import formataddr, parseaddr
from odoo import _, api, fields, models, tools from odoo import _, api, fields, models, tools
@ -28,16 +29,37 @@ class IrMailServer(models.Model):
@api.constrains("domain_whitelist") @api.constrains("domain_whitelist")
def check_valid_domain_whitelist(self): def check_valid_domain_whitelist(self):
if self.domain_whitelist: if self.domain_whitelist:
values = False domains = list(self.domain_whitelist.split(","))
try: for domain in domains:
values = list(self.domain_whitelist.split(",")) if not self._is_valid_domain(domain):
except Exception: raise ValidationError(
pass _(
"%s is not a valid domain. Please define a list of"
" valid domains separated by comma"
)
% (domain)
)
if not isinstance(values, list): @api.constrains("smtp_from")
raise ValidationError( def check_valid_smtp_from(self):
_("Please define a list of domains separate by comma") if self.smtp_from:
) match = re.match(
r"^[_a-z0-9-]+(\.[_a-z0-9-]+)*@[a-z0-9-]+(\.[a-z0-9-]+)*(\."
r"[a-z]{2,4})$",
self.smtp_from,
)
if match is None:
raise ValidationError(_("Not a valid Email From"))
def _is_valid_domain(self, domain_name):
domain_regex = (
r"(([\da-zA-Z])([_\w-]{,62})\.){,127}(([\da-zA-Z])"
r"[_\w-]{,61})?([\da-zA-Z]\.((xn\-\-[a-zA-Z\d]+)|([a-zA-Z\d]{2,})))"
)
domain_regex = "{}$".format(domain_regex)
valid_domain_name_regex = re.compile(domain_regex, re.IGNORECASE)
domain_name = domain_name.lower().strip()
return True if re.match(valid_domain_name_regex, domain_name) else False
@api.model @api.model
def _get_domain_whitelist(self, domain_whitelist_string): def _get_domain_whitelist(self, domain_whitelist_string):

View File

@ -4,17 +4,17 @@ being appended into the proper Sender header instead. To accomplish this we:
* Add a domain whitelist field in the mail server model. This one represent an * Add a domain whitelist field in the mail server model. This one represent an
allowed Domains list separated by commas. If there is not given SMTP server allowed Domains list separated by commas. If there is not given SMTP server
it will let us to search the proper mail server to be used to sent themessages it will let us to search the proper mail server to be used to send the messages
where the message 'From' email domain match with the domain whitelist. If where the message 'From' email domain match with the domain whitelist. If
there is not mail sever that match then will use the default mail server to there is not mail server that matches then will use the default mail server to
sent the message. send the message.
* Add a Email From field that will let us to email from a specific address taking * Add a Email From field that will let us to email from a specific address taking
into account this conditions: into account this conditions:
1) If the sender domain match with the domain whitelist then the original 1) If the sender domain match with the domain whitelist then the original
message's 'From' will remain as it is and will not be changed because the message's 'From' will remain as it is and will not be changed because the
mail server is able to sent in the name of the sender domain. mail server is able to send in the name of the sender domain.
2) If the original message's 'From' does not match with the domain whitelist 2) If the original message's 'From' does not match with the domain whitelist
then the email From is replaced with the Email From field value. then the email From is replaced with the Email From field value.

View File

@ -1,2 +0,0 @@
* Add validation of smtp_from field to ensure that is a valid email address
* Add validation of domain_whitelist field to ensure that they are valid domains

View File

@ -374,15 +374,15 @@ being appended into the proper Sender header instead. To accomplish this we:</p>
<ul class="simple"> <ul class="simple">
<li>Add a domain whitelist field in the mail server model. This one represent an <li>Add a domain whitelist field in the mail server model. This one represent an
allowed Domains list separated by commas. If there is not given SMTP server allowed Domains list separated by commas. If there is not given SMTP server
it will let us to search the proper mail server to be used to sent themessages it will let us to search the proper mail server to be used to send the messages
where the message From email domain match with the domain whitelist. If where the message From email domain match with the domain whitelist. If
there is not mail sever that match then will use the default mail server to there is not mail server that matches then will use the default mail server to
sent the message.</li> send the message.</li>
<li>Add a Email From field that will let us to email from a specific address taking <li>Add a Email From field that will let us to email from a specific address taking
into account this conditions:<ol class="arabic"> into account this conditions:<ol class="arabic">
<li>If the sender domain match with the domain whitelist then the original <li>If the sender domain match with the domain whitelist then the original
messages From will remain as it is and will not be changed because the messages From will remain as it is and will not be changed because the
mail server is able to sent in the name of the sender domain.</li> mail server is able to send in the name of the sender domain.</li>
<li>If the original messages From does not match with the domain whitelist <li>If the original messages From does not match with the domain whitelist
then the email From is replaced with the Email From field value.</li> then the email From is replaced with the Email From field value.</li>
</ol> </ol>
@ -395,12 +395,11 @@ server configured in the system.</li>
<div class="contents local topic" id="contents"> <div class="contents local topic" id="contents">
<ul class="simple"> <ul class="simple">
<li><a class="reference internal" href="#usage" id="id1">Usage</a></li> <li><a class="reference internal" href="#usage" id="id1">Usage</a></li>
<li><a class="reference internal" href="#known-issues-roadmap" id="id2">Known issues / Roadmap</a></li> <li><a class="reference internal" href="#bug-tracker" id="id2">Bug Tracker</a></li>
<li><a class="reference internal" href="#bug-tracker" id="id3">Bug Tracker</a></li> <li><a class="reference internal" href="#credits" id="id3">Credits</a><ul>
<li><a class="reference internal" href="#credits" id="id4">Credits</a><ul> <li><a class="reference internal" href="#authors" id="id4">Authors</a></li>
<li><a class="reference internal" href="#authors" id="id5">Authors</a></li> <li><a class="reference internal" href="#contributors" id="id5">Contributors</a></li>
<li><a class="reference internal" href="#contributors" id="id6">Contributors</a></li> <li><a class="reference internal" href="#maintainers" id="id6">Maintainers</a></li>
<li><a class="reference internal" href="#maintainers" id="id7">Maintainers</a></li>
</ul> </ul>
</li> </li>
</ul> </ul>
@ -413,15 +412,8 @@ server configured in the system.</li>
<li>Set the <cite>Domain Whitelist</cite> option with the domain whitelist</li> <li>Set the <cite>Domain Whitelist</cite> option with the domain whitelist</li>
</ul> </ul>
</div> </div>
<div class="section" id="known-issues-roadmap">
<h1><a class="toc-backref" href="#id2">Known issues / Roadmap</a></h1>
<ul class="simple">
<li>Add validation of smtp_from field to ensure that is a valid email address</li>
<li>Add validation of domain_whitelist field to ensure that they are valid domains</li>
</ul>
</div>
<div class="section" id="bug-tracker"> <div class="section" id="bug-tracker">
<h1><a class="toc-backref" href="#id3">Bug Tracker</a></h1> <h1><a class="toc-backref" href="#id2">Bug Tracker</a></h1>
<p>Bugs are tracked on <a class="reference external" href="https://github.com/OCA/social/issues">GitHub Issues</a>. <p>Bugs are tracked on <a class="reference external" href="https://github.com/OCA/social/issues">GitHub Issues</a>.
In case of trouble, please check there if your issue has already been reported. In case of trouble, please check there if your issue has already been reported.
If you spotted it first, help us smashing it by providing a detailed and welcomed If you spotted it first, help us smashing it by providing a detailed and welcomed
@ -429,9 +421,9 @@ If you spotted it first, help us smashing it by providing a detailed and welcome
<p>Do not contact contributors directly about support or help with technical issues.</p> <p>Do not contact contributors directly about support or help with technical issues.</p>
</div> </div>
<div class="section" id="credits"> <div class="section" id="credits">
<h1><a class="toc-backref" href="#id4">Credits</a></h1> <h1><a class="toc-backref" href="#id3">Credits</a></h1>
<div class="section" id="authors"> <div class="section" id="authors">
<h2><a class="toc-backref" href="#id5">Authors</a></h2> <h2><a class="toc-backref" href="#id4">Authors</a></h2>
<ul class="simple"> <ul class="simple">
<li>brain-tec AG</li> <li>brain-tec AG</li>
<li>LasLabs</li> <li>LasLabs</li>
@ -439,7 +431,7 @@ If you spotted it first, help us smashing it by providing a detailed and welcome
</ul> </ul>
</div> </div>
<div class="section" id="contributors"> <div class="section" id="contributors">
<h2><a class="toc-backref" href="#id6">Contributors</a></h2> <h2><a class="toc-backref" href="#id5">Contributors</a></h2>
<ul class="simple"> <ul class="simple">
<li>Frédéric Garbely &lt;<a class="reference external" href="mailto:frederic.garbely&#64;braintec-group.com">frederic.garbely&#64;braintec-group.com</a>&gt;</li> <li>Frédéric Garbely &lt;<a class="reference external" href="mailto:frederic.garbely&#64;braintec-group.com">frederic.garbely&#64;braintec-group.com</a>&gt;</li>
<li>Dave Lasley &lt;<a class="reference external" href="mailto:dave&#64;laslabs.com">dave&#64;laslabs.com</a>&gt;</li> <li>Dave Lasley &lt;<a class="reference external" href="mailto:dave&#64;laslabs.com">dave&#64;laslabs.com</a>&gt;</li>
@ -450,7 +442,7 @@ If you spotted it first, help us smashing it by providing a detailed and welcome
</ul> </ul>
</div> </div>
<div class="section" id="maintainers"> <div class="section" id="maintainers">
<h2><a class="toc-backref" href="#id7">Maintainers</a></h2> <h2><a class="toc-backref" href="#id6">Maintainers</a></h2>
<p>This module is maintained by the OCA.</p> <p>This module is maintained by the OCA.</p>
<a class="reference external image-reference" href="https://odoo-community.org"><img alt="Odoo Community Association" src="https://odoo-community.org/logo.png" /></a> <a class="reference external image-reference" href="https://odoo-community.org"><img alt="Odoo Community Association" src="https://odoo-community.org/logo.png" /></a>
<p>OCA, or the Odoo Community Association, is a nonprofit organization whose <p>OCA, or the Odoo Community Association, is a nonprofit organization whose

View File

@ -9,6 +9,7 @@ from email import message_from_string
from mock import MagicMock from mock import MagicMock
import odoo.tools as tools import odoo.tools as tools
from odoo.exceptions import ValidationError
from odoo.tests.common import TransactionCase from odoo.tests.common import TransactionCase
_logger = logging.getLogger(__name__) _logger = logging.getLogger(__name__)
@ -118,7 +119,7 @@ class TestIrMailServer(TransactionCase):
message["Return-Path"], '"{}" <{}>'.format(user, self.email_from) message["Return-Path"], '"{}" <{}>'.format(user, self.email_from)
) )
def test_1_from_outgoing_server_domainone(self): def test_01_from_outgoing_server_domainone(self):
self._init_mail_server_domain_whilelist_based() self._init_mail_server_domain_whilelist_based()
domain = "domainone.com" domain = "domainone.com"
email_from = "Mitchell Admin <admin@%s>" % domain email_from = "Mitchell Admin <admin@%s>" % domain
@ -137,7 +138,7 @@ class TestIrMailServer(TransactionCase):
% (used_mail_server.name, expected_mail_server.name), % (used_mail_server.name, expected_mail_server.name),
) )
def test_2_from_outgoing_server_domaintwo(self): def test_02_from_outgoing_server_domaintwo(self):
self._init_mail_server_domain_whilelist_based() self._init_mail_server_domain_whilelist_based()
domain = "domaintwo.com" domain = "domaintwo.com"
email_from = "Mitchell Admin <admin@%s>" % domain email_from = "Mitchell Admin <admin@%s>" % domain
@ -156,7 +157,7 @@ class TestIrMailServer(TransactionCase):
% (used_mail_server.name, expected_mail_server.name), % (used_mail_server.name, expected_mail_server.name),
) )
def test_3_from_outgoing_server_another(self): def test_03_from_outgoing_server_another(self):
self._init_mail_server_domain_whilelist_based() self._init_mail_server_domain_whilelist_based()
domain = "example.com" domain = "example.com"
email_from = "Mitchell Admin <admin@%s>" % domain email_from = "Mitchell Admin <admin@%s>" % domain
@ -177,7 +178,7 @@ class TestIrMailServer(TransactionCase):
% (used_mail_server.name, expected_mail_server.name), % (used_mail_server.name, expected_mail_server.name),
) )
def test_4_from_outgoing_server_none_use_config(self): def test_04_from_outgoing_server_none_use_config(self):
self._init_mail_server_domain_whilelist_based() self._init_mail_server_domain_whilelist_based()
domain = "example.com" domain = "example.com"
email_from = "Mitchell Admin <admin@%s>" % domain email_from = "Mitchell Admin <admin@%s>" % domain
@ -203,7 +204,7 @@ class TestIrMailServer(TransactionCase):
used_mail_server, "using this mail server %s" % (used_mail_server.name) used_mail_server, "using this mail server %s" % (used_mail_server.name)
) )
def test_5_from_outgoing_server_none_same_domain(self): def test_05_from_outgoing_server_none_same_domain(self):
self._init_mail_server_domain_whilelist_based() self._init_mail_server_domain_whilelist_based()
# Find config values # Find config values
@ -229,7 +230,7 @@ class TestIrMailServer(TransactionCase):
used_mail_server = self.Model.browse(used_mail_server) used_mail_server = self.Model.browse(used_mail_server)
self.assertFalse(used_mail_server) self.assertFalse(used_mail_server)
def test_6_from_outgoing_server_no_name_from(self): def test_06_from_outgoing_server_no_name_from(self):
self._init_mail_server_domain_whilelist_based() self._init_mail_server_domain_whilelist_based()
domain = "example.com" domain = "example.com"
email_from = "test@%s" % domain email_from = "test@%s" % domain
@ -248,7 +249,7 @@ class TestIrMailServer(TransactionCase):
% (used_mail_server.name, expected_mail_server.name), % (used_mail_server.name, expected_mail_server.name),
) )
def test_7_from_outgoing_server_multidomain_1(self): def test_07_from_outgoing_server_multidomain_1(self):
self._init_mail_server_domain_whilelist_based() self._init_mail_server_domain_whilelist_based()
domain = "domainthree.com" domain = "domainthree.com"
email_from = "Mitchell Admin <admin@%s>" % domain email_from = "Mitchell Admin <admin@%s>" % domain
@ -267,7 +268,7 @@ class TestIrMailServer(TransactionCase):
% (used_mail_server.name, expected_mail_server.name), % (used_mail_server.name, expected_mail_server.name),
) )
def test_8_from_outgoing_server_multidomain_3(self): def test_08_from_outgoing_server_multidomain_3(self):
self._init_mail_server_domain_whilelist_based() self._init_mail_server_domain_whilelist_based()
domain = "domainmulti.com" domain = "domainmulti.com"
email_from = "test@%s" % domain email_from = "test@%s" % domain
@ -285,3 +286,43 @@ class TestIrMailServer(TransactionCase):
"It using %s but we expect to use %s" "It using %s but we expect to use %s"
% (used_mail_server.name, expected_mail_server.name), % (used_mail_server.name, expected_mail_server.name),
) )
def test_09_not_valid_domain_whitelist(self):
self._init_mail_server_domain_whilelist_based()
mail_server = self.mail_server_domainone
mail_server.domain_whitelist = "example.com"
error_msg = (
"%s is not a valid domain. Please define a list of valid"
" domains separated by comma"
)
with self.assertRaisesRegex(ValidationError, error_msg % "asdasd"):
mail_server.domain_whitelist = "asdasd"
with self.assertRaisesRegex(ValidationError, error_msg % "asdasd"):
mail_server.domain_whitelist = "example.com, asdasd"
with self.assertRaisesRegex(ValidationError, error_msg % "invalid"):
mail_server.domain_whitelist = "example.com; invalid"
with self.assertRaisesRegex(ValidationError, error_msg % ";"):
mail_server.domain_whitelist = ";"
with self.assertRaisesRegex(ValidationError, error_msg % "."):
mail_server.domain_whitelist = "hola.com,."
def test_10_not_valid_smtp_from(self):
self._init_mail_server_domain_whilelist_based()
mail_server = self.mail_server_domainone
error_msg = "Not a valid Email From"
with self.assertRaisesRegex(ValidationError, error_msg):
mail_server.smtp_from = "asdasd"
with self.assertRaisesRegex(ValidationError, error_msg):
mail_server.smtp_from = "example.com"
with self.assertRaisesRegex(ValidationError, error_msg):
mail_server.smtp_from = "."
mail_server.smtp_from = "notifications@test.com"

View File

@ -12,7 +12,7 @@
<field name="arch" type="xml"> <field name="arch" type="xml">
<xpath expr="//field[@name='smtp_pass']" position="after"> <xpath expr="//field[@name='smtp_pass']" position="after">
<field name="domain_whitelist"/> <field name="domain_whitelist"/>
<field name="smtp_from" /> <field name="smtp_from" widget="email"/>
</xpath> </xpath>
</field> </field>
</record> </record>