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

Lines changed: 2 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

coderd/apidoc/swagger.json

Lines changed: 2 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

coderd/database/dbauthz/customroles_test.go

Lines changed: 53 additions & 69 deletions
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)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy