Skip to content

Commit c04d045

Browse files
authored
feat: RBAC provisionerdaemons and parameters (#1755)
* chore: Remove org_id from provisionerdaemons
1 parent 104d07f commit c04d045

18 files changed

+184
-63
lines changed

coderd/coderd.go

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -131,14 +131,20 @@ func New(options *Options) *API {
131131
r.Get("/{hash}", api.fileByHash)
132132
r.Post("/", api.postFile)
133133
})
134+
r.Route("/provisionerdaemons", func(r chi.Router) {
135+
r.Use(
136+
apiKeyMiddleware,
137+
authRolesMiddleware,
138+
)
139+
r.Get("/", api.provisionerDaemons)
140+
})
134141
r.Route("/organizations/{organization}", func(r chi.Router) {
135142
r.Use(
136143
apiKeyMiddleware,
137144
httpmw.ExtractOrganizationParam(options.Database),
138145
authRolesMiddleware,
139146
)
140147
r.Get("/", api.organization)
141-
r.Get("/provisionerdaemons", api.provisionerDaemonsByOrganization)
142148
r.Post("/templateversions", api.postTemplateVersionsByOrganization)
143149
r.Route("/templates", func(r chi.Router) {
144150
r.Post("/", api.postTemplateByOrganization)
@@ -166,7 +172,7 @@ func New(options *Options) *API {
166172
})
167173
})
168174
r.Route("/parameters/{scope}/{id}", func(r chi.Router) {
169-
r.Use(apiKeyMiddleware)
175+
r.Use(apiKeyMiddleware, authRolesMiddleware)
170176
r.Post("/", api.postParameter)
171177
r.Get("/", api.parameters)
172178
r.Route("/{name}", func(r chi.Router) {

coderd/coderd_test.go

Lines changed: 51 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ import (
66
"net/http"
77
"strings"
88
"testing"
9+
"time"
910

1011
"github.com/go-chi/chi/v5"
1112
"github.com/stretchr/testify/assert"
@@ -45,9 +46,29 @@ func TestAuthorizeAllEndpoints(t *testing.T) {
4546
IncludeProvisionerD: true,
4647
})
4748
admin := coderdtest.CreateFirstUser(t, client)
48-
organization, err := client.Organization(context.Background(), admin.OrganizationID)
49+
// The provisioner will call to coderd and register itself. This is async,
50+
// so we wait for it to occur.
51+
require.Eventually(t, func() bool {
52+
provisionerds, err := client.ProvisionerDaemons(ctx)
53+
require.NoError(t, err)
54+
return len(provisionerds) > 0
55+
}, time.Second*10, time.Second)
56+
57+
provisionerds, err := client.ProvisionerDaemons(ctx)
58+
require.NoError(t, err, "fetch provisioners")
59+
require.Len(t, provisionerds, 1)
60+
61+
organization, err := client.Organization(ctx, admin.OrganizationID)
4962
require.NoError(t, err, "fetch org")
5063

64+
organizationParam, err := client.CreateParameter(ctx, codersdk.ParameterOrganization, organization.ID, codersdk.CreateParameterRequest{
65+
Name: "test-param",
66+
SourceValue: "hello world",
67+
SourceScheme: codersdk.ParameterSourceSchemeData,
68+
DestinationScheme: codersdk.ParameterDestinationSchemeProvisionerVariable,
69+
})
70+
require.NoError(t, err, "create org param")
71+
5172
// Setup some data in the database.
5273
version := coderdtest.CreateTemplateVersion(t, client, admin.OrganizationID, &echo.Responses{
5374
Parse: echo.ParseComplete,
@@ -118,18 +139,10 @@ func TestAuthorizeAllEndpoints(t *testing.T) {
118139
"GET:/api/v2/workspaceagents/{workspaceagent}/turn": {NoAuthorize: true},
119140

120141
// TODO: @emyrk these need to be fixed by adding authorize calls
121-
"GET:/api/v2/organizations/{organization}/provisionerdaemons": {NoAuthorize: true},
122-
"GET:/api/v2/organizations/{organization}/templates/{templatename}": {NoAuthorize: true},
123-
"POST:/api/v2/organizations/{organization}/templateversions": {NoAuthorize: true},
124-
"POST:/api/v2/organizations/{organization}/workspaces": {NoAuthorize: true},
125-
126-
"POST:/api/v2/parameters/{scope}/{id}": {NoAuthorize: true},
127-
"GET:/api/v2/parameters/{scope}/{id}": {NoAuthorize: true},
128-
"DELETE:/api/v2/parameters/{scope}/{id}/{name}": {NoAuthorize: true},
129-
130-
"POST:/api/v2/users/{user}/organizations": {NoAuthorize: true},
131-
132-
"GET:/api/v2/workspaces/{workspace}/watch": {NoAuthorize: true},
142+
"POST:/api/v2/organizations/{organization}/workspaces": {NoAuthorize: true},
143+
"POST:/api/v2/users/{user}/organizations": {NoAuthorize: true},
144+
"GET:/api/v2/workspaces/{workspace}/watch": {NoAuthorize: true},
145+
"POST:/api/v2/organizations/{organization}/templateversions": {NoAuthorize: true},
133146

134147
// These endpoints have more assertions. This is good, add more endpoints to assert if you can!
135148
"GET:/api/v2/organizations/{organization}": {AssertObject: rbac.ResourceOrganization.InOrg(admin.OrganizationID)},
@@ -251,6 +264,27 @@ func TestAuthorizeAllEndpoints(t *testing.T) {
251264
AssertAction: rbac.ActionRead,
252265
AssertObject: rbac.ResourceTemplate.InOrg(template.OrganizationID).WithID(template.ID.String()),
253266
},
267+
"GET:/api/v2/provisionerdaemons": {
268+
StatusCode: http.StatusOK,
269+
AssertObject: rbac.ResourceProvisionerDaemon.WithID(provisionerds[0].ID.String()),
270+
},
271+
272+
"POST:/api/v2/parameters/{scope}/{id}": {
273+
AssertAction: rbac.ActionUpdate,
274+
AssertObject: rbac.ResourceOrganization.WithID(organization.ID.String()),
275+
},
276+
"GET:/api/v2/parameters/{scope}/{id}": {
277+
AssertAction: rbac.ActionRead,
278+
AssertObject: rbac.ResourceOrganization.WithID(organization.ID.String()),
279+
},
280+
"DELETE:/api/v2/parameters/{scope}/{id}/{name}": {
281+
AssertAction: rbac.ActionUpdate,
282+
AssertObject: rbac.ResourceOrganization.WithID(organization.ID.String()),
283+
},
284+
"GET:/api/v2/organizations/{organization}/templates/{templatename}": {
285+
AssertAction: rbac.ActionRead,
286+
AssertObject: rbac.ResourceTemplate.InOrg(template.OrganizationID).WithID(template.ID.String()),
287+
},
254288

255289
// These endpoints need payloads to get to the auth part. Payloads will be required
256290
"PUT:/api/v2/users/{user}/roles": {StatusCode: http.StatusBadRequest, NoAuthorize: true},
@@ -292,6 +326,10 @@ func TestAuthorizeAllEndpoints(t *testing.T) {
292326
route = strings.ReplaceAll(route, "{hash}", file.Hash)
293327
route = strings.ReplaceAll(route, "{workspaceresource}", workspaceResources[0].ID.String())
294328
route = strings.ReplaceAll(route, "{templateversion}", version.ID.String())
329+
route = strings.ReplaceAll(route, "{templatename}", template.Name)
330+
// Only checking org scoped params here
331+
route = strings.ReplaceAll(route, "{scope}", string(organizationParam.Scope))
332+
route = strings.ReplaceAll(route, "{id}", organizationParam.ScopeID.String())
295333

296334
resp, err := client.Request(context.Background(), method, route, nil)
297335
require.NoError(t, err, "do req")

coderd/database/databasefake/databasefake.go

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1283,11 +1283,10 @@ func (q *fakeQuerier) InsertProvisionerDaemon(_ context.Context, arg database.In
12831283
defer q.mutex.Unlock()
12841284

12851285
daemon := database.ProvisionerDaemon{
1286-
ID: arg.ID,
1287-
CreatedAt: arg.CreatedAt,
1288-
OrganizationID: arg.OrganizationID,
1289-
Name: arg.Name,
1290-
Provisioners: arg.Provisioners,
1286+
ID: arg.ID,
1287+
CreatedAt: arg.CreatedAt,
1288+
Name: arg.Name,
1289+
Provisioners: arg.Provisioners,
12911290
}
12921291
q.provisionerDaemons = append(q.provisionerDaemons, daemon)
12931292
return daemon, nil

coderd/database/dump.sql

Lines changed: 0 additions & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
ALTER TABLE provisioner_daemons ADD COLUMN organization_id uuid;
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
ALTER TABLE provisioner_daemons DROP COLUMN organization_id;

coderd/database/modelmethods.go

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,3 +22,7 @@ func (m OrganizationMember) RBACObject() rbac.Object {
2222
func (o Organization) RBACObject() rbac.Object {
2323
return rbac.ResourceOrganization.InOrg(o.ID).WithID(o.ID.String())
2424
}
25+
26+
func (d ProvisionerDaemon) RBACObject() rbac.Object {
27+
return rbac.ResourceProvisionerDaemon.WithID(d.ID.String())
28+
}

coderd/database/models.go

Lines changed: 5 additions & 6 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

coderd/database/queries.sql.go

Lines changed: 7 additions & 13 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

coderd/database/queries/provisionerdaemons.sql

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -17,12 +17,11 @@ INSERT INTO
1717
provisioner_daemons (
1818
id,
1919
created_at,
20-
organization_id,
2120
"name",
2221
provisioners
2322
)
2423
VALUES
25-
($1, $2, $3, $4, $5) RETURNING *;
24+
($1, $2, $3, $4) RETURNING *;
2625

2726
-- name: UpdateProvisionerDaemonByID :exec
2827
UPDATE

0 commit comments

Comments
 (0)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy