@@ -57,6 +57,7 @@ type MembershipRepo interface {
5757 // RBAC methods
5858
5959 ListAllByUser (ctx context.Context , userID uuid.UUID ) ([]* Membership , error )
60+ ListDirectMembershipsByUserInOrg (ctx context.Context , orgID uuid.UUID , userID uuid.UUID ) ([]* Membership , error )
6061 // ListGroupMembershipsByUser returns all memberships of the users inherited from groups
6162 ListGroupMembershipsByUser (ctx context.Context , userID uuid.UUID ) ([]* Membership , error )
6263 ListAllByResource (ctx context.Context , rt authz.ResourceType , id uuid.UUID ) ([]* Membership , error )
@@ -69,13 +70,14 @@ type MembershipsRBAC interface {
6970
7071type MembershipUseCase struct {
7172 repo MembershipRepo
73+ groupReo GroupRepo
7274 orgUseCase * OrganizationUseCase
7375 logger * log.Helper
7476 auditor * AuditorUseCase
7577}
7678
77- func NewMembershipUseCase (repo MembershipRepo , orgUC * OrganizationUseCase , auditor * AuditorUseCase , logger log.Logger ) * MembershipUseCase {
78- return & MembershipUseCase {repo : repo , orgUseCase : orgUC , logger : log .NewHelper (logger ), auditor : auditor }
79+ func NewMembershipUseCase (repo MembershipRepo , orgUC * OrganizationUseCase , auditor * AuditorUseCase , groupRepo GroupRepo , logger log.Logger ) * MembershipUseCase {
80+ return & MembershipUseCase {repo : repo , orgUseCase : orgUC , logger : log .NewHelper (logger ), auditor : auditor , groupReo : groupRepo }
7981}
8082
8183// LeaveAndDeleteOrg deletes a membership (and the org i) from the database associated with the current user
@@ -99,9 +101,23 @@ func (uc *MembershipUseCase) LeaveAndDeleteOrg(ctx context.Context, userID, memb
99101 return NewErrNotFound ("membership" )
100102 }
101103
102- uc .logger .Infow ("msg" , "Deleting membership" , "user_id" , userID , "membership_id" , m .ID .String ())
103- if err := uc .repo .Delete (ctx , membershipUUID ); err != nil {
104- return fmt .Errorf ("failed to delete membership: %w" , err )
104+ // Get all direct memberships for the user in the org in regard to resources
105+ resourceMemberships , err := uc .repo .ListDirectMembershipsByUserInOrg (ctx , m .OrganizationID , userUUID )
106+ if err != nil {
107+ return fmt .Errorf ("failed to find direct memberships in org: %w" , err )
108+ }
109+
110+ for _ , rm := range resourceMemberships {
111+ uc .logger .Infow ("msg" , "Deleting membership" , "user_id" , userID , "membership_id" , rm .ID .String ())
112+
113+ if err := uc .repo .Delete (ctx , rm .ID ); err != nil {
114+ return fmt .Errorf ("failed to delete membership: %w" , err )
115+ }
116+ }
117+
118+ // Remove the user from all groups in the org
119+ if err := uc .groupReo .RemoveMemberFromAllGroups (ctx , m .OrganizationID , userUUID ); err != nil {
120+ return fmt .Errorf ("failed to remove user from all groups in org: %w" , err )
105121 }
106122
107123 uc .auditor .Dispatch (ctx , & events.OrgUserLeft {
@@ -142,22 +158,59 @@ func (uc *MembershipUseCase) DeleteOther(ctx context.Context, orgID, userID, mem
142158 return NewErrInvalidUUID (err )
143159 }
144160
161+ // Find the membership to delete
145162 m , err := uc .repo .FindByIDInOrg (ctx , orgUUID , membershipUUID )
146163 if err != nil {
147164 return fmt .Errorf ("failed to find membership: %w" , err )
148165 } else if m == nil {
149166 return NewErrNotFound ("membership" )
150167 }
151168
169+ // Prevent users from deleting their own membership
152170 if m .User .ID == userID {
153171 return NewErrValidationStr ("cannot delete yourself from the org" )
154172 }
155173
174+ // Parse the user ID of the membership to be removed
175+ toRemoveUserUUID , err := uuid .Parse (m .User .ID )
176+ if err != nil {
177+ return NewErrInvalidUUID (err )
178+ }
179+
180+ // Log the deletion
156181 uc .logger .Infow ("msg" , "Deleting membership" , "org_id" , orgID , "membership_id" , m .ID .String ())
182+
183+ // Delete the main membership
157184 if err := uc .repo .Delete (ctx , membershipUUID ); err != nil {
158185 return fmt .Errorf ("failed to delete membership: %w" , err )
159186 }
160187
188+ // Clean up all resource-related memberships
189+ if err := uc .deleteRelatedMemberships (ctx , m .OrganizationID , toRemoveUserUUID ); err != nil {
190+ return err
191+ }
192+
193+ // Remove the user from all groups in the org
194+ if err := uc .groupReo .RemoveMemberFromAllGroups (ctx , m .OrganizationID , toRemoveUserUUID ); err != nil {
195+ return fmt .Errorf ("failed to remove user from all groups in org: %w" , err )
196+ }
197+
198+ return nil
199+ }
200+
201+ // deleteRelatedMemberships removes all resource-related memberships for a user in an organization
202+ func (uc * MembershipUseCase ) deleteRelatedMemberships (ctx context.Context , orgID , userID uuid.UUID ) error {
203+ resourceMemberships , err := uc .repo .ListDirectMembershipsByUserInOrg (ctx , orgID , userID )
204+ if err != nil {
205+ return fmt .Errorf ("failed to find direct memberships in org: %w" , err )
206+ }
207+
208+ for _ , rm := range resourceMemberships {
209+ if err := uc .repo .Delete (ctx , rm .ID ); err != nil {
210+ return fmt .Errorf ("failed to delete membership: %w" , err )
211+ }
212+ }
213+
161214 return nil
162215}
163216
0 commit comments