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

Commite2a3d15

Browse files
committed
auth-filter query
1 parenta279cef commite2a3d15

File tree

12 files changed

+178
-55
lines changed

12 files changed

+178
-55
lines changed

‎coderd/database/dbauthz/dbauthz.go

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2766,7 +2766,11 @@ func (q *querier) GetWorkspaces(ctx context.Context, arg database.GetWorkspacesP
27662766
}
27672767

27682768
func (q*querier)GetWorkspacesAndAgentsByOwnerID(ctx context.Context,ownerID uuid.UUID) ([]database.GetWorkspacesAndAgentsByOwnerIDRow,error) {
2769-
returnq.db.GetWorkspacesAndAgentsByOwnerID(ctx,ownerID)
2769+
prep,err:=prepareSQLFilter(ctx,q.auth,policy.ActionRead,rbac.ResourceWorkspace.Type)
2770+
iferr!=nil {
2771+
returnnil,xerrors.Errorf("(dev error) prepare sql filter: %w",err)
2772+
}
2773+
returnq.db.GetAuthorizedWorkspacesAndAgentsByOwnerID(ctx,ownerID,prep)
27702774
}
27712775

27722776
func (q*querier)GetWorkspacesEligibleForTransition(ctx context.Context,now time.Time) ([]database.WorkspaceTable,error) {
@@ -4222,6 +4226,10 @@ func (q *querier) GetAuthorizedWorkspaces(ctx context.Context, arg database.GetW
42224226
returnq.GetWorkspaces(ctx,arg)
42234227
}
42244228

4229+
func (q*querier)GetAuthorizedWorkspacesAndAgentsByOwnerID(ctx context.Context,ownerID uuid.UUID,_ rbac.PreparedAuthorized) ([]database.GetWorkspacesAndAgentsByOwnerIDRow,error) {
4230+
returnq.GetWorkspacesAndAgentsByOwnerID(ctx,ownerID)
4231+
}
4232+
42254233
// GetAuthorizedUsers is not required for dbauthz since GetUsers is already
42264234
// authenticated.
42274235
func (q*querier)GetAuthorizedUsers(ctx context.Context,arg database.GetUsersParams,_ rbac.PreparedAuthorized) ([]database.GetUsersRow,error) {

‎coderd/database/dbauthz/dbauthz_test.go

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1478,6 +1478,14 @@ func (s *MethodTestSuite) TestWorkspace() {
14781478
_=dbgen.WorkspaceAgent(s.T(),db, database.WorkspaceAgent{ResourceID:res.ID})
14791479
check.Args(ws.OwnerID).Asserts()
14801480
}))
1481+
s.Run("GetAuthorizedWorkspacesAndAgentsByOwnerID",s.Subtest(func(db database.Store,check*expects) {
1482+
ws:=dbgen.Workspace(s.T(),db, database.WorkspaceTable{})
1483+
build:=dbgen.WorkspaceBuild(s.T(),db, database.WorkspaceBuild{WorkspaceID:ws.ID,JobID:uuid.New()})
1484+
_=dbgen.ProvisionerJob(s.T(),db,nil, database.ProvisionerJob{ID:build.JobID,Type:database.ProvisionerJobTypeWorkspaceBuild})
1485+
res:=dbgen.WorkspaceResource(s.T(),db, database.WorkspaceResource{JobID:build.JobID})
1486+
_=dbgen.WorkspaceAgent(s.T(),db, database.WorkspaceAgent{ResourceID:res.ID})
1487+
check.Args(ws.OwnerID,emptyPreparedAuthorized{}).Asserts()
1488+
}))
14811489
s.Run("GetLatestWorkspaceBuildByWorkspaceID",s.Subtest(func(db database.Store,check*expects) {
14821490
ws:=dbgen.Workspace(s.T(),db, database.WorkspaceTable{})
14831491
b:=dbgen.WorkspaceBuild(s.T(),db, database.WorkspaceBuild{WorkspaceID:ws.ID})

‎coderd/database/dbmem/dbmem.go

Lines changed: 63 additions & 51 deletions
Original file line numberDiff line numberDiff line change
@@ -6840,57 +6840,8 @@ func (q *FakeQuerier) GetWorkspaces(ctx context.Context, arg database.GetWorkspa
68406840
}
68416841

68426842
func (q*FakeQuerier)GetWorkspacesAndAgentsByOwnerID(ctx context.Context,ownerID uuid.UUID) ([]database.GetWorkspacesAndAgentsByOwnerIDRow,error) {
6843-
q.mutex.RLock()
6844-
deferq.mutex.RUnlock()
6845-
6846-
workspaces:=make([]database.WorkspaceTable,0)
6847-
for_,workspace:=rangeq.workspaces {
6848-
ifworkspace.OwnerID==ownerID&&!workspace.Deleted {
6849-
workspaces=append(workspaces,workspace)
6850-
}
6851-
}
6852-
6853-
out:=make([]database.GetWorkspacesAndAgentsByOwnerIDRow,0,len(workspaces))
6854-
for_,w:=rangeworkspaces {
6855-
// these always exist
6856-
build,err:=q.getLatestWorkspaceBuildByWorkspaceIDNoLock(ctx,w.ID)
6857-
iferr!=nil {
6858-
returnnil,xerrors.Errorf("get latest build: %w",err)
6859-
}
6860-
6861-
job,err:=q.getProvisionerJobByIDNoLock(ctx,build.JobID)
6862-
iferr!=nil {
6863-
returnnil,xerrors.Errorf("get provisioner job: %w",err)
6864-
}
6865-
6866-
outAgents:=make([]database.AgentIDNamePair,0)
6867-
resources,err:=q.getWorkspaceResourcesByJobIDNoLock(ctx,job.ID)
6868-
iferr!=nil {
6869-
returnnil,xerrors.Errorf("get workspace resources: %w",err)
6870-
}
6871-
iflen(resources)>0 {
6872-
agents,err:=q.getWorkspaceAgentsByResourceIDsNoLock(ctx, []uuid.UUID{resources[0].ID})
6873-
iferr!=nil {
6874-
returnnil,xerrors.Errorf("get workspace agents: %w",err)
6875-
}
6876-
for_,a:=rangeagents {
6877-
outAgents=append(outAgents, database.AgentIDNamePair{
6878-
ID:a.ID,
6879-
Name:a.Name,
6880-
})
6881-
}
6882-
}
6883-
6884-
out=append(out, database.GetWorkspacesAndAgentsByOwnerIDRow{
6885-
ID:w.ID,
6886-
Name:w.Name,
6887-
JobStatus:job.JobStatus,
6888-
Transition:build.Transition,
6889-
Agents:outAgents,
6890-
})
6891-
}
6892-
6893-
returnout,nil
6843+
// No auth filter.
6844+
returnq.GetAuthorizedWorkspacesAndAgentsByOwnerID(ctx,ownerID,nil)
68946845
}
68956846

68966847
func (q*FakeQuerier)GetWorkspacesEligibleForTransition(ctx context.Context,now time.Time) ([]database.WorkspaceTable,error) {
@@ -11272,6 +11223,67 @@ func (q *FakeQuerier) GetAuthorizedWorkspaces(ctx context.Context, arg database.
1127211223
returnq.convertToWorkspaceRowsNoLock(ctx,workspaces,int64(beforePageCount),arg.WithSummary),nil
1127311224
}
1127411225

11226+
func (q*FakeQuerier)GetAuthorizedWorkspacesAndAgentsByOwnerID(ctx context.Context,ownerID uuid.UUID,prepared rbac.PreparedAuthorized) ([]database.GetWorkspacesAndAgentsByOwnerIDRow,error) {
11227+
q.mutex.RLock()
11228+
deferq.mutex.RUnlock()
11229+
11230+
ifprepared!=nil {
11231+
// Call this to match the same function calls as the SQL implementation.
11232+
_,err:=prepared.CompileToSQL(ctx,rbac.ConfigWithoutACL())
11233+
iferr!=nil {
11234+
returnnil,err
11235+
}
11236+
}
11237+
workspaces:=make([]database.WorkspaceTable,0)
11238+
for_,workspace:=rangeq.workspaces {
11239+
ifworkspace.OwnerID==ownerID&&!workspace.Deleted {
11240+
workspaces=append(workspaces,workspace)
11241+
}
11242+
}
11243+
11244+
out:=make([]database.GetWorkspacesAndAgentsByOwnerIDRow,0,len(workspaces))
11245+
for_,w:=rangeworkspaces {
11246+
// these always exist
11247+
build,err:=q.getLatestWorkspaceBuildByWorkspaceIDNoLock(ctx,w.ID)
11248+
iferr!=nil {
11249+
returnnil,xerrors.Errorf("get latest build: %w",err)
11250+
}
11251+
11252+
job,err:=q.getProvisionerJobByIDNoLock(ctx,build.JobID)
11253+
iferr!=nil {
11254+
returnnil,xerrors.Errorf("get provisioner job: %w",err)
11255+
}
11256+
11257+
outAgents:=make([]database.AgentIDNamePair,0)
11258+
resources,err:=q.getWorkspaceResourcesByJobIDNoLock(ctx,job.ID)
11259+
iferr!=nil {
11260+
returnnil,xerrors.Errorf("get workspace resources: %w",err)
11261+
}
11262+
iflen(resources)>0 {
11263+
agents,err:=q.getWorkspaceAgentsByResourceIDsNoLock(ctx, []uuid.UUID{resources[0].ID})
11264+
iferr!=nil {
11265+
returnnil,xerrors.Errorf("get workspace agents: %w",err)
11266+
}
11267+
for_,a:=rangeagents {
11268+
outAgents=append(outAgents, database.AgentIDNamePair{
11269+
ID:a.ID,
11270+
Name:a.Name,
11271+
})
11272+
}
11273+
}
11274+
11275+
out=append(out, database.GetWorkspacesAndAgentsByOwnerIDRow{
11276+
ID:w.ID,
11277+
Name:w.Name,
11278+
JobStatus:job.JobStatus,
11279+
Transition:build.Transition,
11280+
Agents:outAgents,
11281+
})
11282+
}
11283+
11284+
returnout,nil
11285+
}
11286+
1127511287
func (q*FakeQuerier)GetAuthorizedUsers(ctx context.Context,arg database.GetUsersParams,prepared rbac.PreparedAuthorized) ([]database.GetUsersRow,error) {
1127611288
iferr:=validateDatabaseType(arg);err!=nil {
1127711289
returnnil,err

‎coderd/database/dbmetrics/querymetrics.go

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

‎coderd/database/dbmock/dbmock.go

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

‎coderd/database/modelqueries.go

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -221,6 +221,7 @@ func (q *sqlQuerier) GetTemplateGroupRoles(ctx context.Context, id uuid.UUID) ([
221221

222222
typeworkspaceQuerierinterface {
223223
GetAuthorizedWorkspaces(ctx context.Context,argGetWorkspacesParams,prepared rbac.PreparedAuthorized) ([]GetWorkspacesRow,error)
224+
GetAuthorizedWorkspacesAndAgentsByOwnerID(ctx context.Context,ownerID uuid.UUID,prepared rbac.PreparedAuthorized) ([]GetWorkspacesAndAgentsByOwnerIDRow,error)
224225
}
225226

226227
// GetAuthorizedWorkspaces returns all workspaces that the user is authorized to access.
@@ -320,6 +321,49 @@ func (q *sqlQuerier) GetAuthorizedWorkspaces(ctx context.Context, arg GetWorkspa
320321
returnitems,nil
321322
}
322323

324+
func (q*sqlQuerier)GetAuthorizedWorkspacesAndAgentsByOwnerID(ctx context.Context,ownerID uuid.UUID,prepared rbac.PreparedAuthorized) ([]GetWorkspacesAndAgentsByOwnerIDRow,error) {
325+
authorizedFilter,err:=prepared.CompileToSQL(ctx,rbac.ConfigWorkspaces())
326+
iferr!=nil {
327+
returnnil,xerrors.Errorf("compile authorized filter: %w",err)
328+
}
329+
330+
// In order to properly use ORDER BY, OFFSET, and LIMIT, we need to inject the
331+
// authorizedFilter between the end of the where clause and those statements.
332+
filtered,err:=insertAuthorizedFilter(getWorkspacesAndAgentsByOwnerID,fmt.Sprintf(" AND %s",authorizedFilter))
333+
iferr!=nil {
334+
returnnil,xerrors.Errorf("insert authorized filter: %w",err)
335+
}
336+
337+
// The name comment is for metric tracking
338+
query:=fmt.Sprintf("-- name: GetAuthorizedWorkspacesAndAgentsByOwnerID :many\n%s",filtered)
339+
rows,err:=q.db.QueryContext(ctx,query,ownerID)
340+
iferr!=nil {
341+
returnnil,err
342+
}
343+
deferrows.Close()
344+
varitems []GetWorkspacesAndAgentsByOwnerIDRow
345+
forrows.Next() {
346+
variGetWorkspacesAndAgentsByOwnerIDRow
347+
iferr:=rows.Scan(
348+
&i.ID,
349+
&i.Name,
350+
&i.JobStatus,
351+
&i.Transition,
352+
pq.Array(&i.Agents),
353+
);err!=nil {
354+
returnnil,err
355+
}
356+
items=append(items,i)
357+
}
358+
iferr:=rows.Close();err!=nil {
359+
returnnil,err
360+
}
361+
iferr:=rows.Err();err!=nil {
362+
returnnil,err
363+
}
364+
returnitems,nil
365+
}
366+
323367
typeuserQuerierinterface {
324368
GetAuthorizedUsers(ctx context.Context,argGetUsersParams,prepared rbac.PreparedAuthorized) ([]GetUsersRow,error)
325369
}

‎coderd/database/querier.go

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more aboutcustomizing how changed files appear on GitHub.

‎coderd/database/querier_test.go

Lines changed: 20 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,9 @@ import (
2424
"github.com/coder/coder/v2/coderd/database/dbtestutil"
2525
"github.com/coder/coder/v2/coderd/database/dbtime"
2626
"github.com/coder/coder/v2/coderd/database/migrations"
27+
"github.com/coder/coder/v2/coderd/httpmw"
2728
"github.com/coder/coder/v2/coderd/rbac"
29+
"github.com/coder/coder/v2/coderd/rbac/policy"
2830
"github.com/coder/coder/v2/testutil"
2931
)
3032

@@ -612,7 +614,7 @@ func TestGetWorkspaceAgentUsageStatsAndLabels(t *testing.T) {
612614
})
613615
}
614616

615-
funcTestGetWorkspacesAndAgentsByOwnerID(t*testing.T) {
617+
funcTestGetAuthorizedWorkspacesAndAgentsByOwnerID(t*testing.T) {
616618
t.Parallel()
617619
iftesting.Short() {
618620
t.SkipNow()
@@ -628,6 +630,7 @@ func TestGetWorkspacesAndAgentsByOwnerID(t *testing.T) {
628630
owner:=dbgen.User(t,db, database.User{
629631
RBACRoles: []string{rbac.RoleOwner().String()},
630632
})
633+
user:=dbgen.User(t,db, database.User{})
631634
tpl:=dbgen.Template(t,db, database.Template{
632635
OrganizationID:org.ID,
633636
CreatedBy:owner.ID,
@@ -666,7 +669,22 @@ func TestGetWorkspacesAndAgentsByOwnerID(t *testing.T) {
666669
CreateAgent:false,
667670
})
668671

669-
ownerRows,err:=db.GetWorkspacesAndAgentsByOwnerID(ctx,owner.ID)
672+
authorizer:=rbac.NewStrictCachingAuthorizer(prometheus.NewRegistry())
673+
userSubject,_,err:=httpmw.UserRBACSubject(ctx,db,user.ID,rbac.ExpandableScope(rbac.ScopeAll))
674+
require.NoError(t,err)
675+
preparedUser,err:=authorizer.Prepare(ctx,userSubject,policy.ActionRead,rbac.ResourceWorkspace.Type)
676+
require.NoError(t,err)
677+
userCtx:=dbauthz.As(ctx,userSubject)
678+
userRows,err:=db.GetAuthorizedWorkspacesAndAgentsByOwnerID(userCtx,owner.ID,preparedUser)
679+
require.NoError(t,err)
680+
require.Len(t,userRows,0)
681+
682+
ownerSubject,_,err:=httpmw.UserRBACSubject(ctx,db,owner.ID,rbac.ExpandableScope(rbac.ScopeAll))
683+
require.NoError(t,err)
684+
preparedOwner,err:=authorizer.Prepare(ctx,ownerSubject,policy.ActionRead,rbac.ResourceWorkspace.Type)
685+
require.NoError(t,err)
686+
ownerCtx:=dbauthz.As(ctx,ownerSubject)
687+
ownerRows,err:=db.GetAuthorizedWorkspacesAndAgentsByOwnerID(ownerCtx,owner.ID,preparedOwner)
670688
require.NoError(t,err)
671689
require.Len(t,ownerRows,4)
672690
for_,row:=rangeownerRows {

‎coderd/database/queries.sql.go

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

‎coderd/database/queries/workspaces.sql

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -724,6 +724,8 @@ WHERE
724724
-- Filter by owner_id
725725
workspaces.owner_id= @owner_id :: uuid
726726
ANDworkspaces.deleted= false
727+
-- Authorize Filter clause will be injected below in GetAuthorizedWorkspacesAndAgentsByOwnerID
728+
-- @authorize_filter
727729
GROUP BYworkspaces.id,workspaces.name,latest_build.job_status,latest_build.job_id,latest_build.transition;
728730

729731

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp