fix(fusion_helpdesk): define missing _norm_email helper (NameError on every inbox endpoint)
The IDOR-hardening commit (fb345be3) referenced _norm_email in submit()
and _identity() but never defined or imported it, so every inbox endpoint
(my_tickets, ticket_detail, ticket_reply, unread_count) and the New-ticket
submit path raised NameError at runtime — surfaced as a JSON-RPC error in
the dialog. The smoke test missed it because it replicated build_scope_domain
directly instead of calling the controller.
Add _norm_email(*candidates) to utils.py (returns the first candidate that
email_normalize accepts, else '' — rejecting self-set wildcards like '%' so
the inbox scope key can't be widened), import it in main.py, drop the now-unused
email_normalize import there, and add unit tests + a guard that the controller
namespace resolves the name.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -8,6 +8,7 @@ here is unit-testable in isolation, which is what lets us validate the
|
||||
identity keystone, the server-side scoping boundary, the public-message
|
||||
filter and the unread maths without a live central Odoo to talk to.
|
||||
"""
|
||||
from odoo.tools import email_normalize
|
||||
|
||||
# Sentinel used so a missing label/email can never widen a domain to
|
||||
# "match everything". An empty string in `=`/`=ilike` would match rows
|
||||
@@ -29,6 +30,24 @@ def escape_like(value):
|
||||
return (value or '').replace('\\', '\\\\').replace('%', '\\%').replace('_', '\\_')
|
||||
|
||||
|
||||
def _norm_email(*candidates):
|
||||
"""Return the first candidate that normalises to a valid email, else ''.
|
||||
|
||||
Used to derive the inbox scope key from a chain of fallbacks (the
|
||||
confirmed reply email -> ``user.email`` -> ``user.login``).
|
||||
``email_normalize`` lowercases the address and returns a falsy value for
|
||||
anything that is not exactly one valid email — including a self-set
|
||||
wildcard like ``%`` — so the value fed into ``build_scope_domain`` can
|
||||
never widen the scope. Pairs with :func:`escape_like` as defense in depth
|
||||
against the ``partner_email =ilike`` IDOR.
|
||||
"""
|
||||
for candidate in candidates:
|
||||
normalized = email_normalize(candidate or '')
|
||||
if normalized:
|
||||
return normalized
|
||||
return ''
|
||||
|
||||
|
||||
def build_ticket_vals(kind, subject, body_html, team_id, client_label,
|
||||
reporter_name, reporter_email, company_name):
|
||||
"""Construct the `helpdesk.ticket` create vals for a forwarded report.
|
||||
|
||||
Reference in New Issue
Block a user