Skip to content

Commit 91a4a98

Browse files
authored
chore: add an unassign action for roles (#16728)
1 parent bf5b002 commit 91a4a98

File tree

18 files changed

+214
-240
lines changed

18 files changed

+214
-240
lines changed

coderd/apidoc/docs.go

+2
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

coderd/apidoc/swagger.json

+2
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

coderd/database/dbauthz/customroles_test.go

+53-69
Original file line numberDiff line numberDiff line change
@@ -34,11 +34,12 @@ func TestInsertCustomRoles(t *testing.T) {
3434
}
3535
}
3636

37-
canAssignRole := rbac.Role{
37+
canCreateCustomRole := rbac.Role{
3838
Identifier: rbac.RoleIdentifier{Name: "can-assign"},
3939
DisplayName: "",
4040
Site: rbac.Permissions(map[string][]policy.Action{
41-
rbac.ResourceAssignRole.Type: {policy.ActionRead, policy.ActionCreate},
41+
rbac.ResourceAssignRole.Type: {policy.ActionRead},
42+
rbac.ResourceAssignOrgRole.Type: {policy.ActionRead, policy.ActionCreate},
4243
}),
4344
}
4445

@@ -61,37 +62,37 @@ func TestInsertCustomRoles(t *testing.T) {
6162
return all
6263
}
6364

64-
orgID := uuid.NullUUID{
65-
UUID: uuid.New(),
66-
Valid: true,
67-
}
65+
orgID := uuid.New()
66+
6867
testCases := []struct {
6968
name string
7069

7170
subject rbac.ExpandableRoles
7271

7372
// Perms to create on new custom role
74-
organizationID uuid.NullUUID
73+
organizationID uuid.UUID
7574
site []codersdk.Permission
7675
org []codersdk.Permission
7776
user []codersdk.Permission
7877
errorContains string
7978
}{
8079
{
8180
// No roles, so no assign role
82-
name: "no-roles",
83-
subject: rbac.RoleIdentifiers{},
84-
errorContains: "forbidden",
81+
name: "no-roles",
82+
organizationID: orgID,
83+
subject: rbac.RoleIdentifiers{},
84+
errorContains: "forbidden",
8585
},
8686
{
8787
// This works because the new role has 0 perms
88-
name: "empty",
89-
subject: merge(canAssignRole),
88+
name: "empty",
89+
organizationID: orgID,
90+
subject: merge(canCreateCustomRole),
9091
},
9192
{
9293
name: "mixed-scopes",
93-
subject: merge(canAssignRole, rbac.RoleOwner()),
9494
organizationID: orgID,
95+
subject: merge(canCreateCustomRole, rbac.RoleOwner()),
9596
site: codersdk.CreatePermissions(map[codersdk.RBACResource][]codersdk.RBACAction{
9697
codersdk.ResourceWorkspace: {codersdk.ActionRead},
9798
}),
@@ -101,27 +102,30 @@ func TestInsertCustomRoles(t *testing.T) {
101102
errorContains: "organization roles specify site or user permissions",
102103
},
103104
{
104-
name: "invalid-action",
105-
subject: merge(canAssignRole, rbac.RoleOwner()),
106-
site: codersdk.CreatePermissions(map[codersdk.RBACResource][]codersdk.RBACAction{
105+
name: "invalid-action",
106+
organizationID: orgID,
107+
subject: merge(canCreateCustomRole, rbac.RoleOwner()),
108+
org: codersdk.CreatePermissions(map[codersdk.RBACResource][]codersdk.RBACAction{
107109
// Action does not go with resource
108110
codersdk.ResourceWorkspace: {codersdk.ActionViewInsights},
109111
}),
110112
errorContains: "invalid action",
111113
},
112114
{
113-
name: "invalid-resource",
114-
subject: merge(canAssignRole, rbac.RoleOwner()),
115-
site: codersdk.CreatePermissions(map[codersdk.RBACResource][]codersdk.RBACAction{
115+
name: "invalid-resource",
116+
organizationID: orgID,
117+
subject: merge(canCreateCustomRole, rbac.RoleOwner()),
118+
org: codersdk.CreatePermissions(map[codersdk.RBACResource][]codersdk.RBACAction{
116119
"foobar": {codersdk.ActionViewInsights},
117120
}),
118121
errorContains: "invalid resource",
119122
},
120123
{
121124
// Not allowing these at this time.
122-
name: "negative-permission",
123-
subject: merge(canAssignRole, rbac.RoleOwner()),
124-
site: []codersdk.Permission{
125+
name: "negative-permission",
126+
organizationID: orgID,
127+
subject: merge(canCreateCustomRole, rbac.RoleOwner()),
128+
org: []codersdk.Permission{
125129
{
126130
Negate: true,
127131
ResourceType: codersdk.ResourceWorkspace,
@@ -131,89 +135,69 @@ func TestInsertCustomRoles(t *testing.T) {
131135
errorContains: "no negative permissions",
132136
},
133137
{
134-
name: "wildcard", // not allowed
135-
subject: merge(canAssignRole, rbac.RoleOwner()),
136-
site: codersdk.CreatePermissions(map[codersdk.RBACResource][]codersdk.RBACAction{
138+
name: "wildcard", // not allowed
139+
organizationID: orgID,
140+
subject: merge(canCreateCustomRole, rbac.RoleOwner()),
141+
org: codersdk.CreatePermissions(map[codersdk.RBACResource][]codersdk.RBACAction{
137142
codersdk.ResourceWorkspace: {"*"},
138143
}),
139144
errorContains: "no wildcard symbols",
140145
},
141146
// escalation checks
142147
{
143-
name: "read-workspace-escalation",
144-
subject: merge(canAssignRole),
145-
site: codersdk.CreatePermissions(map[codersdk.RBACResource][]codersdk.RBACAction{
148+
name: "read-workspace-escalation",
149+
organizationID: orgID,
150+
subject: merge(canCreateCustomRole),
151+
org: codersdk.CreatePermissions(map[codersdk.RBACResource][]codersdk.RBACAction{
146152
codersdk.ResourceWorkspace: {codersdk.ActionRead},
147153
}),
148154
errorContains: "not allowed to grant this permission",
149155
},
150156
{
151-
name: "read-workspace-outside-org",
152-
organizationID: uuid.NullUUID{
153-
UUID: uuid.New(),
154-
Valid: true,
155-
},
156-
subject: merge(canAssignRole, rbac.ScopedRoleOrgAdmin(orgID.UUID)),
157+
name: "read-workspace-outside-org",
158+
organizationID: uuid.New(),
159+
subject: merge(canCreateCustomRole, rbac.ScopedRoleOrgAdmin(orgID)),
157160
org: codersdk.CreatePermissions(map[codersdk.RBACResource][]codersdk.RBACAction{
158161
codersdk.ResourceWorkspace: {codersdk.ActionRead},
159162
}),
160-
errorContains: "forbidden",
163+
errorContains: "not allowed to grant this permission",
161164
},
162165
{
163166
name: "user-escalation",
164167
// These roles do not grant user perms
165-
subject: merge(canAssignRole, rbac.ScopedRoleOrgAdmin(orgID.UUID)),
168+
organizationID: orgID,
169+
subject: merge(canCreateCustomRole, rbac.ScopedRoleOrgAdmin(orgID)),
166170
user: codersdk.CreatePermissions(map[codersdk.RBACResource][]codersdk.RBACAction{
167171
codersdk.ResourceWorkspace: {codersdk.ActionRead},
168172
}),
169-
errorContains: "not allowed to grant this permission",
173+
errorContains: "organization roles specify site or user permissions",
170174
},
171175
{
172-
name: "template-admin-escalation",
173-
subject: merge(canAssignRole, rbac.RoleTemplateAdmin()),
176+
name: "site-escalation",
177+
organizationID: orgID,
178+
subject: merge(canCreateCustomRole, rbac.RoleTemplateAdmin()),
174179
site: codersdk.CreatePermissions(map[codersdk.RBACResource][]codersdk.RBACAction{
175-
codersdk.ResourceWorkspace: {codersdk.ActionRead}, // ok!
176180
codersdk.ResourceDeploymentConfig: {codersdk.ActionUpdate}, // not ok!
177181
}),
178-
user: codersdk.CreatePermissions(map[codersdk.RBACResource][]codersdk.RBACAction{
179-
codersdk.ResourceWorkspace: {codersdk.ActionRead}, // ok!
180-
}),
181-
errorContains: "deployment_config",
182+
errorContains: "organization roles specify site or user permissions",
182183
},
183184
// ok!
184185
{
185-
name: "read-workspace-template-admin",
186-
subject: merge(canAssignRole, rbac.RoleTemplateAdmin()),
187-
site: codersdk.CreatePermissions(map[codersdk.RBACResource][]codersdk.RBACAction{
186+
name: "read-workspace-template-admin",
187+
organizationID: orgID,
188+
subject: merge(canCreateCustomRole, rbac.RoleTemplateAdmin()),
189+
org: codersdk.CreatePermissions(map[codersdk.RBACResource][]codersdk.RBACAction{
188190
codersdk.ResourceWorkspace: {codersdk.ActionRead},
189191
}),
190192
},
191193
{
192194
name: "read-workspace-in-org",
193-
subject: merge(canAssignRole, rbac.ScopedRoleOrgAdmin(orgID.UUID)),
194195
organizationID: orgID,
196+
subject: merge(canCreateCustomRole, rbac.ScopedRoleOrgAdmin(orgID)),
195197
org: codersdk.CreatePermissions(map[codersdk.RBACResource][]codersdk.RBACAction{
196198
codersdk.ResourceWorkspace: {codersdk.ActionRead},
197199
}),
198200
},
199-
{
200-
name: "user-perms",
201-
// This is weird, but is ok
202-
subject: merge(canAssignRole, rbac.RoleMember()),
203-
user: codersdk.CreatePermissions(map[codersdk.RBACResource][]codersdk.RBACAction{
204-
codersdk.ResourceWorkspace: {codersdk.ActionRead},
205-
}),
206-
},
207-
{
208-
name: "site+user-perms",
209-
subject: merge(canAssignRole, rbac.RoleMember(), rbac.RoleTemplateAdmin()),
210-
site: codersdk.CreatePermissions(map[codersdk.RBACResource][]codersdk.RBACAction{
211-
codersdk.ResourceWorkspace: {codersdk.ActionRead},
212-
}),
213-
user: codersdk.CreatePermissions(map[codersdk.RBACResource][]codersdk.RBACAction{
214-
codersdk.ResourceWorkspace: {codersdk.ActionRead},
215-
}),
216-
},
217201
}
218202

219203
for _, tc := range testCases {
@@ -234,7 +218,7 @@ func TestInsertCustomRoles(t *testing.T) {
234218
_, err := az.InsertCustomRole(ctx, database.InsertCustomRoleParams{
235219
Name: "test-role",
236220
DisplayName: "",
237-
OrganizationID: tc.organizationID,
221+
OrganizationID: uuid.NullUUID{UUID: tc.organizationID, Valid: true},
238222
SitePermissions: db2sdk.List(tc.site, convertSDKPerm),
239223
OrgPermissions: db2sdk.List(tc.org, convertSDKPerm),
240224
UserPermissions: db2sdk.List(tc.user, convertSDKPerm),
@@ -249,11 +233,11 @@ func TestInsertCustomRoles(t *testing.T) {
249233
LookupRoles: []database.NameOrganizationPair{
250234
{
251235
Name: "test-role",
252-
OrganizationID: tc.organizationID.UUID,
236+
OrganizationID: tc.organizationID,
253237
},
254238
},
255239
ExcludeOrgRoles: false,
256-
OrganizationID: uuid.UUID{},
240+
OrganizationID: uuid.Nil,
257241
})
258242
require.NoError(t, err)
259243
require.Len(t, roles, 1)

0 commit comments

Comments
 (0)