From a0290a9d360e0e427c80fe5df87f518a4df453d1 Mon Sep 17 00:00:00 2001
From: std-odoo <std@odoo.com>
Date: Wed, 31 May 2023 10:24:26 +0200
Subject: [PATCH] [FIX] mail_plugin: fix access error when enriching some
 partners

Bug
===
When we enrich a partner we don't have access to, it will try to read
it, but because of the ACL if will crash. To fix that issue, we don't
return the partner if we can't access it and we show an error message
in the UI instead of letting it crash.

Task-3344536

closes odoo/odoo#134767

Signed-off-by: Thibault Delavallee (tde) <tde@openerp.com>
---
 .../mail_plugin/controllers/authenticate.py   |  3 ++
 addons/mail_plugin/controllers/mail_plugin.py |  9 +++--
 addons/mail_plugin/i18n/mail_plugin.pot       |  6 ++++
 addons/mail_plugin/tests/test_controller.py   | 34 +++++++++++++++++++
 4 files changed, 50 insertions(+), 2 deletions(-)

diff --git a/addons/mail_plugin/controllers/authenticate.py b/addons/mail_plugin/controllers/authenticate.py
index 998f2689960e..436197cbfd71 100644
--- a/addons/mail_plugin/controllers/authenticate.py
+++ b/addons/mail_plugin/controllers/authenticate.py
@@ -11,6 +11,7 @@ import werkzeug
 
 from odoo import http
 from odoo.http import request
+from werkzeug.exceptions import NotFound
 
 _logger = logging.getLogger(__name__)
 
@@ -92,6 +93,8 @@ class Authenticate(http.Controller):
     # Using UTC explicitly in case of a distributed system where the generation and the signature verification do not
     # necessarily happen on the same server
     def _generate_auth_code(self, scope, name):
+        if not request.env.user._is_internal():
+            raise NotFound()
         auth_dict = {
             'scope': scope,
             'name': name,
diff --git a/addons/mail_plugin/controllers/mail_plugin.py b/addons/mail_plugin/controllers/mail_plugin.py
index 1d747cc41941..d26576f13b2b 100644
--- a/addons/mail_plugin/controllers/mail_plugin.py
+++ b/addons/mail_plugin/controllers/mail_plugin.py
@@ -288,9 +288,8 @@ class MailPluginController(http.Controller):
         search = self._get_iap_search_term(email)
 
         partner_iap = request.env["res.partner.iap"].sudo().search([("iap_search_domain", "=", search)], limit=1)
-
         if partner_iap:
-            return partner_iap.partner_id
+            return partner_iap.partner_id.sudo(False)
 
         return request.env["res.partner"].search([("is_company", "=", True), ("email_normalized", "=ilike", "%" + search)], limit=1)
 
@@ -298,6 +297,12 @@ class MailPluginController(http.Controller):
         if not company:
             return {'id': -1}
 
+        try:
+            company.check_access_rights('read')
+            company.check_access_rule('read')
+        except AccessError:
+            return {'id': company.id, 'name': _('No Access')}
+
         fields_list = ['id', 'name', 'phone', 'mobile', 'email', 'website']
 
         company_values = dict((fname, company[fname]) for fname in fields_list)
diff --git a/addons/mail_plugin/i18n/mail_plugin.pot b/addons/mail_plugin/i18n/mail_plugin.pot
index 364220c1136d..b4145a4546cd 100644
--- a/addons/mail_plugin/i18n/mail_plugin.pot
+++ b/addons/mail_plugin/i18n/mail_plugin.pot
@@ -467,6 +467,12 @@ msgstr ""
 msgid "Logout"
 msgstr ""
 
+#. module: mail_plugin
+#: code:addons/mail_plugin/controllers/mail_plugin.py:0
+#, python-format
+msgid "No Access"
+msgstr ""
+
 #. module: mail_plugin
 #. openerp-web
 #: code:addons/mail_plugin/static/src/to_translate/translations_outlook.xml:0
diff --git a/addons/mail_plugin/tests/test_controller.py b/addons/mail_plugin/tests/test_controller.py
index fa788ee1a11a..41757791f4cc 100644
--- a/addons/mail_plugin/tests/test_controller.py
+++ b/addons/mail_plugin/tests/test_controller.py
@@ -6,6 +6,7 @@ from unittest.mock import Mock, patch
 
 from odoo.addons.iap.tools import iap_tools
 from odoo.addons.mail_plugin.tests.common import TestMailPluginControllerCommon, mock_auth_method_outlook
+from odoo.exceptions import AccessError
 
 
 class TestMailPluginController(TestMailPluginControllerCommon):
@@ -126,6 +127,39 @@ class TestMailPluginController(TestMailPluginControllerCommon):
         self.assertEqual(first_company_id, second_company_id, "Should not create a new company")
         self.assertEqual(result["partner"]["company"]["additionalInfo"]["iap_information"], "test")
 
+    def test_get_partner_no_access(self):
+        """Test the case where the partner has been enriched by someone else, but we can't access it."""
+        partner = self.env["res.partner"].create({"name": "Test", "website": "https://test.example.com"})
+        self.env["res.partner.iap"].create({
+            "partner_id": partner.id,
+            "iap_search_domain": "@test.example.com",
+        })
+
+        # sanity check, we can access the partner
+        result = self.mock_plugin_partner_get(
+            "Test", "test@test.example.com",
+            lambda _, domain: {"name": "Name", "email": "test@test.example.com"},
+        )
+        self.assertEqual(result["partner"]["company"]["website"], "https://test.example.com")
+
+        # now we can't access it
+        def _check_access_rule(record, operation, *args, **kwargs):
+            if operation == "read" and record == partner:
+                raise AccessError("No Access")
+            return True
+
+        with patch.object(type(partner), 'check_access_rule', _check_access_rule):
+            result = self.mock_plugin_partner_get(
+                "Test", "test@test.example.com",
+                lambda _, domain: {"name": "Name", "email": "test@test.example.com"},
+            )
+        self.assertEqual(result["partner"]["company"].get("id"), partner.id)
+        self.assertEqual(result["partner"]["company"].get("name"), "No Access")
+        self.assertFalse(result["partner"]["company"].get("website"))
+
+        partners = self.env["res.partner"].search([("email", "=", partner.email)])
+        self.assertEqual(partners, partner, "Should not have created a new partner")
+
     def test_get_partner_no_email_returned_by_iap(self):
         """Test the case where IAP do not return an email address.
 
-- 
GitLab