Prevent org membership removal with existing group/project memberships
What does this MR do and why?
Prevent organization membership removal when the user has group/project membership in the organization.
References
- Issue: #614050 (closed)
- Related MR: !249299 (merged)
- Parent epic: gitlab-org/gitlab&22845
Screenshot
How to set up and validate locally
-
Open a Rails console:
rails console -
Create an organization with an owner, and a second organization user. The second user is also added to a second organization, because the service otherwise blocks removal with "A user must associate with at least one organization":
organization = FactoryBot.create(:organization) owner = FactoryBot.create(:organization_owner, :without_common_organization, organization: organization).user org_user = FactoryBot.create(:organization_user, :without_common_organization, organization: organization) member_user = org_user.user FactoryBot.create(:organization_user, organization: FactoryBot.create(:organization), user: member_user) -
Create a group in that organization and add the second user as a developer (the membership within the org), then print the GlobalID of the organization user for the mutation:
group = FactoryBot.create(:group, organization: organization) group.add_developer(member_user) org_user.to_global_id.to_s # => "gid://gitlab/Organizations::OrganizationUser/<id>" -
Sign in as the owner, open GraphiQL at
http://gdk.test:3000/-/graphql-explorer, and run the mutation with the GlobalID from the previous step. Confirm it returns the:has_membershipserror and does not delete the record:mutation { organizationUserDelete(input: { id: "gid://gitlab/Organizations::OrganizationUser/<id>" }) { organizationUser { id } errors } }Expected response —
organizationUserisnullanderrorscontains the message:{ "data": { "organizationUserDelete": { "organizationUser": null, "errors": [ "You cannot remove a user from an organization while they are a member of groups or projects in the organization" ] } } } -
Confirm the
organization_usersrow is retained (in the Rails console):Organizations::OrganizationUser.exists?(org_user.id) # => true -
Contrast: remove the group membership, then re-run the same mutation in GraphiQL and confirm it now succeeds (
errorsis empty andorganizationUseris returned). The removal succeeds because the user still belongs to the second organization created earlier:group.members.find_by(user: member_user).destroy{ "data": { "organizationUserDelete": { "organizationUser": { "id": "gid://gitlab/Organizations::OrganizationUser/<id>" }, "errors": [] } } }
MR acceptance checklist
Evaluate this MR against the MR acceptance checklist. It helps you analyze changes to reduce risks in quality, performance, reliability, security, and maintainability.
Related to #614050 (closed)
