# Copyright 2026 Munin # License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl). from odoo.http import request from odoo.addons.portal.controllers.portal import CustomerPortal from werkzeug.exceptions import NotFound from ..models.res_users import match_portal_url # Routes always reachable, whatever the portal groups of the user. # # Split in two because of how each route is matched, not because of how # important it is: both lists are equally "always reachable". # # Exact match, for routes that have no sub-route of their own. '/my' has to # stay here in any case: as a prefix it would match every portal page and # make this module a no-op. WHITELISTED_ROUTES = ['/my', '/my/home', '/my/account', '/my/security', '/my/payment_method'] # Prefix match, for routes that also serve detail and pager sub-pages # ('/my/invoices/', '/my/invoices/page/', '/my/invoices/overdue'), # which go through _prepare_portal_layout_values too. WHITELISTED_ROUTE_PREFIXES = ['/my/invoices'] class CustomerPortalPolicy(CustomerPortal): def _prepare_portal_layout_values(self): vals = super()._prepare_portal_layout_values() current_path = request.httprequest.path if current_path in WHITELISTED_ROUTES: return vals if any(match_portal_url(route, current_path) for route in WHITELISTED_ROUTE_PREFIXES): return vals if request.env.user.validate_portal_url(current_path): return vals if '/my/' not in current_path: return vals raise NotFound()