Skip to content

security(spp_change_request_v2): group-scope conflict rules never fire for CR requesters — record rule hides co-members' CRs (fail-open) #494

Description

@kneckinator

Filed at origin/19.0 (23f43963, the merge of #477). From the expert review of #477. Pre-existing, but #477 made the group-scope path executable for the first time (it crashed unconditionally before — see #476), so this is now reachable rather than latent.

Summary

_detect_conflicts searches for conflicting CRs as the current user:

matches = self.env["spp.change.request"].search(domain)   # conflict_mixin.py:197

rule_cr_user (spp_change_request_v2/security/rules.xml:6-18) restricts group_cr_user to CRs they created or that are about their own partner:

['|', ('create_uid', '=', user.id), ('registrant_id', 'in', user.partner_id.ids)]

A group-scope rule exists precisely to find CRs for other members of the same household — which are, by definition, other people's CRs, normally created by other users. For a requester the search returns nothing, so the rule never fires, action = "block" included.

Impact

Group-scope conflict detection works only for validators and managers, whose record rules are broader — i.e. only at review time, never at the point of submission where blocking is supposed to stop the request. The submit-time guard in _on_submit (models/change_request.py:1127-1133), which raises a UserError on a blocking conflict, is inert for the requester persona.

Fail-open: the control reports "no conflict" rather than erroring, so nothing signals that the check did not really run.

Why this is not a one-line sudo()

Populating conflicting_cr_ids with records the user cannot read trades the fail-open for an AccessError (or a display_name leak) at render time. The field is rendered on the CR form as a list of the other CRs, with name / request type / state (views/conflict_extensions.xml:289), and is used by the conflict wizard (views/conflict_wizard_views.xml:155,179).

A fix has to separate what the detection engine may see from what the requester may be shown — e.g. detect with elevated rights, but for users who cannot read the matches store and display only a count plus a generic message, keeping the full list for validators.

Suggested acceptance criteria

  • A group-scope block rule fires for a group_cr_user requester when a co-member has an open CR created by a different user.
  • That requester's CR form renders without an AccessError and does not disclose the other CR's identifying data (name, registrant) — only that a conflict exists.
  • Tests covering both personas: requester and validator.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't working

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions