fix: update journal access rules to support domain ID filtering and improve read operation handling
This commit is contained in:
parent
2ba3ca12eb
commit
71e6a8d64a
@ -30,13 +30,61 @@ class AccountJournal(models.Model):
|
|||||||
self.env.context.get('install_mode')
|
self.env.context.get('install_mode')
|
||||||
)
|
)
|
||||||
if not bypass:
|
if not bypass:
|
||||||
allowed_ids = user.sudo().allowed_journal_ids.ids
|
allowed_ids = list(user.sudo().allowed_journal_ids.ids)
|
||||||
|
|
||||||
|
# When Odoo's fetch() verifies a record it just loaded, it re-runs
|
||||||
|
# _search with [('id', 'in', [X])]. The record was already cleared
|
||||||
|
# by _check_access/check_access_rule, so we must honour the explicit
|
||||||
|
# IDs present in the domain and add them to the allow-list so they
|
||||||
|
# survive the sudo search.
|
||||||
|
for leaf in domain:
|
||||||
|
if (
|
||||||
|
isinstance(leaf, (list, tuple))
|
||||||
|
and len(leaf) == 3
|
||||||
|
and leaf[0] == 'id'
|
||||||
|
and leaf[1] in ('=', 'in')
|
||||||
|
):
|
||||||
|
value = leaf[2]
|
||||||
|
if isinstance(value, (list, tuple, set)):
|
||||||
|
allowed_ids.extend(value)
|
||||||
|
elif isinstance(value, int):
|
||||||
|
allowed_ids.append(value)
|
||||||
|
|
||||||
domain = [('id', 'in', allowed_ids)] + list(domain)
|
domain = [('id', 'in', allowed_ids)] + list(domain)
|
||||||
# Run the search as sudo to bypass standard multi-company rules
|
# Run the search as sudo to bypass standard multi-company rules
|
||||||
return self.sudo()._search(domain, offset=offset, limit=limit, order=order, **kwargs)
|
return self.sudo()._search(domain, offset=offset, limit=limit, order=order, **kwargs)
|
||||||
|
|
||||||
return super(AccountJournal, self)._search(domain, offset=offset, limit=limit, order=order, **kwargs)
|
return super(AccountJournal, self)._search(domain, offset=offset, limit=limit, order=order, **kwargs)
|
||||||
|
|
||||||
|
def _check_access(self, operation):
|
||||||
|
"""
|
||||||
|
Overridden to bypass multi-company record rules for allowed journals,
|
||||||
|
and enforce the allowed journals restriction for write, create, and delete operations.
|
||||||
|
"""
|
||||||
|
if self.env.su:
|
||||||
|
return super(AccountJournal, self)._check_access(operation)
|
||||||
|
|
||||||
|
user = self.env.user
|
||||||
|
allowed_journals = user.sudo().allowed_journal_ids
|
||||||
|
if allowed_journals:
|
||||||
|
# Enforce restriction for write, create, and delete operations.
|
||||||
|
if operation in ('write', 'create', 'unlink'):
|
||||||
|
forbidden = self.filtered(lambda j: j.id not in allowed_journals.ids)
|
||||||
|
if forbidden:
|
||||||
|
import functools
|
||||||
|
return forbidden, functools.partial(AccessError, _("You do not have access to this journal."))
|
||||||
|
|
||||||
|
# Read operations are allowed to prevent access errors when loading
|
||||||
|
# documents (payments/moves) referencing other journals.
|
||||||
|
if operation == 'read':
|
||||||
|
return None
|
||||||
|
|
||||||
|
# If all records in self are allowed, bypass standard record rules.
|
||||||
|
if all(j.id in allowed_journals.ids for j in self):
|
||||||
|
return None
|
||||||
|
|
||||||
|
return super(AccountJournal, self)._check_access(operation)
|
||||||
|
|
||||||
def check_access_rule(self, operation):
|
def check_access_rule(self, operation):
|
||||||
"""
|
"""
|
||||||
Overridden to bypass multi-company record rules for allowed journals,
|
Overridden to bypass multi-company record rules for allowed journals,
|
||||||
@ -55,6 +103,9 @@ class AccountJournal(models.Model):
|
|||||||
if not all(j.id in allowed_journals.ids for j in self):
|
if not all(j.id in allowed_journals.ids for j in self):
|
||||||
raise AccessError(_("You do not have access to this journal."))
|
raise AccessError(_("You do not have access to this journal."))
|
||||||
|
|
||||||
|
if operation == 'read':
|
||||||
|
return
|
||||||
|
|
||||||
# If all records in self are allowed, bypass standard record rules.
|
# If all records in self are allowed, bypass standard record rules.
|
||||||
if all(j.id in allowed_journals.ids for j in self):
|
if all(j.id in allowed_journals.ids for j in self):
|
||||||
return
|
return
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user