diff --git a/cli/provisioners_test.go b/cli/provisioners_test.go index ec528cfeda7cc..30a89714ff57f 100644 --- a/cli/provisioners_test.go +++ b/cli/provisioners_test.go @@ -71,7 +71,7 @@ func TestProvisioners_Golden(t *testing.T) { }) owner := coderdtest.CreateFirstUser(t, client) templateAdminClient, _ := coderdtest.CreateAnotherUser(t, client, owner.OrganizationID, rbac.ScopedRoleOrgTemplateAdmin(owner.OrganizationID)) - memberClient, member := coderdtest.CreateAnotherUser(t, client, owner.OrganizationID) + _, member := coderdtest.CreateAnotherUser(t, client, owner.OrganizationID) // Create initial resources with a running provisioner. firstProvisioner := coderdtest.NewTaggedProvisionerDaemon(t, coderdAPI, "default-provisioner", map[string]string{"owner": "", "scope": "organization"}) @@ -178,8 +178,9 @@ func TestProvisioners_Golden(t *testing.T) { t.Logf("replace[%q] = %q", id, replaceID) } - // Test provisioners list with member as members can access - // provisioner daemons. + // Test provisioners list with template admin as members are currently + // unable to access provisioner jobs. In the future (with RBAC + // changes), we may allow them to view _their_ jobs. t.Run("list", func(t *testing.T) { t.Parallel() @@ -190,7 +191,7 @@ func TestProvisioners_Golden(t *testing.T) { "--column", "id,created at,last seen at,name,version,tags,key name,status,current job id,current job status,previous job id,previous job status,organization", ) inv.Stdout = &got - clitest.SetupConfig(t, memberClient, root) + clitest.SetupConfig(t, templateAdminClient, root) err := inv.Run() require.NoError(t, err) diff --git a/coderd/provisionerdaemons.go b/coderd/provisionerdaemons.go index e701771770091..6495c4eb15bee 100644 --- a/coderd/provisionerdaemons.go +++ b/coderd/provisionerdaemons.go @@ -9,6 +9,8 @@ import ( "github.com/coder/coder/v2/coderd/httpapi" "github.com/coder/coder/v2/coderd/httpmw" "github.com/coder/coder/v2/coderd/provisionerdserver" + "github.com/coder/coder/v2/coderd/rbac" + "github.com/coder/coder/v2/coderd/rbac/policy" "github.com/coder/coder/v2/coderd/util/ptr" "github.com/coder/coder/v2/codersdk" ) @@ -31,6 +33,13 @@ func (api *API) provisionerDaemons(rw http.ResponseWriter, r *http.Request) { org = httpmw.OrganizationParam(r) ) + // This endpoint returns information about provisioner jobs. + // For now, only owners and template admins can access provisioner jobs. + if !api.Authorize(r, policy.ActionRead, rbac.ResourceProvisionerJobs.InOrg(org.ID)) { + httpapi.ResourceNotFound(rw) + return + } + qp := r.URL.Query() p := httpapi.NewQueryParamParser() limit := p.PositiveInt32(qp, 50, "limit") diff --git a/coderd/provisionerdaemons_test.go b/coderd/provisionerdaemons_test.go index 6496b4dd57e0a..d6d1138f7a912 100644 --- a/coderd/provisionerdaemons_test.go +++ b/coderd/provisionerdaemons_test.go @@ -241,11 +241,14 @@ func TestProvisionerDaemons(t *testing.T) { require.Nil(t, daemons[0].PreviousJob) }) - t.Run("MemberAllowed", func(t *testing.T) { + // For now, this is not allowed even though the member has created a + // workspace. Once member-level permissions for jobs are supported + // by RBAC, this test should be updated. + t.Run("MemberDenied", func(t *testing.T) { t.Parallel() ctx := testutil.Context(t, testutil.WaitMedium) daemons, err := memberClient.OrganizationProvisionerDaemons(ctx, owner.OrganizationID, nil) - require.NoError(t, err) - require.Len(t, daemons, 50) + require.Error(t, err) + require.Len(t, daemons, 0) }) } diff --git a/enterprise/coderd/provisionerdaemons_test.go b/enterprise/coderd/provisionerdaemons_test.go index 20d784467591f..0cd812b45c5f1 100644 --- a/enterprise/coderd/provisionerdaemons_test.go +++ b/enterprise/coderd/provisionerdaemons_test.go @@ -953,7 +953,7 @@ func TestGetProvisionerDaemons(t *testing.T) { org := coderdenttest.CreateOrganization(t, client, coderdenttest.CreateOrganizationOptions{ IncludeProvisionerDaemon: false, }) - orgAdmin, _ := coderdtest.CreateAnotherUser(t, client, org.ID, rbac.ScopedRoleOrgMember(org.ID)) + orgTemplateAdmin, _ := coderdtest.CreateAnotherUser(t, client, org.ID, rbac.ScopedRoleOrgTemplateAdmin(org.ID)) daemonCreatedAt := time.Now() @@ -986,11 +986,11 @@ func TestGetProvisionerDaemons(t *testing.T) { require.NoError(t, err, "should be able to create provisioner daemon") daemonAsCreated := db2sdk.ProvisionerDaemon(pd) - allDaemons, err := orgAdmin.OrganizationProvisionerDaemons(ctx, org.ID, nil) + allDaemons, err := orgTemplateAdmin.OrganizationProvisionerDaemons(ctx, org.ID, nil) require.NoError(t, err) require.Len(t, allDaemons, 1) - daemonsAsFound, err := orgAdmin.OrganizationProvisionerDaemons(ctx, org.ID, &codersdk.OrganizationProvisionerDaemonsOptions{ + daemonsAsFound, err := orgTemplateAdmin.OrganizationProvisionerDaemons(ctx, org.ID, &codersdk.OrganizationProvisionerDaemonsOptions{ Tags: tt.tagsToFilterBy, }) if tt.expectToGetDaemon {