[IMP]hide_portal_module_by_user: fix invoices access in v18
This commit is contained in:
@@ -1,16 +1,47 @@
|
||||
# Copyright 2026 Munin
|
||||
# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl).
|
||||
|
||||
from urllib.parse import parse_qsl, urlsplit
|
||||
|
||||
from odoo import fields, models
|
||||
|
||||
|
||||
def match_portal_url(portal_url, target):
|
||||
"""Whether ``target`` is covered by the ``portal_url`` of a portal group.
|
||||
|
||||
A group url is the one read from the portal.portal_docs_entry t-call it
|
||||
was generated from, and it covers:
|
||||
|
||||
- the listing itself and its sub-pages, since the portal serves detail
|
||||
and pager pages below it ('/my/projects/135', '/my/projects/page/2'),
|
||||
which go through _prepare_portal_layout_values as well;
|
||||
- the entries narrowing that listing down with query arguments. Odoo 18
|
||||
splits some listings in several entries this way, eg. account has
|
||||
'/my/invoices?filterby=invoices' and '/my/invoices?filterby=bills'
|
||||
where 16.0 had a single '/my/invoices'.
|
||||
|
||||
A group url carrying query arguments only matches targets carrying them
|
||||
all, so a group can be restricted to one such entry; a group url without
|
||||
any matches every entry of the listing.
|
||||
"""
|
||||
if not portal_url or not target:
|
||||
return False
|
||||
ref = urlsplit(portal_url)
|
||||
got = urlsplit(target)
|
||||
root = ref.path.rstrip('/')
|
||||
if not (got.path == root or got.path.startswith(root + '/')):
|
||||
return False
|
||||
return set(parse_qsl(ref.query)) <= set(parse_qsl(got.query))
|
||||
|
||||
|
||||
class ResUsers(models.Model):
|
||||
_inherit = "res.users"
|
||||
|
||||
portal_url = fields.Char(string='Portal URL')
|
||||
|
||||
def validate_portal_url(self, url):
|
||||
group = self.sudo().env['res.groups'].search([('portal_url', '=', url)])
|
||||
if self.env.user in group.users:
|
||||
return True
|
||||
groups = self.sudo().env['res.groups'].search([('portal_url', '!=', False)])
|
||||
for group in groups.filtered(lambda g: match_portal_url(g.portal_url, url)):
|
||||
if self.env.user in group.users:
|
||||
return True
|
||||
return False
|
||||
|
||||
Reference in New Issue
Block a user