refactor(deleter): delegate org removal cascade to membership#1696
refactor(deleter): delegate org removal cascade to membership#1696rohilsurana wants to merge 3 commits into
Conversation
…nline RemoveUsers
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
|
No actionable comments were generated in the recent review. 🎉 ℹ️ Recent review info⚙️ Run configurationConfiguration used: Path: .coderabbit.yaml Review profile: CHILL Plan: Pro Run ID: 📒 Files selected for processing (2)
🚧 Files skipped from review as they are similar to previous changes (2)
📝 WalkthroughSummary by CodeRabbit
WalkthroughThis PR centralizes cascade user deletion: it removes RemoveUsers from group/org contracts, adds membership.ForceRemoveOrganizationMember (unguarded cascade), drops org audit-record dependency, rewrites the deleter to pre-clean resource-scoped policies, and updates mocks and wiring. ChangesMember removal cascade refactoring
🎯 3 (Moderate) | ⏱️ ~25 minutes Possibly related PRs
Suggested reviewers
🚥 Pre-merge checks | ✅ 2✅ Passed checks (2 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. 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 |
Coverage Report for CI Build 27411342262Warning 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.3%) to 43.56%Details
Uncovered Changes
Coverage Regressions129 previously-covered lines in 6 files lost coverage.
Coverage Stats
💛 - Coveralls |
There was a problem hiding this comment.
Actionable comments posted: 1
🧹 Nitpick comments (1)
core/deleter/service_test.go (1)
261-319: ⚡ Quick winAdd a regression case for the policy-list error branch in
RemoveUsersFromOrg.Given this PR fixes the wrong-variable check around policy listing, add one subtest where
policyService.Listreturns a non-policy.ErrNotExisterror and assert it is returned/aggregated (and membership force-remove is not invoked for that user). This locks in the bug fix.Proposed test addition
func TestRemoveUsersFromOrg(t *testing.T) { @@ t.Run("propagates membership cascade failure", func(t *testing.T) { @@ }) + + t.Run("surfaces policy-list error for a user", func(t *testing.T) { + orgSvc, projSvc, resSvc, grpSvc, mbrSvc, polSvc, roleSvc, invSvc, usrSvc, patSvc, suSvc, custSvc, subSvc, invocSvc := newMocks(t) + + projSvc.EXPECT().List(mock.Anything, project.Filter{OrgID: orgID}).Return([]project.Project{}, nil) + polSvc.EXPECT().List(mock.Anything, policy.Filter{PrincipalID: userID, PrincipalType: schema.UserPrincipal}). + Return(nil, errors.New("policy list boom")) + + svc := deleter.NewCascadeDeleter(orgSvc, projSvc, resSvc, grpSvc, mbrSvc, polSvc, roleSvc, invSvc, usrSvc, patSvc, suSvc, custSvc, subSvc, invocSvc) + err := svc.RemoveUsersFromOrg(context.Background(), orgID, []string{userID}) + assert.ErrorContains(t, err, "policy list boom") + }) }
ℹ️ Review info
⚙️ Run configuration
Configuration used: Path: .coderabbit.yaml
Review profile: CHILL
Plan: Pro
Run ID: 3d8f65d7-ee99-4517-8664-c4ba87676663
📒 Files selected for processing (15)
cmd/serve.gocore/deleter/mocks/group_service.gocore/deleter/mocks/membership_service.gocore/deleter/mocks/organization_service.gocore/deleter/service.gocore/deleter/service_test.gocore/group/service.gocore/membership/service.gocore/membership/service_test.gocore/organization/mocks/audit_record_repository.gocore/organization/service.gocore/organization/service_test.gointernal/api/v1beta1connect/interfaces.gointernal/api/v1beta1connect/mocks/cascade_deleter.gointernal/api/v1beta1connect/mocks/group_service.go
💤 Files with no reviewable changes (6)
- core/organization/mocks/audit_record_repository.go
- core/deleter/mocks/group_service.go
- internal/api/v1beta1connect/interfaces.go
- internal/api/v1beta1connect/mocks/group_service.go
- internal/api/v1beta1connect/mocks/cascade_deleter.go
- core/group/service.go
Summary
deleter.RemoveUsersFromOrgreimplemented the org-member removal cascade inline (policy walks over projects/groups/resources), duplicating logic thatmembership.RemoveOrganizationMemberalready handles canonically. This PR consolidates the removal path and deletes the now-orphaned inline implementations.Changes
membership.ForceRemoveOrganizationMember(new): same cascade asRemoveOrganizationMemberbut without the member-and-owner guards — noErrNotMemberwhen the principal has no org policies, and it removes the org's last owner without complaint. Deletion cascades need this: deleting a user who solely owns an org must succeed (the org is left ownerless, same as today's behavior). Anything user-initiated keeps going through the guarded variant. Implemented by parameterizing the existing method; the cascade internals already supported unguarded owner deletes.deleter.RemoveUsersFromOrg: now cleans up custom-resource policies (outside the membership cascade's scope) and delegates everything else toForceRemoveOrganizationMemberper user. Also fixes a latent bug where the policy-list error check tested the wrong variable (errinstead ofpolicyErr).organization.Service.RemoveUsersandgroup.Service.RemoveUsers(+ its private helper): the deleter was their only caller — API handlers already use the membership service directly. Dropped the org service's now-unusedAuditRecordRepositorydependency andextractPrincipalInfohelper, and removed dead method declarations from the deleter/API interfaces (CascadeDeleter.RemoveUsersFromOrghad no handler callers).Behavior notes
org.RemoveUsers.GroupMemberRemovedEventlegacy audit viagroup.RemoveUsers; the membership cascade removes the same policies/relations but emits the org-level removal audit instead. User deletion itself remains separately audited.Test plan
membership.ForceRemoveOrganizationMember(last-owner bypass, no-ErrNotMember cascade, error propagation)deleter.RemoveUsersFromOrg(membership delegation, custom-resource cleanup incl. out-of-org and missing resources, error propagation)go test -race ./core/... ./internal/api/... ./cmd/...passesmake lintclean