5 changed files with 290 additions and 0 deletions
-
26partner_email_validation/__init__.py
-
62partner_email_validation/__openerp__.py
-
117partner_email_validation/partner.py
-
29partner_email_validation/tests/__init__.py
-
56partner_email_validation/tests/test_email_validate.py
@ -0,0 +1,26 @@ |
|||||
|
# -*- encoding: utf-8 -*- |
||||
|
############################################################################## |
||||
|
# |
||||
|
# OpenERP, Open Source Management Solution |
||||
|
# This module copyright (C) 2015 Savoir-faire Linux |
||||
|
# (<http://www.savoirfairelinux.com>). |
||||
|
# |
||||
|
# This program is free software: you can redistribute it and/or modify |
||||
|
# it under the terms of the GNU Affero General Public License as |
||||
|
# published by the Free Software Foundation, either version 3 of the |
||||
|
# License, or (at your option) any later version. |
||||
|
# |
||||
|
# This program is distributed in the hope that it will be useful, |
||||
|
# but WITHOUT ANY WARRANTY; without even the implied warranty of |
||||
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
||||
|
# GNU Affero General Public License for more details. |
||||
|
# |
||||
|
# You should have received a copy of the GNU Affero General Public License |
||||
|
# along with this program. If not, see <http://www.gnu.org/licenses/>. |
||||
|
# |
||||
|
############################################################################## |
||||
|
|
||||
|
from . import ( |
||||
|
partner, |
||||
|
tests, |
||||
|
) |
@ -0,0 +1,62 @@ |
|||||
|
# -*- encoding: utf-8 -*- |
||||
|
############################################################################## |
||||
|
# |
||||
|
# OpenERP, Open Source Management Solution |
||||
|
# This module copyright (C) 2015 Savoir-faire Linux |
||||
|
# (<http://www.savoirfairelinux.com>). |
||||
|
# |
||||
|
# This program is free software: you can redistribute it and/or modify |
||||
|
# it under the terms of the GNU Affero General Public License as |
||||
|
# published by the Free Software Foundation, either version 3 of the |
||||
|
# License, or (at your option) any later version. |
||||
|
# |
||||
|
# This program is distributed in the hope that it will be useful, |
||||
|
# but WITHOUT ANY WARRANTY; without even the implied warranty of |
||||
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
||||
|
# GNU Affero General Public License for more details. |
||||
|
# |
||||
|
# You should have received a copy of the GNU Affero General Public License |
||||
|
# along with this program. If not, see <http://www.gnu.org/licenses/>. |
||||
|
# |
||||
|
############################################################################## |
||||
|
|
||||
|
{ |
||||
|
'name': 'Partner Email Validation', |
||||
|
'version': '1.0', |
||||
|
'author': 'Savoir-faire Linux', |
||||
|
'maintainer': 'Savoir-faire Linux', |
||||
|
'website': 'http://www.savoirfairelinux.com', |
||||
|
'license': 'AGPL-3', |
||||
|
'category': 'Customer Relationship Management', |
||||
|
'summary': 'Validate Partner Email', |
||||
|
'description': """ |
||||
|
This module performs simple validation on email addresses. Emails are |
||||
|
checked for: |
||||
|
- Having a mailbox and domain part: mailbox@domain |
||||
|
- Having a seemingly valid domain |
||||
|
- (sub.)*domain.tld where tld has at least two letters |
||||
|
- @test and @localhost |
||||
|
- Containing letters or numbers, with a few special characters: |
||||
|
- ".-_+" for mailbox part |
||||
|
- "-." for domain part |
||||
|
- Quoted mailboxes "Foo Bar"@spam.eggs are not supported as of now. |
||||
|
|
||||
|
No email is sent for validation. |
||||
|
|
||||
|
Contributors |
||||
|
------------ |
||||
|
* Vincent Vinet (vincent.vinet@savoirfairelinux.com) |
||||
|
""", |
||||
|
'depends': [ |
||||
|
'base', |
||||
|
], |
||||
|
'external_dependencies': { |
||||
|
'python': [], |
||||
|
}, |
||||
|
'data': [ |
||||
|
], |
||||
|
'demo': [], |
||||
|
'test': [], |
||||
|
'installable': True, |
||||
|
'auto_install': False, |
||||
|
} |
@ -0,0 +1,117 @@ |
|||||
|
# -*- encoding: utf-8 -*- |
||||
|
############################################################################## |
||||
|
# |
||||
|
# OpenERP, Open Source Management Solution |
||||
|
# This module copyright (C) 2015 Savoir-faire Linux |
||||
|
# (<http://www.savoirfairelinux.com>). |
||||
|
# |
||||
|
# This program is free software: you can redistribute it and/or modify |
||||
|
# it under the terms of the GNU Affero General Public License as |
||||
|
# published by the Free Software Foundation, either version 3 of the |
||||
|
# License, or (at your option) any later version. |
||||
|
# |
||||
|
# This program is distributed in the hope that it will be useful, |
||||
|
# but WITHOUT ANY WARRANTY; without even the implied warranty of |
||||
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
||||
|
# GNU Affero General Public License for more details. |
||||
|
# |
||||
|
# You should have received a copy of the GNU Affero General Public License |
||||
|
# along with this program. If not, see <http://www.gnu.org/licenses/>. |
||||
|
# |
||||
|
############################################################################## |
||||
|
|
||||
|
import logging |
||||
|
import unicodedata |
||||
|
|
||||
|
from openerp.osv import orm |
||||
|
from openerp.tools.translate import _ |
||||
|
|
||||
|
_logger = logging.getLogger(__name__) |
||||
|
|
||||
|
|
||||
|
class Partner(orm.Model): |
||||
|
_name = _inherit = 'res.partner' |
||||
|
|
||||
|
def _check_email_domain(self, domain): |
||||
|
""" Checks if a domain is valid for an email """ |
||||
|
# Allow localhost and test, those are valid domains |
||||
|
if domain in (u'localhost', u'test'): |
||||
|
return True |
||||
|
|
||||
|
domain_parts = domain.split(u".") |
||||
|
|
||||
|
# Disallow @foo @foo. @foo..com |
||||
|
if len(domain_parts) <= 1: |
||||
|
_logger.debug("Email has single domain part") |
||||
|
return False |
||||
|
|
||||
|
# Disallow @foo. @foo..com, @.b |
||||
|
for part in domain_parts: |
||||
|
if not part: |
||||
|
_logger.debug("Empty domain part") |
||||
|
return False |
||||
|
|
||||
|
# TLD must have 2 chars at least |
||||
|
if len(domain_parts[-1]) < 2: |
||||
|
_logger.debug("TLD too short") |
||||
|
return False |
||||
|
|
||||
|
# Check that we have letters, numbers, '.' or '-' |
||||
|
for letter in domain: |
||||
|
if letter in ".-": |
||||
|
continue |
||||
|
|
||||
|
cat = unicodedata.category(letter) |
||||
|
if cat[0] not in u'LN': # Letter or Number |
||||
|
_logger.debug("Character not accepted in domain: %r", |
||||
|
letter) |
||||
|
return False |
||||
|
|
||||
|
return True |
||||
|
|
||||
|
def _check_email_mailbox(self, mailbox): |
||||
|
""" Checks if a mailbox is valid for an email """ |
||||
|
for letter in mailbox: |
||||
|
if letter in ".-_+": # Few accepted symbols |
||||
|
continue |
||||
|
|
||||
|
cat = unicodedata.category(letter) |
||||
|
if cat[0] not in u'LN': # Letter or Number |
||||
|
_logger.debug("Character not accepted in mailbox: %r", |
||||
|
letter) |
||||
|
return False |
||||
|
|
||||
|
return True |
||||
|
|
||||
|
def _check_valid_email(self, email): |
||||
|
""" Checks if an email address is valid """ |
||||
|
mail, sep, domain = email.rpartition(u'@') |
||||
|
# We need a full "mail@domain" |
||||
|
if not mail or not sep or not domain: |
||||
|
_logger.debug("Mail is not mail@domain") |
||||
|
return False |
||||
|
|
||||
|
if not self._check_email_domain(domain): |
||||
|
return False |
||||
|
|
||||
|
if not self._check_email_mailbox(mail): |
||||
|
return False |
||||
|
|
||||
|
return True |
||||
|
|
||||
|
def _check_customer_email(self, cr, uid, ids, context=None): |
||||
|
for partner in self.browse(cr, uid, ids, context=None): |
||||
|
if not partner.email: |
||||
|
# The view already forces the email to be filled, do not |
||||
|
# double check or repeat conditions |
||||
|
continue |
||||
|
|
||||
|
if not self._check_valid_email(partner.email): |
||||
|
return False |
||||
|
|
||||
|
return True |
||||
|
|
||||
|
_constraints = [ |
||||
|
(_check_customer_email, |
||||
|
_('You must provide a valid email address'), ['email']), |
||||
|
] |
@ -0,0 +1,29 @@ |
|||||
|
# -*- encoding: utf-8 -*- |
||||
|
############################################################################### |
||||
|
# |
||||
|
# OpenERP, Open Source Management Solution |
||||
|
# This module copyright (C) 2015 Savoir-faire Linux |
||||
|
# (<http://www.savoirfairelinux.com>). |
||||
|
# |
||||
|
# This program is free software: you can redistribute it and/or modify |
||||
|
# it under the terms of the GNU Affero General Public License as |
||||
|
# published by the Free Software Foundation, either version 3 of the |
||||
|
# License, or (at your option) any later version. |
||||
|
# |
||||
|
# This program is distributed in the hope that it will be useful, |
||||
|
# but WITHOUT ANY WARRANTY; without even the implied warranty of |
||||
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
||||
|
# GNU Affero General Public License for more details. |
||||
|
# |
||||
|
# You should have received a copy of the GNU Affero General Public License |
||||
|
# along with this program. If not, see <http://www.gnu.org/licenses/>. |
||||
|
# |
||||
|
############################################################################### |
||||
|
|
||||
|
from . import ( |
||||
|
test_email_validate, |
||||
|
) |
||||
|
|
||||
|
checks = [ |
||||
|
test_email_validate, |
||||
|
] |
@ -0,0 +1,56 @@ |
|||||
|
# -*- coding: utf-8 -*- |
||||
|
############################################################################## |
||||
|
# |
||||
|
# OpenERP, Open Source Management Solution |
||||
|
# Copyright (C) 2014 Savoir-faire Linux (<http://www.savoirfairelinux.com>). |
||||
|
# |
||||
|
# This program is free software: you can redistribute it and/or modify |
||||
|
# it under the terms of the GNU Affero General Public License as |
||||
|
# published by the Free Software Foundation, either version 3 of the |
||||
|
# License, or (at your option) any later version. |
||||
|
# |
||||
|
# This program is distributed in the hope that it will be useful, |
||||
|
# but WITHOUT ANY WARRANTY; without even the implied warranty of |
||||
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
||||
|
# GNU Affero General Public License for more details. |
||||
|
# |
||||
|
# You should have received a copy of the GNU Affero General Public License |
||||
|
# along with this program. If not, see <http://www.gnu.org/licenses/>. |
||||
|
# |
||||
|
############################################################################## |
||||
|
from __future__ import unicode_literals |
||||
|
|
||||
|
from openerp.tests.common import TransactionCase |
||||
|
|
||||
|
|
||||
|
class TestEmailValidate(TransactionCase): |
||||
|
""" |
||||
|
Tests specific reseller behaviors for invoices |
||||
|
""" |
||||
|
|
||||
|
def test_valid_emails(self): |
||||
|
check = self.registry("res.partner")._check_valid_email |
||||
|
for email in [ |
||||
|
"mailbox+tag@foo.bar", |
||||
|
"domain@has-dash.com", |
||||
|
"hey.I.just.met.y0u@call.me", |
||||
|
"allô@mail.me", |
||||
|
"aлrr@test.рф", |
||||
|
"foo@123.com" |
||||
|
]: |
||||
|
self.assertTrue(check(email)) |
||||
|
|
||||
|
def test_invalid_emails(self): |
||||
|
check = self.registry("res.partner")._check_valid_email |
||||
|
for email in [ |
||||
|
"", |
||||
|
"noarobas" |
||||
|
"nodomain@" |
||||
|
"empty@domain..part", |
||||
|
"@nomailbox.com" |
||||
|
"not@fqdn", |
||||
|
"not@twoletter.c", |
||||
|
"symbol@in.domain!", |
||||
|
"s!ymbol@in.mailbox", |
||||
|
]: |
||||
|
self.assertFalse(check(email)) |
Write
Preview
Loading…
Cancel
Save
Reference in new issue