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

Commitcaeff49

Browse files
authored
chore: refactor roles to support multiple permission sets scoped by org id (#20186)
In preparation for adding the "member" permission level, which will alsobe grouped by org ID, do a bit of a refactor to make room for it and theexisting "org" level to live in the same `map`
1 parent6213b30 commitcaeff49

File tree

15 files changed

+234
-203
lines changed

15 files changed

+234
-203
lines changed

‎coderd/database/db2sdk/db2sdk.go‎

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -693,13 +693,13 @@ func SlimRoleFromName(name string) codersdk.SlimRole {
693693
funcRBACRole(role rbac.Role) codersdk.Role {
694694
slim:=SlimRole(role)
695695

696-
orgPerms:=role.Org[slim.OrganizationID]
696+
orgPerms:=role.ByOrgID[slim.OrganizationID]
697697
return codersdk.Role{
698698
Name:slim.Name,
699699
OrganizationID:slim.OrganizationID,
700700
DisplayName:slim.DisplayName,
701701
SitePermissions:List(role.Site,RBACPermission),
702-
OrganizationPermissions:List(orgPerms,RBACPermission),
702+
OrganizationPermissions:List(orgPerms.Org,RBACPermission),
703703
UserPermissions:List(role.User,RBACPermission),
704704
}
705705
}

‎coderd/database/dbauthz/dbauthz.go‎

Lines changed: 33 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -232,8 +232,8 @@ var (
232232
// Provisionerd creates usage events
233233
rbac.ResourceUsageEvent.Type: {policy.ActionCreate},
234234
}),
235-
Org:map[string][]rbac.Permission{},
236-
User: []rbac.Permission{},
235+
User:[]rbac.Permission{},
236+
ByOrgID:map[string]rbac.OrgPermissions{},
237237
},
238238
}),
239239
Scope:rbac.ScopeAll,
@@ -257,8 +257,8 @@ var (
257257
rbac.ResourceWorkspace.Type: {policy.ActionDelete,policy.ActionRead,policy.ActionUpdate,policy.ActionWorkspaceStart,policy.ActionWorkspaceStop},
258258
rbac.ResourceWorkspaceDormant.Type: {policy.ActionDelete,policy.ActionRead,policy.ActionUpdate,policy.ActionWorkspaceStop},
259259
}),
260-
Org:map[string][]rbac.Permission{},
261-
User: []rbac.Permission{},
260+
User:[]rbac.Permission{},
261+
ByOrgID:map[string]rbac.OrgPermissions{},
262262
},
263263
}),
264264
Scope:rbac.ScopeAll,
@@ -280,8 +280,8 @@ var (
280280
rbac.ResourceWorkspaceDormant.Type: {policy.ActionRead,policy.ActionUpdate},
281281
rbac.ResourceProvisionerJobs.Type: {policy.ActionRead,policy.ActionUpdate},
282282
}),
283-
Org:map[string][]rbac.Permission{},
284-
User: []rbac.Permission{},
283+
User:[]rbac.Permission{},
284+
ByOrgID:map[string]rbac.OrgPermissions{},
285285
},
286286
}),
287287
Scope:rbac.ScopeAll,
@@ -299,8 +299,8 @@ var (
299299
Site:rbac.Permissions(map[string][]policy.Action{
300300
rbac.ResourceCryptoKey.Type: {policy.WildcardSymbol},
301301
}),
302-
Org:map[string][]rbac.Permission{},
303-
User: []rbac.Permission{},
302+
User:[]rbac.Permission{},
303+
ByOrgID:map[string]rbac.OrgPermissions{},
304304
},
305305
}),
306306
Scope:rbac.ScopeAll,
@@ -318,8 +318,8 @@ var (
318318
Site:rbac.Permissions(map[string][]policy.Action{
319319
rbac.ResourceCryptoKey.Type: {policy.WildcardSymbol},
320320
}),
321-
Org:map[string][]rbac.Permission{},
322-
User: []rbac.Permission{},
321+
User:[]rbac.Permission{},
322+
ByOrgID:map[string]rbac.OrgPermissions{},
323323
},
324324
}),
325325
Scope:rbac.ScopeAll,
@@ -336,8 +336,8 @@ var (
336336
Site:rbac.Permissions(map[string][]policy.Action{
337337
rbac.ResourceConnectionLog.Type: {policy.ActionUpdate,policy.ActionRead},
338338
}),
339-
Org:map[string][]rbac.Permission{},
340-
User: []rbac.Permission{},
339+
User:[]rbac.Permission{},
340+
ByOrgID:map[string]rbac.OrgPermissions{},
341341
},
342342
}),
343343
Scope:rbac.ScopeAll,
@@ -357,8 +357,8 @@ var (
357357
rbac.ResourceWebpushSubscription.Type: {policy.ActionCreate,policy.ActionRead,policy.ActionUpdate,policy.ActionDelete},
358358
rbac.ResourceDeploymentConfig.Type: {policy.ActionRead,policy.ActionUpdate},// To read and upsert VAPID keys
359359
}),
360-
Org:map[string][]rbac.Permission{},
361-
User: []rbac.Permission{},
360+
User:[]rbac.Permission{},
361+
ByOrgID:map[string]rbac.OrgPermissions{},
362362
},
363363
}),
364364
Scope:rbac.ScopeAll,
@@ -376,8 +376,8 @@ var (
376376
// The workspace monitor needs to be able to update monitors
377377
rbac.ResourceWorkspaceAgentResourceMonitor.Type: {policy.ActionUpdate},
378378
}),
379-
Org:map[string][]rbac.Permission{},
380-
User: []rbac.Permission{},
379+
User:[]rbac.Permission{},
380+
ByOrgID:map[string]rbac.OrgPermissions{},
381381
},
382382
}),
383383
Scope:rbac.ScopeAll,
@@ -393,12 +393,12 @@ var (
393393
Identifier: rbac.RoleIdentifier{Name:"subagentapi"},
394394
DisplayName:"Sub Agent API",
395395
Site: []rbac.Permission{},
396-
Org:map[string][]rbac.Permission{
397-
orgID.String(): {},
398-
},
399396
User:rbac.Permissions(map[string][]policy.Action{
400397
rbac.ResourceWorkspace.Type: {policy.ActionRead,policy.ActionUpdate,policy.ActionCreateAgent,policy.ActionDeleteAgent},
401398
}),
399+
ByOrgID:map[string]rbac.OrgPermissions{
400+
orgID.String(): {},
401+
},
402402
},
403403
}),
404404
Scope:rbac.ScopeAll,
@@ -437,8 +437,8 @@ var (
437437
rbac.ResourceOauth2App.Type: {policy.ActionCreate,policy.ActionRead,policy.ActionUpdate,policy.ActionDelete},
438438
rbac.ResourceOauth2AppSecret.Type: {policy.ActionCreate,policy.ActionRead,policy.ActionUpdate,policy.ActionDelete},
439439
}),
440-
Org:map[string][]rbac.Permission{},
441-
User: []rbac.Permission{},
440+
User:[]rbac.Permission{},
441+
ByOrgID:map[string]rbac.OrgPermissions{},
442442
},
443443
}),
444444
Scope:rbac.ScopeAll,
@@ -455,8 +455,8 @@ var (
455455
Site:rbac.Permissions(map[string][]policy.Action{
456456
rbac.ResourceProvisionerDaemon.Type: {policy.ActionRead},
457457
}),
458-
Org:map[string][]rbac.Permission{},
459-
User: []rbac.Permission{},
458+
User:[]rbac.Permission{},
459+
ByOrgID:map[string]rbac.OrgPermissions{},
460460
},
461461
}),
462462
Scope:rbac.ScopeAll,
@@ -532,8 +532,8 @@ var (
532532
Site:rbac.Permissions(map[string][]policy.Action{
533533
rbac.ResourceFile.Type: {policy.ActionRead},
534534
}),
535-
Org:map[string][]rbac.Permission{},
536-
User: []rbac.Permission{},
535+
User:[]rbac.Permission{},
536+
ByOrgID:map[string]rbac.OrgPermissions{},
537537
},
538538
}),
539539
Scope:rbac.ScopeAll,
@@ -553,8 +553,8 @@ var (
553553
// reads/processes them.
554554
rbac.ResourceUsageEvent.Type: {policy.ActionRead,policy.ActionUpdate},
555555
}),
556-
Org:map[string][]rbac.Permission{},
557-
User: []rbac.Permission{},
556+
User:[]rbac.Permission{},
557+
ByOrgID:map[string]rbac.OrgPermissions{},
558558
},
559559
}),
560560
Scope:rbac.ScopeAll,
@@ -577,8 +577,8 @@ var (
577577
rbac.ResourceApiKey.Type: {policy.ActionRead},// Validate API keys.
578578
rbac.ResourceAibridgeInterception.Type: {policy.ActionCreate,policy.ActionRead,policy.ActionUpdate},
579579
}),
580-
Org:map[string][]rbac.Permission{},
581-
User: []rbac.Permission{},
580+
User:[]rbac.Permission{},
581+
ByOrgID:map[string]rbac.OrgPermissions{},
582582
},
583583
}),
584584
Scope:rbac.ScopeAll,
@@ -1254,13 +1254,13 @@ func (q *querier) customRoleCheck(ctx context.Context, role database.CustomRole)
12541254
returnxerrors.Errorf("invalid role: %w",err)
12551255
}
12561256

1257-
iflen(rbacRole.Org)>0&&len(rbacRole.Site)>0 {
1257+
iflen(rbacRole.ByOrgID)>0&&len(rbacRole.Site)>0 {
12581258
// This is a choice to keep roles simple. If we allow mixing site and org scoped perms, then knowing who can
12591259
// do what gets more complicated.
12601260
returnxerrors.Errorf("invalid custom role, cannot assign both org and site permissions at the same time")
12611261
}
12621262

1263-
iflen(rbacRole.Org)>1 {
1263+
iflen(rbacRole.ByOrgID)>1 {
12641264
// Again to avoid more complexity in our roles
12651265
returnxerrors.Errorf("invalid custom role, cannot assign permissions to more than 1 org at a time")
12661266
}
@@ -1273,8 +1273,8 @@ func (q *querier) customRoleCheck(ctx context.Context, role database.CustomRole)
12731273
}
12741274
}
12751275

1276-
fororgID,perms:=rangerbacRole.Org {
1277-
for_,orgPerm:=rangeperms {
1276+
fororgID,perms:=rangerbacRole.ByOrgID {
1277+
for_,orgPerm:=rangeperms.Org {
12781278
err:=q.customRoleEscalationCheck(ctx,act,orgPerm, rbac.Object{OrgID:orgID,Type:orgPerm.ResourceType})
12791279
iferr!=nil {
12801280
returnxerrors.Errorf("org=%q: %w",orgID,err)

‎coderd/database/modelmethods.go‎

Lines changed: 9 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -176,8 +176,8 @@ func (s APIKeyScopes) expandRBACScope() (rbac.Scope, error) {
176176
// Identifier is informational; not used in policy evaluation.
177177
Identifier: rbac.RoleIdentifier{Name:"Scope_Multiple"},
178178
Site:nil,
179-
Org:map[string][]rbac.Permission{},
180179
User:nil,
180+
ByOrgID:map[string]rbac.OrgPermissions{},
181181
}
182182

183183
// Collect allow lists for a union after expanding all scopes.
@@ -191,8 +191,10 @@ func (s APIKeyScopes) expandRBACScope() (rbac.Scope, error) {
191191

192192
// Merge role permissions: union by simple concatenation.
193193
merged.Site=append(merged.Site,expanded.Site...)
194-
fororgID,perms:=rangeexpanded.Org {
195-
merged.Org[orgID]=append(merged.Org[orgID],perms...)
194+
fororgID,perms:=rangeexpanded.ByOrgID {
195+
orgPerms:=merged.ByOrgID[orgID]
196+
orgPerms.Org=append(orgPerms.Org,perms.Org...)
197+
merged.ByOrgID[orgID]=orgPerms
196198
}
197199
merged.User=append(merged.User,expanded.User...)
198200

@@ -201,10 +203,11 @@ func (s APIKeyScopes) expandRBACScope() (rbac.Scope, error) {
201203

202204
// De-duplicate permissions across Site/Org/User
203205
merged.Site=rbac.DeduplicatePermissions(merged.Site)
204-
fororgID,perms:=rangemerged.Org {
205-
merged.Org[orgID]=rbac.DeduplicatePermissions(perms)
206-
}
207206
merged.User=rbac.DeduplicatePermissions(merged.User)
207+
fororgID,perms:=rangemerged.ByOrgID {
208+
perms.Org=rbac.DeduplicatePermissions(perms.Org)
209+
merged.ByOrgID[orgID]=perms
210+
}
208211

209212
union,err:=rbac.UnionAllowLists(allowLists...)
210213
iferr!=nil {

‎coderd/rbac/astvalue.go‎

Lines changed: 14 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -157,23 +157,30 @@ func (role Role) regoValue() ast.Value {
157157
ifrole.cachedRegoValue!=nil {
158158
returnrole.cachedRegoValue
159159
}
160-
orgMap:=ast.NewObject()
161-
fork,p:=rangerole.Org {
162-
orgMap.Insert(ast.StringTerm(k),ast.NewTerm(regoSlice(p)))
160+
byOrgIDMap:=ast.NewObject()
161+
fork,p:=rangerole.ByOrgID {
162+
byOrgIDMap.Insert(ast.StringTerm(k),ast.NewTerm(
163+
ast.NewObject(
164+
[2]*ast.Term{
165+
ast.StringTerm("org"),
166+
ast.NewTerm(regoSlice(p.Org)),
167+
},
168+
),
169+
))
163170
}
164171
returnast.NewObject(
165172
[2]*ast.Term{
166173
ast.StringTerm("site"),
167174
ast.NewTerm(regoSlice(role.Site)),
168175
},
169-
[2]*ast.Term{
170-
ast.StringTerm("org"),
171-
ast.NewTerm(orgMap),
172-
},
173176
[2]*ast.Term{
174177
ast.StringTerm("user"),
175178
ast.NewTerm(regoSlice(role.User)),
176179
},
180+
[2]*ast.Term{
181+
ast.StringTerm("by_org_id"),
182+
ast.NewTerm(byOrgIDMap),
183+
},
177184
)
178185
}
179186

‎coderd/rbac/authz_internal_test.go‎

Lines changed: 27 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -633,20 +633,22 @@ func TestAuthorizeDomain(t *testing.T) {
633633
{
634634
Identifier:RoleIdentifier{Name:"ReadOnlyOrgAndUser"},
635635
Site: []Permission{},
636-
Org:map[string][]Permission{
637-
defOrg.String(): {{
638-
Negate:false,
639-
ResourceType:"*",
640-
Action:policy.ActionRead,
641-
}},
642-
},
643636
User: []Permission{
644637
{
645638
Negate:false,
646639
ResourceType:"*",
647640
Action:policy.ActionRead,
648641
},
649642
},
643+
ByOrgID:map[string]OrgPermissions{
644+
defOrg.String(): {
645+
Org: []Permission{{
646+
Negate:false,
647+
ResourceType:"*",
648+
Action:policy.ActionRead,
649+
}},
650+
},
651+
},
650652
},
651653
},
652654
}
@@ -726,12 +728,14 @@ func TestAuthorizeLevels(t *testing.T) {
726728
must(RoleByName(RoleOwner())),
727729
{
728730
Identifier:RoleIdentifier{Name:"org-deny:",OrganizationID:defOrg},
729-
Org:map[string][]Permission{
731+
ByOrgID:map[string]OrgPermissions{
730732
defOrg.String(): {
731-
{
732-
Negate:true,
733-
ResourceType:"*",
734-
Action:"*",
733+
Org: []Permission{
734+
{
735+
Negate:true,
736+
ResourceType:"*",
737+
Action:"*",
738+
},
735739
},
736740
},
737741
},
@@ -926,8 +930,8 @@ func TestAuthorizeScope(t *testing.T) {
926930
// Only read access for workspaces.
927931
ResourceWorkspace.Type: {policy.ActionRead},
928932
}),
929-
Org:map[string][]Permission{},
930-
User: []Permission{},
933+
User:[]Permission{},
934+
ByOrgID:map[string]OrgPermissions{},
931935
},
932936
AllowIDList: []AllowListElement{{Type:ResourceWorkspace.Type,ID:workspaceID.String()}},
933937
},
@@ -1015,8 +1019,8 @@ func TestAuthorizeScope(t *testing.T) {
10151019
// Only read access for workspaces.
10161020
ResourceWorkspace.Type: {policy.ActionCreate},
10171021
}),
1018-
Org:map[string][]Permission{},
1019-
User: []Permission{},
1022+
User:[]Permission{},
1023+
ByOrgID:map[string]OrgPermissions{},
10201024
},
10211025
// Empty string allow_list is allowed for actions like 'create'
10221026
AllowIDList: []AllowListElement{{
@@ -1138,14 +1142,16 @@ func TestAuthorizeScope(t *testing.T) {
11381142
},
11391143
DisplayName:"OrgAndUserScope",
11401144
Site:nil,
1141-
Org:map[string][]Permission{
1142-
defOrg.String():Permissions(map[string][]policy.Action{
1143-
ResourceWorkspace.Type: {policy.ActionRead},
1144-
}),
1145-
},
11461145
User:Permissions(map[string][]policy.Action{
11471146
ResourceUser.Type: {policy.ActionRead},
11481147
}),
1148+
ByOrgID:map[string]OrgPermissions{
1149+
defOrg.String(): {
1150+
Org:Permissions(map[string][]policy.Action{
1151+
ResourceWorkspace.Type: {policy.ActionRead},
1152+
}),
1153+
},
1154+
},
11491155
},
11501156
AllowIDList: []AllowListElement{AllowListAll()},
11511157
},

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp