From 9b4c1014841ac2d3fe941e07f8ea736026aefc55 Mon Sep 17 00:00:00 2001
From: Thibault Francois <tfr@openerp.com>
Date: Fri, 12 Feb 2021 11:50:34 +0000
Subject: [PATCH] [IMP] crm|mail: Use flanker to check email correctness

Context
-------
Lead assignement is now based on PLS probability.
We want to avoid giving the same score to real email addresses
and email addresses that are just well formed

Flanker try to acheive that be checking specific
criteria according to the domain, check the dns and mx record

Improvement
-----------
Define a mail_validate function seach as phone_validate.
If flanker is installed, use flanker for validation of
email addresses else use email_normalize.
It should help the PLS to give a bad score to well formed addresses
that flanker suspect to be wrong.

Setup
-----
NB: flanker is not available as debian package, we make it optional

To install flanker
```
pip install flanker
pip install redis
pip install dnsq
```

If you have installed it as root you may need to run
```py
from flanker.addresslib import address
```
as root for the first initialisation

closes odoo/odoo#66429

X-original-commit: f540976c8751e2bf402fed8db830ec0fbf98f654
Signed-off-by: Thibault Delavallee (tde) <tde@openerp.com>
---
 addons/crm/models/crm_lead.py        |  5 ++++-
 addons/mail/__init__.py              |  2 +-
 addons/mail/tools/__init__.py        |  4 ++++
 addons/mail/tools/mail_validation.py | 27 +++++++++++++++++++++++++++
 4 files changed, 36 insertions(+), 2 deletions(-)
 create mode 100644 addons/mail/tools/__init__.py
 create mode 100644 addons/mail/tools/mail_validation.py

diff --git a/addons/crm/models/crm_lead.py b/addons/crm/models/crm_lead.py
index 210029dbbdd0..693b67ff751e 100644
--- a/addons/crm/models/crm_lead.py
+++ b/addons/crm/models/crm_lead.py
@@ -8,6 +8,7 @@ from datetime import date, datetime, timedelta
 from psycopg2 import sql
 
 from odoo import api, fields, models, tools, SUPERUSER_ID
+from odoo.addons.mail.tools import mail_validation
 from odoo.addons.phone_validation.tools import phone_validation
 from odoo.exceptions import UserError, AccessError
 from odoo.osv import expression
@@ -18,6 +19,8 @@ from . import crm_stage
 
 _logger = logging.getLogger(__name__)
 
+
+
 CRM_LEAD_FIELDS_TO_MERGE = [
     # UTM mixin
     'campaign_id',
@@ -451,7 +454,7 @@ class Lead(models.Model):
             if lead.email_from:
                 email_state = 'incorrect'
                 for email in email_split(lead.email_from):
-                    if tools.email_normalize(email):
+                    if mail_validation.mail_validate(email):
                         email_state = 'correct'
                         break
             lead.email_state = email_state
diff --git a/addons/mail/__init__.py b/addons/mail/__init__.py
index f2cd96d8c832..2334d4398bec 100644
--- a/addons/mail/__init__.py
+++ b/addons/mail/__init__.py
@@ -1,5 +1,5 @@
 # -*- coding: utf-8 -*-
-
 from . import models
+from . import tools
 from . import wizard
 from . import controllers
diff --git a/addons/mail/tools/__init__.py b/addons/mail/tools/__init__.py
new file mode 100644
index 000000000000..b9c73282748e
--- /dev/null
+++ b/addons/mail/tools/__init__.py
@@ -0,0 +1,4 @@
+# -*- coding: utf-8 -*-
+# Part of Odoo. See LICENSE file for full copyright and licensing details.
+
+from . import mail_validation
diff --git a/addons/mail/tools/mail_validation.py b/addons/mail/tools/mail_validation.py
new file mode 100644
index 000000000000..937bdcd262e1
--- /dev/null
+++ b/addons/mail/tools/mail_validation.py
@@ -0,0 +1,27 @@
+# -*- coding: utf-8 -*-
+# Part of Odoo. See LICENSE file for full copyright and licensing details.
+import logging
+
+from odoo import tools
+
+_logger = logging.getLogger(__name__)
+
+_flanker_lib_warning = False
+
+try:
+    from flanker.addresslib import address
+    # Avoid warning each time a mx server is not reachable by flanker
+    logging.getLogger("flanker.addresslib.validate").setLevel(logging.ERROR)
+
+    def mail_validate(email):
+        return bool(address.validate_address(email))
+
+except ImportError:
+
+    def mail_validate(email):
+        global _flanker_lib_warning
+        if not _flanker_lib_warning:
+            _flanker_lib_warning = True
+            _logger.info("The `flanker` Python module is not installed,"
+                           "so email validation fallback to email_normalize. Use 'pip install flanker' to install it")
+        return tools.email_normalize(email)
-- 
GitLab