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

Commit144f374

Browse files
authored
refactor(dbauthz): add authz for system-level functions (#6513)
- Introduces rbac.ResourceSystem- Grants system.* to system and provisionerd rbac subjects- Updates dbauthz system queries where applicable- coderd: Avoid index out of bounds in api.workspaceBuilds- dbauthz: move GetUsersByIDs out of system, modify RBAC check to ResourceUser- workspaceapps: Add test case for when owner of app is not found
1 parent1db2b12 commit144f374

File tree

17 files changed

+470
-200
lines changed

17 files changed

+470
-200
lines changed

‎coderd/coderd.go

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -795,7 +795,8 @@ func (api *API) CreateInMemoryProvisionerDaemon(ctx context.Context, debounce ti
795795
}()
796796

797797
name:=namesgenerator.GetRandomName(1)
798-
daemon,err:=api.Database.InsertProvisionerDaemon(ctx, database.InsertProvisionerDaemonParams{
798+
// nolint:gocritic // Inserting a provisioner daemon is a system function.
799+
daemon,err:=api.Database.InsertProvisionerDaemon(dbauthz.AsSystemRestricted(ctx), database.InsertProvisionerDaemonParams{
799800
ID:uuid.New(),
800801
CreatedAt:database.Now(),
801802
Name:name,

‎coderd/database/dbauthz/dbauthz.go

Lines changed: 29 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -115,17 +115,17 @@ func ActorFromContext(ctx context.Context) (rbac.Subject, bool) {
115115
returna,ok
116116
}
117117

118-
// AsProvisionerd returns a context with an actor that has permissions required
119-
// for provisionerd to function.
120-
funcAsProvisionerd(ctx context.Context) context.Context {
121-
returncontext.WithValue(ctx,authContextKey{}, rbac.Subject{
118+
var (
119+
subjectProvisionerd= rbac.Subject{
122120
ID:uuid.Nil.String(),
123121
Roles:rbac.Roles([]rbac.Role{
124122
{
125123
Name:"provisionerd",
126124
DisplayName:"Provisioner Daemon",
127125
Site:rbac.Permissions(map[string][]rbac.Action{
126+
// TODO: Add ProvisionerJob resource type.
128127
rbac.ResourceFile.Type: {rbac.ActionRead},
128+
rbac.ResourceSystem.Type: {rbac.WildcardSymbol},
129129
rbac.ResourceTemplate.Type: {rbac.ActionRead,rbac.ActionUpdate},
130130
rbac.ResourceUser.Type: {rbac.ActionRead},
131131
rbac.ResourceWorkspace.Type: {rbac.ActionRead,rbac.ActionUpdate,rbac.ActionDelete},
@@ -135,20 +135,15 @@ func AsProvisionerd(ctx context.Context) context.Context {
135135
},
136136
}),
137137
Scope:rbac.ScopeAll,
138-
},
139-
)
140-
}
141-
142-
// AsAutostart returns a context with an actor that has permissions required
143-
// for autostart to function.
144-
funcAsAutostart(ctx context.Context) context.Context {
145-
returncontext.WithValue(ctx,authContextKey{}, rbac.Subject{
138+
}
139+
subjectAutostart= rbac.Subject{
146140
ID:uuid.Nil.String(),
147141
Roles:rbac.Roles([]rbac.Role{
148142
{
149143
Name:"autostart",
150144
DisplayName:"Autostart Daemon",
151145
Site:rbac.Permissions(map[string][]rbac.Action{
146+
rbac.ResourceSystem.Type: {rbac.WildcardSymbol},
152147
rbac.ResourceTemplate.Type: {rbac.ActionRead,rbac.ActionUpdate},
153148
rbac.ResourceWorkspace.Type: {rbac.ActionRead,rbac.ActionUpdate},
154149
}),
@@ -157,14 +152,8 @@ func AsAutostart(ctx context.Context) context.Context {
157152
},
158153
}),
159154
Scope:rbac.ScopeAll,
160-
},
161-
)
162-
}
163-
164-
// AsSystemRestricted returns a context with an actor that has permissions
165-
// required for various system operations (login, logout, metrics cache).
166-
funcAsSystemRestricted(ctx context.Context) context.Context {
167-
returncontext.WithValue(ctx,authContextKey{}, rbac.Subject{
155+
}
156+
subjectSystemRestricted= rbac.Subject{
168157
ID:uuid.Nil.String(),
169158
Roles:rbac.Roles([]rbac.Role{
170159
{
@@ -175,6 +164,7 @@ func AsSystemRestricted(ctx context.Context) context.Context {
175164
rbac.ResourceAPIKey.Type: {rbac.ActionCreate,rbac.ActionUpdate,rbac.ActionDelete},
176165
rbac.ResourceGroup.Type: {rbac.ActionCreate,rbac.ActionUpdate},
177166
rbac.ResourceRoleAssignment.Type: {rbac.ActionCreate},
167+
rbac.ResourceSystem.Type: {rbac.WildcardSymbol},
178168
rbac.ResourceOrganization.Type: {rbac.ActionCreate},
179169
rbac.ResourceOrganizationMember.Type: {rbac.ActionCreate},
180170
rbac.ResourceOrgRoleAssignment.Type: {rbac.ActionCreate},
@@ -187,8 +177,25 @@ func AsSystemRestricted(ctx context.Context) context.Context {
187177
},
188178
}),
189179
Scope:rbac.ScopeAll,
190-
},
191-
)
180+
}
181+
)
182+
183+
// AsProvisionerd returns a context with an actor that has permissions required
184+
// for provisionerd to function.
185+
funcAsProvisionerd(ctx context.Context) context.Context {
186+
returncontext.WithValue(ctx,authContextKey{},subjectProvisionerd)
187+
}
188+
189+
// AsAutostart returns a context with an actor that has permissions required
190+
// for autostart to function.
191+
funcAsAutostart(ctx context.Context) context.Context {
192+
returncontext.WithValue(ctx,authContextKey{},subjectAutostart)
193+
}
194+
195+
// AsSystemRestricted returns a context with an actor that has permissions
196+
// required for various system operations (login, logout, metrics cache).
197+
funcAsSystemRestricted(ctx context.Context) context.Context {
198+
returncontext.WithValue(ctx,authContextKey{},subjectSystemRestricted)
192199
}
193200

194201
varAsRemoveActor= rbac.Subject{

‎coderd/database/dbauthz/querier.go

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -963,6 +963,18 @@ func (q *querier) GetUserByID(ctx context.Context, id uuid.UUID) (database.User,
963963
returnfetch(q.log,q.auth,q.db.GetUserByID)(ctx,id)
964964
}
965965

966+
// GetUsersByIDs is only used for usernames on workspace return data.
967+
// This function should be replaced by joining this data to the workspace query
968+
// itself.
969+
func (q*querier)GetUsersByIDs(ctx context.Context,ids []uuid.UUID) ([]database.User,error) {
970+
for_,uid:=rangeids {
971+
iferr:=q.authorizeContext(ctx,rbac.ActionRead,rbac.ResourceUser.WithID(uid));err!=nil {
972+
returnnil,err
973+
}
974+
}
975+
returnq.db.GetUsersByIDs(ctx,ids)
976+
}
977+
966978
func (q*querier)GetAuthorizedUserCount(ctx context.Context,arg database.GetFilteredUserCountParams,prepared rbac.PreparedAuthorized) (int64,error) {
967979
returnq.db.GetAuthorizedUserCount(ctx,arg,prepared)
968980
}

‎coderd/database/dbauthz/querier_test.go

Lines changed: 7 additions & 74 deletions
Original file line numberDiff line numberDiff line change
@@ -282,11 +282,6 @@ func (s *MethodTestSuite) TestProvsionerJob() {
282282
check.Args(database.UpdateProvisionerJobWithCancelByIDParams{ID:j.ID}).
283283
Asserts(v.RBACObject(tpl), []rbac.Action{rbac.ActionRead,rbac.ActionUpdate}).Returns()
284284
}))
285-
s.Run("GetProvisionerJobsByIDs",s.Subtest(func(db database.Store,check*expects) {
286-
a:=dbgen.ProvisionerJob(s.T(),db, database.ProvisionerJob{})
287-
b:=dbgen.ProvisionerJob(s.T(),db, database.ProvisionerJob{})
288-
check.Args([]uuid.UUID{a.ID,b.ID}).Asserts().Returns(slice.New(a,b))
289-
}))
290285
s.Run("GetProvisionerLogsByIDBetween",s.Subtest(func(db database.Store,check*expects) {
291286
w:=dbgen.Workspace(s.T(),db, database.Workspace{})
292287
j:=dbgen.ProvisionerJob(s.T(),db, database.ProvisionerJob{
@@ -619,22 +614,6 @@ func (s *MethodTestSuite) TestTemplate() {
619614
})
620615
check.Args(tv.ID).Asserts(t1,rbac.ActionRead).Returns(tv)
621616
}))
622-
s.Run("GetTemplateVersionsByIDs",s.Subtest(func(db database.Store,check*expects) {
623-
t1:=dbgen.Template(s.T(),db, database.Template{})
624-
t2:=dbgen.Template(s.T(),db, database.Template{})
625-
tv1:=dbgen.TemplateVersion(s.T(),db, database.TemplateVersion{
626-
TemplateID: uuid.NullUUID{UUID:t1.ID,Valid:true},
627-
})
628-
tv2:=dbgen.TemplateVersion(s.T(),db, database.TemplateVersion{
629-
TemplateID: uuid.NullUUID{UUID:t2.ID,Valid:true},
630-
})
631-
tv3:=dbgen.TemplateVersion(s.T(),db, database.TemplateVersion{
632-
TemplateID: uuid.NullUUID{UUID:t2.ID,Valid:true},
633-
})
634-
check.Args([]uuid.UUID{tv1.ID,tv2.ID,tv3.ID}).
635-
Asserts(/*t1, rbac.ActionRead, t2, rbac.ActionRead*/ ).
636-
Returns(slice.New(tv1,tv2,tv3))
637-
}))
638617
s.Run("GetTemplateVersionsByTemplateID",s.Subtest(func(db database.Store,check*expects) {
639618
t1:=dbgen.Template(s.T(),db, database.Template{})
640619
a:=dbgen.TemplateVersion(s.T(),db, database.TemplateVersion{
@@ -784,6 +763,13 @@ func (s *MethodTestSuite) TestUser() {
784763
u:=dbgen.User(s.T(),db, database.User{})
785764
check.Args(u.ID).Asserts(u,rbac.ActionRead).Returns(u)
786765
}))
766+
s.Run("GetUsersByIDs",s.Subtest(func(db database.Store,check*expects) {
767+
a:=dbgen.User(s.T(),db, database.User{CreatedAt:database.Now().Add(-time.Hour)})
768+
b:=dbgen.User(s.T(),db, database.User{CreatedAt:database.Now()})
769+
check.Args([]uuid.UUID{a.ID,b.ID}).
770+
Asserts(a,rbac.ActionRead,b,rbac.ActionRead).
771+
Returns(slice.New(a,b))
772+
}))
787773
s.Run("GetAuthorizedUserCount",s.Subtest(func(db database.Store,check*expects) {
788774
_=dbgen.User(s.T(),db, database.User{})
789775
check.Args(database.GetFilteredUserCountParams{},emptyPreparedAuthorized{}).Asserts().Returns(int64(1))
@@ -803,13 +789,6 @@ func (s *MethodTestSuite) TestUser() {
803789
b:=dbgen.User(s.T(),db, database.User{CreatedAt:database.Now()})
804790
check.Args(database.GetUsersParams{}).Asserts(a,rbac.ActionRead,b,rbac.ActionRead)
805791
}))
806-
s.Run("GetUsersByIDs",s.Subtest(func(db database.Store,check*expects) {
807-
a:=dbgen.User(s.T(),db, database.User{CreatedAt:database.Now().Add(-time.Hour)})
808-
b:=dbgen.User(s.T(),db, database.User{CreatedAt:database.Now()})
809-
check.Args([]uuid.UUID{a.ID,b.ID}).
810-
Asserts(/*a, rbac.ActionRead, b, rbac.ActionRead*/ ).
811-
Returns(slice.New(a,b))
812-
}))
813792
s.Run("InsertUser",s.Subtest(func(db database.Store,check*expects) {
814793
check.Args(database.InsertUserParams{
815794
ID:uuid.New(),
@@ -977,14 +956,6 @@ func (s *MethodTestSuite) TestWorkspace() {
977956
agt:=dbgen.WorkspaceAgent(s.T(),db, database.WorkspaceAgent{ResourceID:res.ID})
978957
check.Args(agt.AuthInstanceID.String).Asserts(ws,rbac.ActionRead).Returns(agt)
979958
}))
980-
s.Run("GetWorkspaceAgentsByResourceIDs",s.Subtest(func(db database.Store,check*expects) {
981-
ws:=dbgen.Workspace(s.T(),db, database.Workspace{})
982-
build:=dbgen.WorkspaceBuild(s.T(),db, database.WorkspaceBuild{WorkspaceID:ws.ID,JobID:uuid.New()})
983-
res:=dbgen.WorkspaceResource(s.T(),db, database.WorkspaceResource{JobID:build.JobID})
984-
agt:=dbgen.WorkspaceAgent(s.T(),db, database.WorkspaceAgent{ResourceID:res.ID})
985-
check.Args([]uuid.UUID{res.ID}).Asserts(/*ws, rbac.ActionRead*/ ).
986-
Returns([]database.WorkspaceAgent{agt})
987-
}))
988959
s.Run("UpdateWorkspaceAgentLifecycleStateByID",s.Subtest(func(db database.Store,check*expects) {
989960
ws:=dbgen.Workspace(s.T(),db, database.Workspace{})
990961
build:=dbgen.WorkspaceBuild(s.T(),db, database.WorkspaceBuild{WorkspaceID:ws.ID,JobID:uuid.New()})
@@ -1026,23 +997,6 @@ func (s *MethodTestSuite) TestWorkspace() {
1026997

1027998
check.Args(agt.ID).Asserts(ws,rbac.ActionRead).Returns(slice.New(a,b))
1028999
}))
1029-
s.Run("GetWorkspaceAppsByAgentIDs",s.Subtest(func(db database.Store,check*expects) {
1030-
aWs:=dbgen.Workspace(s.T(),db, database.Workspace{})
1031-
aBuild:=dbgen.WorkspaceBuild(s.T(),db, database.WorkspaceBuild{WorkspaceID:aWs.ID,JobID:uuid.New()})
1032-
aRes:=dbgen.WorkspaceResource(s.T(),db, database.WorkspaceResource{JobID:aBuild.JobID})
1033-
aAgt:=dbgen.WorkspaceAgent(s.T(),db, database.WorkspaceAgent{ResourceID:aRes.ID})
1034-
a:=dbgen.WorkspaceApp(s.T(),db, database.WorkspaceApp{AgentID:aAgt.ID})
1035-
1036-
bWs:=dbgen.Workspace(s.T(),db, database.Workspace{})
1037-
bBuild:=dbgen.WorkspaceBuild(s.T(),db, database.WorkspaceBuild{WorkspaceID:bWs.ID,JobID:uuid.New()})
1038-
bRes:=dbgen.WorkspaceResource(s.T(),db, database.WorkspaceResource{JobID:bBuild.JobID})
1039-
bAgt:=dbgen.WorkspaceAgent(s.T(),db, database.WorkspaceAgent{ResourceID:bRes.ID})
1040-
b:=dbgen.WorkspaceApp(s.T(),db, database.WorkspaceApp{AgentID:bAgt.ID})
1041-
1042-
check.Args([]uuid.UUID{a.AgentID,b.AgentID}).
1043-
Asserts(/*aWs, rbac.ActionRead, bWs, rbac.ActionRead*/ ).
1044-
Returns([]database.WorkspaceApp{a,b})
1045-
}))
10461000
s.Run("GetWorkspaceBuildByID",s.Subtest(func(db database.Store,check*expects) {
10471001
ws:=dbgen.Workspace(s.T(),db, database.Workspace{})
10481002
build:=dbgen.WorkspaceBuild(s.T(),db, database.WorkspaceBuild{WorkspaceID:ws.ID})
@@ -1096,15 +1050,6 @@ func (s *MethodTestSuite) TestWorkspace() {
10961050
res:=dbgen.WorkspaceResource(s.T(),db, database.WorkspaceResource{JobID:build.JobID})
10971051
check.Args(res.ID).Asserts(ws,rbac.ActionRead).Returns(res)
10981052
}))
1099-
s.Run("GetWorkspaceResourceMetadataByResourceIDs",s.Subtest(func(db database.Store,check*expects) {
1100-
ws:=dbgen.Workspace(s.T(),db, database.Workspace{})
1101-
build:=dbgen.WorkspaceBuild(s.T(),db, database.WorkspaceBuild{WorkspaceID:ws.ID,JobID:uuid.New()})
1102-
_=dbgen.ProvisionerJob(s.T(),db, database.ProvisionerJob{ID:build.JobID,Type:database.ProvisionerJobTypeWorkspaceBuild})
1103-
a:=dbgen.WorkspaceResource(s.T(),db, database.WorkspaceResource{JobID:build.JobID})
1104-
b:=dbgen.WorkspaceResource(s.T(),db, database.WorkspaceResource{JobID:build.JobID})
1105-
check.Args([]uuid.UUID{a.ID,b.ID}).
1106-
Asserts(/*ws, []rbac.Action{rbac.ActionRead, rbac.ActionRead}*/ )
1107-
}))
11081053
s.Run("Build/GetWorkspaceResourcesByJobID",s.Subtest(func(db database.Store,check*expects) {
11091054
ws:=dbgen.Workspace(s.T(),db, database.Workspace{})
11101055
build:=dbgen.WorkspaceBuild(s.T(),db, database.WorkspaceBuild{WorkspaceID:ws.ID,JobID:uuid.New()})
@@ -1117,18 +1062,6 @@ func (s *MethodTestSuite) TestWorkspace() {
11171062
job:=dbgen.ProvisionerJob(s.T(),db, database.ProvisionerJob{ID:v.JobID,Type:database.ProvisionerJobTypeTemplateVersionImport})
11181063
check.Args(job.ID).Asserts(v.RBACObject(tpl), []rbac.Action{rbac.ActionRead,rbac.ActionRead}).Returns([]database.WorkspaceResource{})
11191064
}))
1120-
s.Run("GetWorkspaceResourcesByJobIDs",s.Subtest(func(db database.Store,check*expects) {
1121-
tpl:=dbgen.Template(s.T(),db, database.Template{})
1122-
v:=dbgen.TemplateVersion(s.T(),db, database.TemplateVersion{TemplateID: uuid.NullUUID{UUID:tpl.ID,Valid:true},JobID:uuid.New()})
1123-
tJob:=dbgen.ProvisionerJob(s.T(),db, database.ProvisionerJob{ID:v.JobID,Type:database.ProvisionerJobTypeTemplateVersionImport})
1124-
1125-
ws:=dbgen.Workspace(s.T(),db, database.Workspace{})
1126-
build:=dbgen.WorkspaceBuild(s.T(),db, database.WorkspaceBuild{WorkspaceID:ws.ID,JobID:uuid.New()})
1127-
wJob:=dbgen.ProvisionerJob(s.T(),db, database.ProvisionerJob{ID:build.JobID,Type:database.ProvisionerJobTypeWorkspaceBuild})
1128-
check.Args([]uuid.UUID{tJob.ID,wJob.ID}).
1129-
Asserts(/*v.RBACObject(tpl), rbac.ActionRead, ws, rbac.ActionRead*/ ).
1130-
Returns([]database.WorkspaceResource{})
1131-
}))
11321065
s.Run("InsertWorkspace",s.Subtest(func(db database.Store,check*expects) {
11331066
u:=dbgen.User(s.T(),db, database.User{})
11341067
o:=dbgen.Organization(s.T(),db, database.Organization{})

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp