Problem/Motivation

The module's reorder flow is hard-coded to "the current user must equal the order's customer":

  • Route commerce_repeat_order.repeat_order requires _permission: 'view own commerce_order'.
  • CommerceRepeatOrder::repeatOrder() double-checks $uid == $order_uid and aborts otherwise.

This works for single-customer stores but prevents any contrib/custom logic from granting reorder access in scenarios where a user can legitimately view an order they did not personally place. The most common example is Commerce + href="https://www.drupal.org/project/group">Group with the commerce_group_order relationship: co-workers in the same organization see each other's orders in their portal's order list, but "Reorder" fails silently (route 403) or shows "You can only repeat your own
order." even though commerce_order.view access was granted.

Other valid scenarios: store managers duplicating a customer order into their own cart to validate pricing, support agents reproducing a user's cart, user-impersonation flows, etc.

Proposed resolution

Two minimal, backwards-compatible changes:

  1. Route requirement — replace _permission: 'view own commerce_order' with _entity_access: 'commerce_order.view'. This preserves the existing single-customer behaviour (core's view-own access plugin still grants it for the order's
    customer) while letting the standard Drupal entity access system delegate the decision to other contrib modules (Group, custom access plugins, etc.).
  2. Controller — keep the existing $uid == $order_uid rule as the default, but expose the final access decision through a new CommerceRepeatOrderAccessEvent. Subscribers receive the order, the current account, and the seeded
    AccessResultInterface, and may override the result via setAccess(). Default behaviour is bit-identical for sites without subscribers.

A merge request implementing both points is attached.

Remaining tasks

  • Code review.
  • Optional: add a kernel test for the event (happy to follow up).
  • Optional: README note documenting the event.

User interface changes

None.

API changes

  • Route requirement changed from _permission to _entity_access. Any consumer relying on the specific permission name no longer needs it; everyone who could reach the route before still can.
  • New public event Drupal\commerce_repeat_order\Event\CommerceRepeatOrderAccessEvent with name commerce_repeat_order.access.

Data model changes

None.

Disclosure

  • This issue description and the accompanying patch/MR were generated by Claude Code under human supervision; every outcome (text, code, and this submission) was reviewed and approved by the submitter before posting.
Command icon Show commands

Start within a Git clone of the project using the version control instructions.

Or, if you do not have SSH keys set up on git.drupalcode.org:

Comments

plopesc created an issue. See original summary.

plopesc changed the visibility of the branch 3585747-allow-third-party-modules to hidden.

plopesc’s picture

Status: Active » Needs review

MR created with two main changes:

The route now requires _entity_access: 'commerce_order.view' instead of the view own permission, so any registered access plugin (core's own-order check, Commerce Group, custom ones) can reach the controller.

The controller still defaults to "only the order's customer may repeat it", but that decision is now dispatched as an OrderCloneAccessEvent. Any module can subscribe and flip the result with $event->setAccess(...) — we'll use it in our
Commerce+Group portal, and it opens the door to impersonation/support-agent flows too. No subscriber on the site means no change in behaviour.