[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

closes odoo/odoo#148997

Signed-off-by: Raphael Collet <rco@odoo.com>
This commit is contained in:
Thomas Lefebvre (thle)
2024-01-11 17:00:50 +00:00
parent 59eec8711c
commit 5f74235d4d
3 changed files with 21 additions and 1 deletions
-1
View File
@@ -53,7 +53,6 @@ HR_WRITABLE_FIELDS = [
'km_home_work',
'marital',
'mobile_phone',
'notes',
'employee_parent_id',
'passport_id',
'permit_no',
+14
View File
@@ -216,3 +216,17 @@ class TestSelfAccessRights(TestHrCommon):
def testSearchUserEMployee(self):
# Searching user based on employee_id field should not raise bad query error
self.env['res.users'].with_user(self.richard).search([('employee_id', 'ilike', 'Hubert')])
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"
+7
View File
@@ -560,6 +560,13 @@ class Users(models.Model):
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'):
readable = self.SELF_READABLE_FIELDS
if fields and self == self.env.user and all(key in readable or key.startswith('context_') for key in fields):