Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit 4be61d9

Browse files
EmyrkKira-Pilot
andauthored
fix: Role assign ui fixes (#3521)
Co-authored-by: Kira Pilot <[email protected]>
1 parent 4b6a82f commit 4be61d9

File tree

17 files changed

+211
-96
lines changed

17 files changed

+211
-96
lines changed

coderd/rbac/builtin.go

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -123,7 +123,10 @@ var (
123123
Name: userAdmin,
124124
DisplayName: "User Admin",
125125
Site: permissions(map[Object][]Action{
126-
ResourceUser: {ActionCreate, ActionRead, ActionUpdate, ActionDelete},
126+
ResourceRoleAssignment: {ActionCreate, ActionRead, ActionUpdate, ActionDelete},
127+
ResourceUser: {ActionCreate, ActionRead, ActionUpdate, ActionDelete},
128+
// Full perms to manage org members
129+
ResourceOrganizationMember: {ActionCreate, ActionRead, ActionUpdate, ActionDelete},
127130
}),
128131
}
129132
},
@@ -196,6 +199,10 @@ var (
196199
templateAdmin: true,
197200
userAdmin: true,
198201
},
202+
userAdmin: {
203+
member: true,
204+
orgMember: true,
205+
},
199206
orgAdmin: {
200207
orgAdmin: true,
201208
orgMember: true,

coderd/rbac/builtin_test.go

Lines changed: 24 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -119,7 +119,7 @@ func TestRolePermissions(t *testing.T) {
119119
memberMe := authSubject{Name: "member_me", UserID: currentUser.String(), Roles: []string{rbac.RoleMember()}}
120120
orgMemberMe := authSubject{Name: "org_member_me", UserID: currentUser.String(), Roles: []string{rbac.RoleMember(), rbac.RoleOrgMember(orgID)}}
121121

122-
admin := authSubject{Name: "admin", UserID: adminID.String(), Roles: []string{rbac.RoleMember(), rbac.RoleOwner()}}
122+
owner := authSubject{Name: "owner", UserID: adminID.String(), Roles: []string{rbac.RoleMember(), rbac.RoleOwner()}}
123123
orgAdmin := authSubject{Name: "org_admin", UserID: adminID.String(), Roles: []string{rbac.RoleMember(), rbac.RoleOrgMember(orgID), rbac.RoleOrgAdmin(orgID)}}
124124

125125
otherOrgMember := authSubject{Name: "org_member_other", UserID: uuid.NewString(), Roles: []string{rbac.RoleMember(), rbac.RoleOrgMember(otherOrg)}}
@@ -130,7 +130,7 @@ func TestRolePermissions(t *testing.T) {
130130

131131
// requiredSubjects are required to be asserted in each test case. This is
132132
// to make sure one is not forgotten.
133-
requiredSubjects := []authSubject{memberMe, admin, orgMemberMe, orgAdmin, otherOrgAdmin, otherOrgMember, templateAdmin, userAdmin}
133+
requiredSubjects := []authSubject{memberMe, owner, orgMemberMe, orgAdmin, otherOrgAdmin, otherOrgMember, templateAdmin, userAdmin}
134134

135135
testCases := []struct {
136136
// Name the test case to better locate the failing test case.
@@ -150,7 +150,7 @@ func TestRolePermissions(t *testing.T) {
150150
Actions: []rbac.Action{rbac.ActionRead},
151151
Resource: rbac.ResourceUser,
152152
AuthorizeMap: map[bool][]authSubject{
153-
true: {admin, memberMe, orgMemberMe, orgAdmin, otherOrgMember, otherOrgAdmin, templateAdmin, userAdmin},
153+
true: {owner, memberMe, orgMemberMe, orgAdmin, otherOrgMember, otherOrgAdmin, templateAdmin, userAdmin},
154154
false: {},
155155
},
156156
},
@@ -159,7 +159,7 @@ func TestRolePermissions(t *testing.T) {
159159
Actions: []rbac.Action{rbac.ActionCreate, rbac.ActionUpdate, rbac.ActionDelete},
160160
Resource: rbac.ResourceUser,
161161
AuthorizeMap: map[bool][]authSubject{
162-
true: {admin, userAdmin},
162+
true: {owner, userAdmin},
163163
false: {memberMe, orgMemberMe, orgAdmin, otherOrgMember, otherOrgAdmin, templateAdmin},
164164
},
165165
},
@@ -169,7 +169,7 @@ func TestRolePermissions(t *testing.T) {
169169
Actions: []rbac.Action{rbac.ActionCreate, rbac.ActionRead, rbac.ActionUpdate, rbac.ActionDelete},
170170
Resource: rbac.ResourceWorkspace.InOrg(orgID).WithOwner(currentUser.String()),
171171
AuthorizeMap: map[bool][]authSubject{
172-
true: {admin, orgMemberMe, orgAdmin, templateAdmin},
172+
true: {owner, orgMemberMe, orgAdmin, templateAdmin},
173173
false: {memberMe, otherOrgAdmin, otherOrgMember, userAdmin},
174174
},
175175
},
@@ -179,7 +179,7 @@ func TestRolePermissions(t *testing.T) {
179179
Actions: []rbac.Action{rbac.ActionCreate, rbac.ActionRead, rbac.ActionUpdate, rbac.ActionDelete},
180180
Resource: rbac.ResourceWorkspaceExecution.InOrg(orgID).WithOwner(currentUser.String()),
181181
AuthorizeMap: map[bool][]authSubject{
182-
true: {admin, orgAdmin, orgMemberMe},
182+
true: {owner, orgAdmin, orgMemberMe},
183183
false: {memberMe, otherOrgAdmin, otherOrgMember, templateAdmin, userAdmin},
184184
},
185185
},
@@ -188,7 +188,7 @@ func TestRolePermissions(t *testing.T) {
188188
Actions: []rbac.Action{rbac.ActionCreate, rbac.ActionUpdate, rbac.ActionDelete},
189189
Resource: rbac.ResourceTemplate.InOrg(orgID),
190190
AuthorizeMap: map[bool][]authSubject{
191-
true: {admin, orgAdmin, templateAdmin},
191+
true: {owner, orgAdmin, templateAdmin},
192192
false: {memberMe, orgMemberMe, otherOrgAdmin, otherOrgMember, userAdmin},
193193
},
194194
},
@@ -197,7 +197,7 @@ func TestRolePermissions(t *testing.T) {
197197
Actions: []rbac.Action{rbac.ActionRead},
198198
Resource: rbac.ResourceTemplate.InOrg(orgID),
199199
AuthorizeMap: map[bool][]authSubject{
200-
true: {admin, orgMemberMe, orgAdmin, templateAdmin},
200+
true: {owner, orgMemberMe, orgAdmin, templateAdmin},
201201
false: {memberMe, otherOrgAdmin, otherOrgMember, userAdmin},
202202
},
203203
},
@@ -206,7 +206,7 @@ func TestRolePermissions(t *testing.T) {
206206
Actions: []rbac.Action{rbac.ActionCreate},
207207
Resource: rbac.ResourceFile,
208208
AuthorizeMap: map[bool][]authSubject{
209-
true: {admin, templateAdmin},
209+
true: {owner, templateAdmin},
210210
false: {orgMemberMe, orgAdmin, memberMe, otherOrgAdmin, otherOrgMember, userAdmin},
211211
},
212212
},
@@ -215,7 +215,7 @@ func TestRolePermissions(t *testing.T) {
215215
Actions: []rbac.Action{rbac.ActionRead, rbac.ActionUpdate, rbac.ActionDelete},
216216
Resource: rbac.ResourceFile.WithOwner(currentUser.String()),
217217
AuthorizeMap: map[bool][]authSubject{
218-
true: {admin, memberMe, orgMemberMe, templateAdmin},
218+
true: {owner, memberMe, orgMemberMe, templateAdmin},
219219
false: {orgAdmin, otherOrgAdmin, otherOrgMember, userAdmin},
220220
},
221221
},
@@ -224,7 +224,7 @@ func TestRolePermissions(t *testing.T) {
224224
Actions: []rbac.Action{rbac.ActionCreate},
225225
Resource: rbac.ResourceOrganization,
226226
AuthorizeMap: map[bool][]authSubject{
227-
true: {admin},
227+
true: {owner},
228228
false: {orgAdmin, otherOrgAdmin, otherOrgMember, memberMe, orgMemberMe, templateAdmin, userAdmin},
229229
},
230230
},
@@ -233,7 +233,7 @@ func TestRolePermissions(t *testing.T) {
233233
Actions: []rbac.Action{rbac.ActionUpdate, rbac.ActionDelete},
234234
Resource: rbac.ResourceOrganization.InOrg(orgID),
235235
AuthorizeMap: map[bool][]authSubject{
236-
true: {admin, orgAdmin},
236+
true: {owner, orgAdmin},
237237
false: {otherOrgAdmin, otherOrgMember, memberMe, orgMemberMe, templateAdmin, userAdmin},
238238
},
239239
},
@@ -242,7 +242,7 @@ func TestRolePermissions(t *testing.T) {
242242
Actions: []rbac.Action{rbac.ActionRead},
243243
Resource: rbac.ResourceOrganization.InOrg(orgID),
244244
AuthorizeMap: map[bool][]authSubject{
245-
true: {admin, orgAdmin, orgMemberMe},
245+
true: {owner, orgAdmin, orgMemberMe},
246246
false: {otherOrgAdmin, otherOrgMember, memberMe, templateAdmin, userAdmin},
247247
},
248248
},
@@ -251,16 +251,16 @@ func TestRolePermissions(t *testing.T) {
251251
Actions: []rbac.Action{rbac.ActionCreate, rbac.ActionUpdate, rbac.ActionDelete},
252252
Resource: rbac.ResourceRoleAssignment,
253253
AuthorizeMap: map[bool][]authSubject{
254-
true: {admin},
255-
false: {orgAdmin, orgMemberMe, otherOrgAdmin, otherOrgMember, memberMe, templateAdmin, userAdmin},
254+
true: {owner, userAdmin},
255+
false: {orgAdmin, orgMemberMe, otherOrgAdmin, otherOrgMember, memberMe, templateAdmin},
256256
},
257257
},
258258
{
259259
Name: "ReadRoleAssignment",
260260
Actions: []rbac.Action{rbac.ActionRead},
261261
Resource: rbac.ResourceRoleAssignment,
262262
AuthorizeMap: map[bool][]authSubject{
263-
true: {admin, orgAdmin, orgMemberMe, otherOrgAdmin, otherOrgMember, memberMe, templateAdmin, userAdmin},
263+
true: {owner, orgAdmin, orgMemberMe, otherOrgAdmin, otherOrgMember, memberMe, templateAdmin, userAdmin},
264264
false: {},
265265
},
266266
},
@@ -269,7 +269,7 @@ func TestRolePermissions(t *testing.T) {
269269
Actions: []rbac.Action{rbac.ActionCreate, rbac.ActionUpdate, rbac.ActionDelete},
270270
Resource: rbac.ResourceOrgRoleAssignment.InOrg(orgID),
271271
AuthorizeMap: map[bool][]authSubject{
272-
true: {admin, orgAdmin},
272+
true: {owner, orgAdmin},
273273
false: {orgMemberMe, otherOrgAdmin, otherOrgMember, memberMe, templateAdmin, userAdmin},
274274
},
275275
},
@@ -278,7 +278,7 @@ func TestRolePermissions(t *testing.T) {
278278
Actions: []rbac.Action{rbac.ActionRead},
279279
Resource: rbac.ResourceOrgRoleAssignment.InOrg(orgID),
280280
AuthorizeMap: map[bool][]authSubject{
281-
true: {admin, orgAdmin, orgMemberMe},
281+
true: {owner, orgAdmin, orgMemberMe},
282282
false: {otherOrgAdmin, otherOrgMember, memberMe, templateAdmin, userAdmin},
283283
},
284284
},
@@ -287,7 +287,7 @@ func TestRolePermissions(t *testing.T) {
287287
Actions: []rbac.Action{rbac.ActionCreate, rbac.ActionRead, rbac.ActionUpdate, rbac.ActionDelete},
288288
Resource: rbac.ResourceAPIKey.WithOwner(currentUser.String()),
289289
AuthorizeMap: map[bool][]authSubject{
290-
true: {admin, orgMemberMe, memberMe},
290+
true: {owner, orgMemberMe, memberMe},
291291
false: {orgAdmin, otherOrgAdmin, otherOrgMember, templateAdmin, userAdmin},
292292
},
293293
},
@@ -296,7 +296,7 @@ func TestRolePermissions(t *testing.T) {
296296
Actions: []rbac.Action{rbac.ActionCreate, rbac.ActionRead, rbac.ActionUpdate, rbac.ActionDelete},
297297
Resource: rbac.ResourceUserData.WithOwner(currentUser.String()),
298298
AuthorizeMap: map[bool][]authSubject{
299-
true: {admin, orgMemberMe, memberMe},
299+
true: {owner, orgMemberMe, memberMe},
300300
false: {orgAdmin, otherOrgAdmin, otherOrgMember, templateAdmin, userAdmin},
301301
},
302302
},
@@ -305,17 +305,17 @@ func TestRolePermissions(t *testing.T) {
305305
Actions: []rbac.Action{rbac.ActionCreate, rbac.ActionUpdate, rbac.ActionDelete},
306306
Resource: rbac.ResourceOrganizationMember.InOrg(orgID),
307307
AuthorizeMap: map[bool][]authSubject{
308-
true: {admin, orgAdmin},
309-
false: {orgMemberMe, memberMe, otherOrgAdmin, otherOrgMember, templateAdmin, userAdmin},
308+
true: {owner, orgAdmin, userAdmin},
309+
false: {orgMemberMe, memberMe, otherOrgAdmin, otherOrgMember, templateAdmin},
310310
},
311311
},
312312
{
313313
Name: "ReadOrgMember",
314314
Actions: []rbac.Action{rbac.ActionRead},
315315
Resource: rbac.ResourceOrganizationMember.InOrg(orgID),
316316
AuthorizeMap: map[bool][]authSubject{
317-
true: {admin, orgAdmin, orgMemberMe},
318-
false: {memberMe, otherOrgAdmin, otherOrgMember, templateAdmin, userAdmin},
317+
true: {owner, orgAdmin, orgMemberMe, userAdmin},
318+
false: {memberMe, otherOrgAdmin, otherOrgMember, templateAdmin},
319319
},
320320
},
321321
}

coderd/roles.go

Lines changed: 12 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -20,14 +20,7 @@ func (api *API) assignableSiteRoles(rw http.ResponseWriter, r *http.Request) {
2020
}
2121

2222
roles := rbac.SiteRoles()
23-
assignable := make([]rbac.Role, 0)
24-
for _, role := range roles {
25-
if rbac.CanAssignRole(actorRoles.Roles, role.Name) {
26-
assignable = append(assignable, role)
27-
}
28-
}
29-
30-
httpapi.Write(rw, http.StatusOK, convertRoles(assignable))
23+
httpapi.Write(rw, http.StatusOK, assignableRoles(actorRoles.Roles, roles))
3124
}
3225

3326
// assignableSiteRoles returns all site wide roles that can be assigned.
@@ -41,14 +34,7 @@ func (api *API) assignableOrgRoles(rw http.ResponseWriter, r *http.Request) {
4134
}
4235

4336
roles := rbac.OrganizationRoles(organization.ID)
44-
assignable := make([]rbac.Role, 0)
45-
for _, role := range roles {
46-
if rbac.CanAssignRole(actorRoles.Roles, role.Name) {
47-
assignable = append(assignable, role)
48-
}
49-
}
50-
51-
httpapi.Write(rw, http.StatusOK, convertRoles(assignable))
37+
httpapi.Write(rw, http.StatusOK, assignableRoles(actorRoles.Roles, roles))
5238
}
5339

5440
func (api *API) checkPermissions(rw http.ResponseWriter, r *http.Request) {
@@ -102,14 +88,19 @@ func convertRole(role rbac.Role) codersdk.Role {
10288
}
10389
}
10490

105-
func convertRoles(roles []rbac.Role) []codersdk.Role {
106-
converted := make([]codersdk.Role, 0, len(roles))
91+
func assignableRoles(actorRoles []string, roles []rbac.Role) []codersdk.AssignableRoles {
92+
assignable := make([]codersdk.AssignableRoles, 0)
10793
for _, role := range roles {
108-
// Roles without display names should never be shown to the ui.
10994
if role.DisplayName == "" {
11095
continue
11196
}
112-
converted = append(converted, convertRole(role))
97+
assignable = append(assignable, codersdk.AssignableRoles{
98+
Role: codersdk.Role{
99+
Name: role.Name,
100+
DisplayName: role.DisplayName,
101+
},
102+
Assignable: rbac.CanAssignRole(actorRoles, role.Name),
103+
})
113104
}
114-
return converted
105+
return assignable
115106
}

0 commit comments

Comments
 (0)