Skip to content

Fix project membership tab showing missing role bindings and duplicate prevention#17814

Open
wormza wants to merge 1 commit into
rancher:release-2.14from
wormza:fix/project-membership-display-pr
Open

Fix project membership tab showing missing role bindings and duplicate prevention#17814
wormza wants to merge 1 commit into
rancher:release-2.14from
wormza:fix/project-membership-display-pr

Conversation

@wormza
Copy link
Copy Markdown

@wormza wormza commented May 25, 2026

Summary

Fixes #17808
Fixes #17809

Occurred changes and/or fixed issues

Three co-dependent bugs in shell/components/ExplorerMembers.vue and related files caused the Project Membership tab to display incomplete data at scale and allowed duplicate role assignments to be created.

Bug 1 — Missing role bindings at scale (#17808)
The Norman PRTB fetch loaded all bindings across every cluster globally (no filter), then filtered client-side. With 65+ clusters the API returns only the first ~200 of 5,000+ global PRTBs, of which perhaps 10–20 belong to the current cluster. Combined with configureConditionalDepaginate suppressing pagination when the global count exceeds 5,000, the tab appeared almost empty on large installations.

Fixed by scoping the fetch to the current cluster's projects using repeated projectId_in query parameters. Note: Norman's Go backend uses net/url.ParseQuery which does not split comma-separated values — each project ID must be a separate repeated parameter. depaginate is set to true because the result set is now bounded by the cluster scope.

Bug 2 — Projects with no role bindings missing from table (#17808)
rowsWithFakeProjects spread placeholder rows for empty projects into the reduce input alongside real PRTB rows. Because fakeRows have no userId/groupPrincipalId, the early-return guard silently dropped them and they never appeared in the output. Fixed by appending fakeRows directly to the return value outside the reduce.

Bug 3 — Duplicate role assignments allowed (#17809)
AddProjectMemberDialog.vue dispatched rancher/create for every selected roleTemplateId without checking whether an identical binding already existed. Fixed by checking the loaded PRTBs in the store before creating, matching on projectId + roleTemplateId + principalId. Shows an error if all selected roles are duplicates, or a warning and skips only duplicates if some are new.

Technical notes summary

  • Norman's _in filter requires repeated query parameters, not comma-separated values. ?projectId_in=a&projectId_in=b works; ?projectId_in=a,b returns zero results because Go's net/url.ParseQuery treats the comma-separated string as a single literal.
  • depaginate: true in explorer.js is safe here because the PRTB fetch is now scoped server-side to the current cluster's projects. The previous conditional depagination (maxResourceCount: 5000) was only necessary to avoid loading all global PRTBs — that risk is gone with scoping.
  • Duplicate check in AddProjectMemberDialog.vue is keyed on projectId (not project display name), so projects with identical names in different clusters are correctly distinguished.

Areas or cases that should be tested

  1. Navigate to a cluster with multiple projects → Cluster and Project MembersProject Membership tab
    • All role bindings for the current cluster's projects should be visible
    • Projects with no role bindings should appear as group headers with a "No roles assigned" row
  2. Repeat on a large Rancher instance where total global PRTB count exceeds 5,000 — the tab should still show all bindings for the current cluster
  3. Click Add Project Member, select a user/group and a role they already hold in that project, click Create
    • Error banner should appear; no duplicate binding should be created
  4. Click Add Project Member, select a mix of new and already-assigned roles, click Create
    • Warning banner should appear; only new bindings should be created
  5. Add a brand new member with roles — should proceed as normal with no warnings

Tested locally using Chrome against https://rancher-di.rnd-odinpf.asgard.capi.

Areas which could experience regressions

  • Project Membership tab — any change to how PRTBs are fetched or filtered
  • Add Project Member dialog — role creation flow; ensure the happy path (no duplicates) is unaffected
  • Other membership tabs (Cluster Membership) — they use the same ExplorerMembers.vue component; confirm they are unaffected by the PRTB scoping change

Screenshot/Video

Checklist

  • The PR is linked to an issue and the linked issue has a Milestone, or no issue is needed
  • The PR has a Milestone
  • The PR template has been filled out
  • The PR has been self reviewed
  • The PR has a reviewer assigned
  • The PR has automated tests or clear instructions for manual tests and the linked issue has appropriate QA labels, or tests are not needed
  • The PR has reviewed with UX and tested in light and dark mode, or there are no UX changes
  • The PR has been reviewed in terms of Accessibility
  • The PR has considered, and if applicable tested with, the three Global Roles Admin, Standard User and User Base

…e prevention

- Scope Norman PRTB fetch to current cluster's projects using repeated
  projectId_in query parameters. Norman's _in filter requires repeated
  params; comma-separated values are parsed as a single literal string
  by Go's net/url.ParseQuery and match nothing.

- Set depaginate: true for Norman PRTBs in explorer.js. The fetch is
  now bounded by the cluster scope so full pagination is safe. The
  previous conditional (maxResourceCount: 5000) suppressed pagination
  at exactly the scale where scoping is needed most.

- Fix rowsWithFakeProjects dropping projects with no role bindings.
  Placeholder rows were spread into the reduce input but immediately
  discarded (no userId/groupPrincipalId). They are now appended to
  the return value outside the reduce.

- Prevent duplicate role assignments in AddProjectMemberDialog. Before
  creating a PRTB, filter selected roleTemplateIds against existing
  store entries keyed on projectId + roleTemplateId + principalId.
  Show an error if all roles are duplicates; a warning if some are.
Copy link
Copy Markdown
Member

@richard-cox richard-cox left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can you fill in the pr description template please

@wormza
Copy link
Copy Markdown
Author

wormza commented May 26, 2026

Can you fill in the pr description template please

@richard-cox I have used the template now.

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

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants