Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit791aa8d

Browse files
committed
add trigger to delete role from organization members on delete
1 parent11a8d30 commit791aa8d

File tree

5 files changed

+142
-3
lines changed

5 files changed

+142
-3
lines changed

‎coderd/database/dbmem/dbmem.go

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1397,6 +1397,16 @@ func (q *FakeQuerier) DeleteCustomRole(_ context.Context, arg database.DeleteCus
13971397
ifinitial==len(q.data.customRoles) {
13981398
returnsql.ErrNoRows
13991399
}
1400+
1401+
// Emulate the trigger 'remove_organization_member_custom_role'
1402+
fori,mem:=rangeq.organizationMembers {
1403+
ifmem.OrganizationID==arg.OrganizationID.UUID {
1404+
mem.Roles=slices.DeleteFunc(mem.Roles,func(rolestring)bool {
1405+
returnrole==arg.Name
1406+
})
1407+
q.organizationMembers[i]=mem
1408+
}
1409+
}
14001410
returnnil
14011411
}
14021412

‎coderd/database/dump.sql

Lines changed: 22 additions & 0 deletions
Some generated files are not rendered by default. Learn more aboutcustomizing how changed files appear on GitHub.
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
DROPTRIGGER IF EXISTS remove_organization_member_custom_roleON custom_roles;
2+
DROPFUNCTION IF EXISTS remove_organization_member_role;
Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
-- When a custom role is deleted, we need to remove the assigned role
2+
-- from all organization members that have it.
3+
-- This action cannot be reverted, so deleting a custom role should be
4+
-- done with caution.
5+
CREATE OR REPLACEFUNCTIONremove_organization_member_role()
6+
RETURNS TRIGGERAS
7+
$$
8+
BEGIN
9+
-- Delete the role from all organization members that have it.
10+
-- TODO: When site wide custom roles are supported, if the
11+
--organization_id is null, we should remove the role from the 'users'
12+
--table instead.
13+
IFOLD.organization_idIS NOT NULL THEN
14+
UPDATE organization_members
15+
-- this is a noop if the role is not assigned to the member
16+
SET roles= array_remove(roles,OLD.name)
17+
WHERE
18+
-- Scope to the correct organization
19+
organization_members.organization_id=OLD.organization_id;
20+
END IF;
21+
RETURN OLD;
22+
END;
23+
$$ LANGUAGE plpgsql;
24+
25+
26+
-- Attach the function to deleting the custom role
27+
CREATETRIGGERremove_organization_member_custom_role
28+
BEFOREDELETEON custom_roles FOR EACH ROW
29+
EXECUTE PROCEDURE remove_organization_member_role();

‎enterprise/coderd/roles_test.go

Lines changed: 79 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -326,13 +326,20 @@ func TestCustomOrganizationRole(t *testing.T) {
326326
},
327327
})
328328

329-
orgAdmin,_:=coderdtest.CreateAnotherUser(t,owner,first.OrganizationID,rbac.ScopedRoleOrgAdmin(first.OrganizationID))
329+
orgAdmin,orgAdminUser:=coderdtest.CreateAnotherUser(t,owner,first.OrganizationID,rbac.ScopedRoleOrgAdmin(first.OrganizationID))
330330
ctx:=testutil.Context(t,testutil.WaitMedium)
331331

332-
//nolint:gocritic // owner is required for this
333-
createdRole,err:=orgAdmin.PatchOrganizationRole(ctx,first.OrganizationID,templateAdminCustom(first.OrganizationID))
332+
createdRole,err:=orgAdmin.PatchOrganizationRole(ctx,templateAdminCustom(first.OrganizationID))
334333
require.NoError(t,err,"upsert role")
335334

335+
//nolint:gocritic // org_admin cannot assign to themselves
336+
_,err=owner.UpdateOrganizationMemberRoles(ctx,first.OrganizationID,orgAdminUser.ID.String(), codersdk.UpdateRoles{
337+
// Give the user this custom role, to ensure when it is deleted, the user
338+
// is ok to be used.
339+
Roles: []string{createdRole.Name,rbac.ScopedRoleOrgAdmin(first.OrganizationID).Name},
340+
})
341+
require.NoError(t,err,"assign custom role to user")
342+
336343
existingRoles,err:=orgAdmin.ListOrganizationRoles(ctx,first.OrganizationID)
337344
require.NoError(t,err)
338345

@@ -352,6 +359,75 @@ func TestCustomOrganizationRole(t *testing.T) {
352359
returnrole.Name==createdRole.Name
353360
})
354361
require.False(t,exists,"custom role should be deleted")
362+
363+
// Verify you can still assign roles.
364+
// There used to be a bug that if a member had a delete role, they
365+
// could not be assigned roles anymore.
366+
//nolint:gocritic // org_admin cannot assign to themselves
367+
_,err=owner.UpdateOrganizationMemberRoles(ctx,first.OrganizationID,orgAdminUser.ID.String(), codersdk.UpdateRoles{
368+
Roles: []string{rbac.ScopedRoleOrgAdmin(first.OrganizationID).Name},
369+
})
370+
require.NoError(t,err)
371+
})
372+
373+
// Verify deleting a custom role cascades to all members
374+
t.Run("DeleteRoleCascadeMembers",func(t*testing.T) {
375+
t.Parallel()
376+
dv:=coderdtest.DeploymentValues(t)
377+
dv.Experiments= []string{string(codersdk.ExperimentCustomRoles)}
378+
owner,first:=coderdenttest.New(t,&coderdenttest.Options{
379+
Options:&coderdtest.Options{
380+
DeploymentValues:dv,
381+
},
382+
LicenseOptions:&coderdenttest.LicenseOptions{
383+
Features: license.Features{
384+
codersdk.FeatureCustomRoles:1,
385+
},
386+
},
387+
})
388+
389+
orgAdmin,orgAdminUser:=coderdtest.CreateAnotherUser(t,owner,first.OrganizationID,rbac.ScopedRoleOrgAdmin(first.OrganizationID))
390+
ctx:=testutil.Context(t,testutil.WaitMedium)
391+
392+
createdRole,err:=orgAdmin.PatchOrganizationRole(ctx,templateAdminCustom(first.OrganizationID))
393+
require.NoError(t,err,"upsert role")
394+
395+
customRoleIdentifier:= rbac.RoleIdentifier{
396+
Name:createdRole.Name,
397+
OrganizationID:first.OrganizationID,
398+
}
399+
400+
// Create a few members with the role
401+
coderdtest.CreateAnotherUser(t,owner,first.OrganizationID,customRoleIdentifier)
402+
coderdtest.CreateAnotherUser(t,owner,first.OrganizationID,rbac.ScopedRoleOrgAdmin(first.OrganizationID),customRoleIdentifier)
403+
coderdtest.CreateAnotherUser(t,owner,first.OrganizationID,rbac.ScopedRoleOrgTemplateAdmin(first.OrganizationID),rbac.ScopedRoleOrgAuditor(first.OrganizationID),customRoleIdentifier)
404+
405+
// Verify members have the custom role
406+
members,err:=orgAdmin.OrganizationMembers(ctx,first.OrganizationID)
407+
require.NoError(t,err)
408+
require.Len(t,members,5)// 3 members + org admin + owner
409+
for_,member:=rangemembers {
410+
ifmember.UserID==orgAdminUser.ID||member.UserID==first.UserID {
411+
continue
412+
}
413+
414+
require.True(t,slices.ContainsFunc(member.Roles,func(role codersdk.SlimRole)bool {
415+
returnrole.Name==customRoleIdentifier.Name
416+
}),"member should have custom role")
417+
}
418+
419+
err=orgAdmin.DeleteOrganizationRole(ctx,first.OrganizationID,createdRole.Name)
420+
require.NoError(t,err)
421+
422+
// Verify the role was removed from all members
423+
members,err=orgAdmin.OrganizationMembers(ctx,first.OrganizationID)
424+
require.NoError(t,err)
425+
require.Len(t,members,5)// 3 members + org admin + owner
426+
for_,member:=rangemembers {
427+
require.False(t,slices.ContainsFunc(member.Roles,func(role codersdk.SlimRole)bool {
428+
returnrole.Name==customRoleIdentifier.Name
429+
}),"role should be removed from all users")
430+
}
355431
})
356432
}
357433

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp