From 1e80dfbb06be920f5d3150bf4973935141c01ada Mon Sep 17 00:00:00 2001 From: "Thomas Lefebvre (thle)" Date: Thu, 11 Jan 2024 09:55:17 +0100 Subject: [PATCH 1/2] [FIX] base, hr: avoid invalid access error in onchange() when editing user Steps to reproduce: ------------------- - install the "hr" module; - remove access rights for "Employees"; - change language on the user profile. Issue: ------ There's an Access Error because we can't read the `private_street` field on the employee that corresponds to the user. Cause: ------ The new version of onchange fetches the record values on the server side, unlike the old version which used the values in the view. In the old version, as we were using view values, this didn't cause any problems, as the values came from a read that which took into account `SELF_READABLE_FIELDS`. Note: We do not have access to the value of the `private_street` field because it is a related field with the attribute `related_sudo=False` and we do not have access rights for the `hr.employee` model. Solution: --------- Use the cache and place the values of the fields in `SELF_READABLE_FIELDS` in it before performing the onchange logic. opw-3664929 --- addons/hr/models/res_users.py | 1 - addons/hr/tests/test_self_user_access.py | 14 ++++++++++++++ odoo/addons/base/models/res_users.py | 7 +++++++ 3 files changed, 21 insertions(+), 1 deletion(-) diff --git a/addons/hr/models/res_users.py b/addons/hr/models/res_users.py index 33f40779989f9..fd6e76f0dc3f8 100644 --- a/addons/hr/models/res_users.py +++ b/addons/hr/models/res_users.py @@ -50,7 +50,6 @@ 'km_home_work', 'marital', 'mobile_phone', - 'notes', 'employee_parent_id', 'passport_id', 'permit_no', diff --git a/addons/hr/tests/test_self_user_access.py b/addons/hr/tests/test_self_user_access.py index b950b2d87407f..d2412a0b62e14 100644 --- a/addons/hr/tests/test_self_user_access.py +++ b/addons/hr/tests/test_self_user_access.py @@ -240,3 +240,17 @@ def test_access_employee_account(self): hubert_acc.invalidate_recordset(["display_name"]) self.assertEqual(hubert_emp.with_user(hubert).sudo().bank_account_id.sudo(False).display_name, 'FR******7890') + + def test_onchange_readable_fields_with_no_access(self): + """ + The purpose is to test that the onchange logic takes into account `SELF_READABLE_FIELDS`. + + The view contains fields that are in `SELF_READABLE_FIELDS` (example: `private_street`). + Even if the user does not have read access to the employee, + it should not cause an access error if these fields are in `SELF_READABLE_FIELDS`. + """ + self.env['res.lang']._activate_lang("fr_FR") + with Form(self.richard.with_user(self.richard), view='hr.res_users_view_form_profile') as form: + # triggering an onchange should not trigger some access error + form.lang = "fr_FR" + form.tz = "Europe/Brussels" diff --git a/odoo/addons/base/models/res_users.py b/odoo/addons/base/models/res_users.py index 56012cf306de0..d03d62588082b 100644 --- a/odoo/addons/base/models/res_users.py +++ b/odoo/addons/base/models/res_users.py @@ -619,6 +619,13 @@ def toggle_active(self): user.partner_id.toggle_active() super(Users, self).toggle_active() + def onchange(self, values, field_names, fields_spec): + # Hacky fix to access fields in `SELF_READABLE_FIELDS` in the onchange logic. + # Put field values in the cache. + if self == self.env.user: + [self.sudo()[field_name] for field_name in self.SELF_READABLE_FIELDS] + return super().onchange(values, field_names, fields_spec) + def read(self, fields=None, load='_classic_read'): if fields and self == self.env.user: readable = self.SELF_READABLE_FIELDS From 036cc9ceb31499365ee3b25e2cd9e4ab0fb8797f Mon Sep 17 00:00:00 2001 From: Raphael Collet Date: Thu, 11 Jan 2024 11:25:40 +0100 Subject: [PATCH 2/2] [FIX] core: avoid hiding access error in onchange() with Form When the server-side form view reads its record, the call to web_read() leaves data in cache, which may prevent some access error to be triggered in the first call to onchange(). In order to avoid that, simply clean up the environment like after the other method calls. --- odoo/tests/common.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/odoo/tests/common.py b/odoo/tests/common.py index 2fcc6adc7e790..3fddd329c94a7 100644 --- a/odoo/tests/common.py +++ b/odoo/tests/common.py @@ -2396,6 +2396,8 @@ def _init_from_defaults(self, model): self._changed.update(self._view['fields']) def _init_from_values(self, values): + self._env.flush_all() + self._env.clear() # discard cache and pending recomputations self._values.update( record_to_values(self._view['fields'], values))