From c60e829cb2abc7e9b9395dced3b7a1d8df577d1e Mon Sep 17 00:00:00 2001 From: Goncalo Brito Date: Fri, 8 Nov 2024 10:20:42 +0100 Subject: [PATCH] [REF] fetch field data as user Currently auditlog fetch field data as sudo It doesn't make sense to use sudo to fetch the data since the user only have access to edit fields that he has access too. By using sudo we bypass multi company rules This commit will fix #2554 --- auditlog/models/rule.py | 29 +++++++++++++---------------- 1 file changed, 13 insertions(+), 16 deletions(-) diff --git a/auditlog/models/rule.py b/auditlog/models/rule.py index 42297e38451..1f45b44d403 100644 --- a/auditlog/models/rule.py +++ b/auditlog/models/rule.py @@ -1,10 +1,11 @@ # Copyright 2015 ABF OSIELL # License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl). +import contextlib import copy from odoo import _, api, fields, models -from odoo.exceptions import UserError +from odoo.exceptions import AccessError, UserError FIELDS_BLACKLIST = [ "id", @@ -263,11 +264,13 @@ def get_auditlog_fields(self, model): By default it is all stored fields only, but you can override this. """ - return list( - n - for n, f in model._fields.items() - if (not f.compute and not f.related) or f.store - ) + fields_list = [] + for n, f in model._fields.items(): + if (not f.compute and not f.related) or f.store: + with contextlib.suppress(AccessError): + model.check_field_access_rights("read", [n]) + fields_list.append(n) + return fields_list def _make_create(self): """Instanciate a create method that log its calls.""" @@ -287,7 +290,7 @@ def create_full(self, vals_list, **kwargs): # their values exist in cache. new_values = {} fields_list = rule_model.get_auditlog_fields(self) - for new_record in new_records.sudo(): + for new_record in new_records: new_values.setdefault(new_record.id, {}) for fname, field in new_record._fields.items(): if fname not in fields_list: @@ -385,9 +388,7 @@ def write_full(self, vals, **kwargs): fields_list = rule_model.get_auditlog_fields(self) old_values = { d["id"]: d - for d in self.sudo() - .with_context(prefetch_fields=False) - .read(fields_list) + for d in self.with_context(prefetch_fields=False).read(fields_list) } # invalidate_recordset method must be called with existing fields if self._name == "res.users": @@ -398,9 +399,7 @@ def write_full(self, vals, **kwargs): result = write_full.origin(self, vals, **kwargs) new_values = { d["id"]: d - for d in self.sudo() - .with_context(prefetch_fields=False) - .read(fields_list) + for d in self.with_context(prefetch_fields=False).read(fields_list) } if self.env.user in users_to_exclude: return result @@ -453,9 +452,7 @@ def unlink_full(self, **kwargs): fields_list = rule_model.get_auditlog_fields(self) old_values = { d["id"]: d - for d in self.sudo() - .with_context(prefetch_fields=False) - .read(fields_list) + for d in self.with_context(prefetch_fields=False).read(fields_list) } if self.env.user in users_to_exclude: return unlink_full.origin(self, **kwargs)