Base org-scoped URL generation on the request's URL, not scoped_paths?

What does this MR do and why?

Organization-scoped path helpers (e.g. admin_users_path / organization_admin_users_path) previously nested a link based on current_organization.scoped_paths?, which broke for the Default Organization: visiting /o/default/admin still generated global links, since scoped_paths? is always false for Default.

Replaced with:

def organization_path
  return data_context.organization.path if data_context.organization?
  return kwargs[:organization_path]     if kwargs.key?(:organization_path)
  return Current.organization_resolver&.from_organization_params&.path
end

nest under organization_path, else global
  • data_context.organization?: an isolated User (or anchor Organization) has no existence outside it (Gitlab::Current::DataContext) - an inescapable boundary that overrides both the URL and an explicit override.
  • kwargs[:organization_path]: an explicit per-call override (including nil, to force the global path), for when the same helper is called from two places on one page that disagree - e.g. a sidebar link stays nested, a header link for the same feature stays global.
  • Current.organization_resolver&.from_organization_params&.path: the request's own URL, read from a Current attribute set once per request - not the calling object's own params (broke for ViewComponents with an unrelated private params of their own, ~35 CI jobs), and not from_request (also matches group/project namespace params, nesting far more broadly than intended, ~85 CI jobs).

Current.organization_resolver also gives !250271 (merged) a way to read the request's Organization from sidebar helpers, instead of the separate Current.request_organization attribute added there for the same purpose.


Note on route pairing: route pairs (which global route maps to which /o/:organization_path route) are matched by name convention alone - the same approach an earlier foo_path(use_data_context: true) version used. A stricter controller/action-matching check sat in between the two, to exclude pairs like instance admin vs. organization admin (see !247881 (merged), !247426 (merged), !244408 (merged), !250534 (merged)), but it also blocked admin-area views from intentionally reusing the same auto-nesting between the instance-wide and organization-scoped admin areas. It's been pulled into a follow-up, !251449 (closed) (see !249936 (comment 3717787915)), pending a design that distinguishes the two cases. Until that lands, an instance admin whose home Organization is isolated could have instance-admin links incorrectly nested under their org - mitigated for now by not marking Organizations that own instance admin users as isolated.

MR acceptance checklist

Evaluate this MR against the MR acceptance checklist.

Edited by Alex Pooley

Merge request reports

Loading
Loading