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

Commite05480d

Browse files
committed
feat: POC for allowing TemplateAdmin to delete prebuild workspaces via auth layer
1 parentaf4a668 commite05480d

File tree

10 files changed

+181
-8
lines changed

10 files changed

+181
-8
lines changed

‎coderd/database/dbauthz/dbauthz.go

Lines changed: 18 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -412,6 +412,9 @@ var (
412412
policy.ActionCreate,policy.ActionDelete,policy.ActionRead,policy.ActionUpdate,
413413
policy.ActionWorkspaceStart,policy.ActionWorkspaceStop,
414414
},
415+
rbac.ResourcePrebuiltWorkspace.Type: {
416+
policy.ActionRead,policy.ActionUpdate,policy.ActionDelete,
417+
},
415418
// Should be able to add the prebuilds system user as a member to any organization that needs prebuilds.
416419
rbac.ResourceOrganizationMember.Type: {
417420
policy.ActionCreate,
@@ -3909,7 +3912,11 @@ func (q *querier) InsertWorkspaceBuild(ctx context.Context, arg database.InsertW
39093912
action=policy.ActionWorkspaceStop
39103913
}
39113914

3912-
iferr=q.authorizeContext(ctx,action,w);err!=nil {
3915+
ifaction==policy.ActionDelete&&w.IsPrebuild() {
3916+
iferr:=q.authorizeContext(ctx,action,w.PrebuildRBAC());err!=nil {
3917+
returnxerrors.Errorf("authorize context: %w",err)
3918+
}
3919+
}elseiferr=q.authorizeContext(ctx,action,w);err!=nil {
39133920
returnxerrors.Errorf("authorize context: %w",err)
39143921
}
39153922

@@ -3927,7 +3934,11 @@ func (q *querier) InsertWorkspaceBuild(ctx context.Context, arg database.InsertW
39273934
// to use a non-active version then we must fail the request.
39283935
ifaccessControl.RequireActiveVersion {
39293936
ifarg.TemplateVersionID!=t.ActiveVersionID {
3930-
iferr=q.authorizeContext(ctx,policy.ActionUpdate,t);err!=nil {
3937+
ifw.IsPrebuild() {
3938+
iferr:=q.authorizeContext(ctx,policy.ActionUpdate,w.PrebuildRBAC());err!=nil {
3939+
returnxerrors.Errorf("cannot use non-active version: %w",err)
3940+
}
3941+
}elseiferr=q.authorizeContext(ctx,policy.ActionUpdate,t);err!=nil {
39313942
returnxerrors.Errorf("cannot use non-active version: %w",err)
39323943
}
39333944
}
@@ -3949,7 +3960,11 @@ func (q *querier) InsertWorkspaceBuildParameters(ctx context.Context, arg databa
39493960
returnerr
39503961
}
39513962

3952-
err=q.authorizeContext(ctx,policy.ActionUpdate,workspace)
3963+
ifworkspace.IsPrebuild() {
3964+
err=q.authorizeContext(ctx,policy.ActionUpdate,workspace.PrebuildRBAC())
3965+
}else {
3966+
err=q.authorizeContext(ctx,policy.ActionUpdate,workspace)
3967+
}
39533968
iferr!=nil {
39543969
returnerr
39553970
}

‎coderd/database/modelmethods.go

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -226,9 +226,26 @@ func (w Workspace) WorkspaceTable() WorkspaceTable {
226226
}
227227

228228
func (wWorkspace)RBACObject() rbac.Object {
229+
//if w.IsPrebuild() {
230+
//return w.PrebuildRBAC()
231+
//}
229232
returnw.WorkspaceTable().RBACObject()
230233
}
231234

235+
func (wWorkspace)IsPrebuild()bool {
236+
// TODO: avoid import cycle
237+
returnw.OwnerID==uuid.MustParse("c42fdf75-3097-471c-8c33-fb52454d81c0")
238+
}
239+
240+
func (wWorkspace)PrebuildRBAC() rbac.Object {
241+
ifw.IsPrebuild() {
242+
returnrbac.ResourcePrebuiltWorkspace.WithID(w.ID).
243+
InOrg(w.OrganizationID).
244+
WithOwner(w.OwnerID.String())
245+
}
246+
returnw.RBACObject()
247+
}
248+
232249
func (wWorkspaceTable)RBACObject() rbac.Object {
233250
ifw.DormantAt.Valid {
234251
returnw.DormantRBAC()

‎coderd/rbac/object_gen.go

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

‎coderd/rbac/policy/policy.go

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -102,6 +102,13 @@ var RBACPermissions = map[string]PermissionDefinition{
102102
"workspace_dormant": {
103103
Actions:workspaceActions,
104104
},
105+
"prebuilt_workspace": {
106+
Actions:map[Action]ActionDefinition{
107+
ActionRead:actDef("read prebuilt workspace"),
108+
ActionUpdate:actDef("update prebuilt workspace"),
109+
ActionDelete:actDef("delete prebuilt workspace"),
110+
},
111+
},
105112
"workspace_proxy": {
106113
Actions:map[Action]ActionDefinition{
107114
ActionCreate:actDef("create a workspace proxy"),

‎coderd/rbac/roles.go

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -335,8 +335,9 @@ func ReloadBuiltinRoles(opts *RoleOptions) {
335335
ResourceAssignOrgRole.Type: {policy.ActionRead},
336336
ResourceTemplate.Type:ResourceTemplate.AvailableActions(),
337337
// CRUD all files, even those they did not upload.
338-
ResourceFile.Type: {policy.ActionCreate,policy.ActionRead},
339-
ResourceWorkspace.Type: {policy.ActionRead},
338+
ResourceFile.Type: {policy.ActionCreate,policy.ActionRead},
339+
ResourceWorkspace.Type: {policy.ActionRead},
340+
ResourcePrebuiltWorkspace.Type: {policy.ActionRead,policy.ActionUpdate,policy.ActionDelete},
340341
// CRUD to provisioner daemons for now.
341342
ResourceProvisionerDaemon.Type: {policy.ActionCreate,policy.ActionRead,policy.ActionUpdate,policy.ActionDelete},
342343
// Needs to read all organizations since
@@ -493,9 +494,10 @@ func ReloadBuiltinRoles(opts *RoleOptions) {
493494
Site: []Permission{},
494495
Org:map[string][]Permission{
495496
organizationID.String():Permissions(map[string][]policy.Action{
496-
ResourceTemplate.Type:ResourceTemplate.AvailableActions(),
497-
ResourceFile.Type: {policy.ActionCreate,policy.ActionRead},
498-
ResourceWorkspace.Type: {policy.ActionRead},
497+
ResourceTemplate.Type:ResourceTemplate.AvailableActions(),
498+
ResourceFile.Type: {policy.ActionCreate,policy.ActionRead},
499+
ResourceWorkspace.Type: {policy.ActionRead},
500+
ResourcePrebuiltWorkspace.Type: {policy.ActionRead,policy.ActionUpdate,policy.ActionDelete},
499501
// Assigning template perms requires this permission.
500502
ResourceOrganization.Type: {policy.ActionRead},
501503
ResourceOrganizationMember.Type: {policy.ActionRead},

‎coderd/workspacebuilds.go

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -404,6 +404,11 @@ func (api *API) postWorkspaceBuilds(rw http.ResponseWriter, r *http.Request) {
404404
ctx,
405405
tx,
406406
func(action policy.Action,object rbac.Objecter)bool {
407+
ifobject.RBACObject().Type==rbac.ResourceWorkspace.Type&&action==policy.ActionDelete {
408+
workspaceObj:=object.(database.Workspace)
409+
prebuild:=workspaceObj.PrebuildRBAC()
410+
returnapi.Authorize(r,action,prebuild)
411+
}
407412
returnapi.Authorize(r,action,object)
408413
},
409414
audit.WorkspaceBuildBaggageFromRequest(r),

‎codersdk/rbacresources_gen.go

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

‎enterprise/coderd/prebuilds/reconcile_test.go

Lines changed: 108 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,12 @@ import (
88
"testing"
99
"time"
1010

11+
"github.com/coder/coder/v2/coderd/coderdtest"
12+
"github.com/coder/coder/v2/coderd/rbac"
13+
"github.com/coder/coder/v2/enterprise/coderd/coderdenttest"
14+
"github.com/coder/coder/v2/enterprise/coderd/license"
15+
"github.com/coder/coder/v2/provisionersdk"
16+
1117
"github.com/prometheus/client_golang/prometheus"
1218
"github.com/stretchr/testify/assert"
1319
"golang.org/x/xerrors"
@@ -420,6 +426,108 @@ func TestPrebuildReconciliation(t *testing.T) {
420426
}
421427
}
422428

429+
funcTestTemplateAdminDelete(t*testing.T) {
430+
t.Parallel()
431+
432+
if!dbtestutil.WillUsePostgres() {
433+
t.Skip("This test requires postgres")
434+
}
435+
436+
t.Run("template admin delete prebuilds",func(t*testing.T) {
437+
t.Parallel()
438+
439+
clock:=quartz.NewMock(t)
440+
441+
// Setup.
442+
ctx:=testutil.Context(t,testutil.WaitSuperLong)
443+
db,pubsub:=dbtestutil.NewDB(t)
444+
445+
spy:=newStoreSpy(db,nil)
446+
447+
logger:=testutil.Logger(t)
448+
client,_,api,owner:=coderdenttest.NewWithAPI(t,&coderdenttest.Options{
449+
Options:&coderdtest.Options{
450+
Database:spy,
451+
Pubsub:pubsub,
452+
},
453+
LicenseOptions:&coderdenttest.LicenseOptions{
454+
Features: license.Features{
455+
codersdk.FeatureExternalProvisionerDaemons:1,
456+
},
457+
},
458+
459+
EntitlementsUpdateInterval:time.Second,
460+
})
461+
462+
orgID:=owner.OrganizationID
463+
464+
provisionerCloser:=coderdenttest.NewExternalProvisionerDaemon(t,client,orgID,map[string]string{
465+
provisionersdk.TagScope:provisionersdk.ScopeOrganization,
466+
})
467+
deferprovisionerCloser.Close()
468+
469+
reconciler:=prebuilds.NewStoreReconciler(spy,pubsub, codersdk.PrebuildsConfig{},logger,clock,prometheus.NewRegistry(),newNoopEnqueuer())
470+
varclaimer agplprebuilds.Claimer=prebuilds.NewEnterpriseClaimer(spy)
471+
api.AGPL.PrebuildsClaimer.Store(&claimer)
472+
473+
version:=coderdtest.CreateTemplateVersion(t,client,orgID,templateWithAgentAndPresetsWithPrebuilds(2))
474+
_=coderdtest.AwaitTemplateVersionJobCompleted(t,client,version.ID)
475+
template:=coderdtest.CreateTemplate(t,client,orgID,version.ID)
476+
presets,err:=client.TemplateVersionPresets(ctx,version.ID)
477+
require.NoError(t,err)
478+
require.Len(t,presets,1)
479+
preset:=setupTestDBPreset(t,db,version.ID,2,"b0rked")
480+
481+
templateAdminClient,_:=coderdtest.CreateAnotherUser(t,client,orgID,rbac.RoleTemplateAdmin())
482+
483+
state,err:=reconciler.SnapshotState(ctx,spy)
484+
require.NoError(t,err)
485+
require.Len(t,state.Presets,2)
486+
487+
for_,preset:=rangepresets {
488+
ps,err:=state.FilterByPreset(preset.ID)
489+
require.NoError(t,err)
490+
require.NotNil(t,ps)
491+
actions,err:=reconciler.CalculateActions(ctx,*ps)
492+
require.NoError(t,err)
493+
require.NotNil(t,actions)
494+
495+
require.NoError(t,reconciler.ReconcilePreset(ctx,*ps))
496+
}
497+
498+
workspace,_:=setupTestDBPrebuild(
499+
t,
500+
clock,
501+
db,
502+
pubsub,
503+
database.WorkspaceTransitionStart,
504+
database.ProvisionerJobStatusSucceeded,
505+
orgID,
506+
preset,
507+
template.ID,
508+
version.ID,
509+
)
510+
511+
require.NoError(t,reconciler.ReconcileAll(ctx))
512+
513+
runningWorkspaces,err:=db.GetRunningPrebuiltWorkspaces(ctx)
514+
require.NoError(t,err)
515+
516+
prebuiltWorkspace,err:=db.GetWorkspaceByID(ctx,runningWorkspaces[0].ID)
517+
require.NoError(t,err)
518+
519+
build,err:=templateAdminClient.CreateWorkspaceBuild(ctx,workspace.ID, codersdk.CreateWorkspaceBuildRequest{
520+
Transition:codersdk.WorkspaceTransitionDelete,
521+
})
522+
require.NoError(t,err,"delete the workspace")
523+
coderdtest.AwaitWorkspaceBuildJobCompleted(t,client,build.ID)
524+
525+
workspaceNew,err:=client.DeletedWorkspace(ctx,prebuiltWorkspace.ID)
526+
require.NoError(t,err)
527+
require.Equal(t,prebuiltWorkspace.ID,workspaceNew.ID)
528+
})
529+
}
530+
423531
// brokenPublisher is used to validate that Publish() calls which always fail do not affect the reconciler's behavior,
424532
// since the messages published are not essential but merely advisory.
425533
typebrokenPublisherstruct {

‎site/src/api/rbacresourcesGenerated.ts

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -123,6 +123,11 @@ export const RBACResourceActions: Partial<
123123
read:"read member",
124124
update:"update an organization member",
125125
},
126+
prebuilt_workspace:{
127+
delete:"delete prebuilt workspace",
128+
read:"read prebuilt workspace",
129+
update:"update prebuilt workspace",
130+
},
126131
provisioner_daemon:{
127132
create:"create a provisioner daemon/key",
128133
delete:"delete a provisioner daemon/key",

‎site/src/api/typesGenerated.ts

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

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp