Repository navigation
fix(deleter): user delete removes every policy the user holds - #2022
Conversation
DeleteUser deletes every live policy of the user after the org removals and before the PATs and the user row. Policies on disabled projects and groups, on projects in orgs where the user has no org-level policy, and on resources in disabled projects stayed live before.
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
|
No actionable comments were generated in the recent review.
|
| Layer / File(s) | Summary |
|---|---|
Policy cleanup contract and implementation core/deleter/service.go, core/deleter/mocks/membership_service.go, core/membership/service.go, core/membership/service_test.go |
MembershipService adds RemovePrincipalPolicies. Policy deletion treats policy.ErrNotExist as success. The mock and membership test cover the new operation. |
Deletion flow and unit coverage core/deleter/service.go, core/deleter/service_test.go |
DeleteUser removes principal policies after organization membership removal and before personal access token cleanup. Unit tests cover this order and verify that errors stop later deletion steps. |
End-to-end deletion regression test/e2e/regression/api_test.go |
The regression test checks that user deletion removes live policies and resource access, and removes the user from organization users and role pairs. |
Priority:
Estimated code review effort: 3 (Moderate) | ~20 minutes
Change: Bug fix
Suggested reviewers: whoabhisheksah
Merge Risk: 
Minimal · up to 89930
-
No merge-blocking issue was identified in the policy cleanup or user-deletion flow.
Pre-merge checks: 
2
- Autofix · Keep fixing CodeRabbit findings and required CI, and resolving merge conflicts
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.
Comment @coderabbitai help to get the list of available commands.
Coverage Report for CI Build 40487021232Warning Build has drifted: This PR's base is out of sync with its target branch, so coverage data may include unrelated changes. Coverage increased (+0.02%) to 55.746%Details
Uncovered ChangesNo uncovered changes found. Coverage Regressions68 previously-covered lines in 2 files lost coverage.
Coverage Stats
💛 - Coveralls |
rohilsurana
left a comment
There was a problem hiding this comment.
The comment on DeleteUser (core/deleter/service.go:557) says the org loop is there so userService.Delete does not leave policy rows behind. The new policy step does that now, so please update or drop that comment.
removePoliciesByFilter stopped at a policy that someone else deleted between the list and the delete, so a user, service user or PAT delete failed until it was retried. It now skips a policy that is already gone, like the other delete loops.
Summary
DeleteUsernow deletes every live policy the user holds before it deletes the user. Before, it only removed the user from the orgs where it held an org-level policy, so these policies stayed live and kept naming a user that no longer exists:CreatePolicydoes not check org membership);Changes
core/deleter/service.go: after the org removals,DeleteUsercallsRemovePrincipalPoliciesfor the user, before it deletes the PATs and the user. A failure stops the delete and leaves the user in place; a retry deletes the rest.core/deleter/mocks/membership_service.go: regenerated for the new interface method.Technical Details
membership.Service.RemovePrincipalPolicieslists the live policies by principal, on any resource type and in any org, and deletes each one withpolicy.Service.Delete: the role binding relations first, then the row. The service user delete uses the same call.ForceRemoveOrganizationMemberis unchanged.user.Service.Deletealready removes every relation whose subject is the user, which includes each policy's bearer relation. They still showed inListPoliciesandGetPolicy.Test Plan
core/deleter/service_test.goTestDeleteUser: the user is removed from each org, then its remaining policies are deleted, then its PATs, then the user. An org removal failure stops the delete before the policy step, and a policy step failure stops it before the PATs and the user. The cases fail without the policy step, with its error only logged, or with it after the PAT step.TestUserDeleteLeavesNoAccessAndNoLivePolicy: a user holds policies on an org, a disabled project, a disabled group, a project in another org, and an order inside the disabled project. AfterDeleteUser, no live policy names the user (checked per resource in the database and withListPolicies), the user can get none of them, andListOrganizationUsersnames the user in neitherusersnorrole_pairs. Without the policy step, the policies on the disabled project, the disabled group, the other org's project and the order stay live.go test ./core/deleter/...passes.go test ./test/e2e/...passes.golangci-lint run ./core/deleter/... ./test/e2e/regression/...reports no issues.