Skip to content

Commit 6a7b053

Browse files
committed
Pass actor to follow logs for subscriber listen
Also fix some dry run resource fetching in authzquerier
1 parent 4967fe6 commit 6a7b053

File tree

8 files changed

+35
-15
lines changed

8 files changed

+35
-15
lines changed

coderd/authzquery/authz.go

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,7 @@ func authorizedInsertWithReturn[ObjectType any, ArgumentType any,
3838

3939
return func(ctx context.Context, arg ArgumentType) (empty ObjectType, err error) {
4040
// Fetch the rbac subject
41-
act, ok := actorFromContext(ctx)
41+
act, ok := ActorFromContext(ctx)
4242
if !ok {
4343
return empty, xerrors.Errorf("no authorization actor in context")
4444
}
@@ -123,7 +123,7 @@ func authorizedFetchAndQuery[ObjectType rbac.Objecter, ArgumentType any,
123123

124124
return func(ctx context.Context, arg ArgumentType) (empty ObjectType, err error) {
125125
// Fetch the rbac subject
126-
act, ok := actorFromContext(ctx)
126+
act, ok := ActorFromContext(ctx)
127127
if !ok {
128128
return empty, xerrors.Errorf("no authorization actor in context")
129129
}
@@ -172,7 +172,7 @@ func authorizedQuery[ArgumentType any, ObjectType rbac.Objecter,
172172

173173
return func(ctx context.Context, arg ArgumentType) (empty ObjectType, err error) {
174174
// Fetch the rbac subject
175-
act, ok := actorFromContext(ctx)
175+
act, ok := ActorFromContext(ctx)
176176
if !ok {
177177
return empty, xerrors.Errorf("no authorization actor in context")
178178
}
@@ -203,7 +203,7 @@ func authorizedFetchSet[ArgumentType any, ObjectType rbac.Objecter,
203203

204204
return func(ctx context.Context, arg ArgumentType) (empty []ObjectType, err error) {
205205
// Fetch the rbac subject
206-
act, ok := actorFromContext(ctx)
206+
act, ok := ActorFromContext(ctx)
207207
if !ok {
208208
return empty, xerrors.Errorf("no authorization actor in context")
209209
}
@@ -234,7 +234,7 @@ func authorizedQueryWithRelated[ObjectType any, ArgumentType any, Related rbac.O
234234

235235
return func(ctx context.Context, arg ArgumentType) (empty ObjectType, err error) {
236236
// Fetch the rbac subject
237-
act, ok := actorFromContext(ctx)
237+
act, ok := ActorFromContext(ctx)
238238
if !ok {
239239
return empty, xerrors.Errorf("no authorization actor in context")
240240
}
@@ -264,7 +264,7 @@ func authorizedQueryWithRelated[ObjectType any, ArgumentType any, Related rbac.O
264264
// prepareSQLFilter is a helper function that prepares a SQL filter using the
265265
// given authorization context.
266266
func prepareSQLFilter(ctx context.Context, authorizer rbac.Authorizer, action rbac.Action, resourceType string) (rbac.PreparedAuthorized, error) {
267-
act, ok := actorFromContext(ctx)
267+
act, ok := ActorFromContext(ctx)
268268
if !ok {
269269
return nil, xerrors.Errorf("no authorization actor in context")
270270
}

coderd/authzquery/authzquerier.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -52,7 +52,7 @@ func (q *AuthzQuerier) InTx(function func(querier database.Store) error, txOpts
5252

5353
// authorizeContext is a helper function to authorize an action on an object.
5454
func (q *AuthzQuerier) authorizeContext(ctx context.Context, action rbac.Action, object rbac.Objecter) error {
55-
act, ok := actorFromContext(ctx)
55+
act, ok := ActorFromContext(ctx)
5656
if !ok {
5757
return xerrors.Errorf("no authorization actor in context")
5858
}

coderd/authzquery/context.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -53,10 +53,10 @@ func WithWorkspaceAgentTokenContext(ctx context.Context, workspaceID uuid.UUID,
5353
})
5454
}
5555

56-
// actorFromContext returns the authorization subject from the context.
56+
// ActorFromContext returns the authorization subject from the context.
5757
// All authentication flows should set the authorization subject in the context.
5858
// If no actor is present, the function returns false.
59-
func actorFromContext(ctx context.Context) (rbac.Subject, bool) {
59+
func ActorFromContext(ctx context.Context) (rbac.Subject, bool) {
6060
a, ok := ctx.Value(authContextKey{}).(rbac.Subject)
6161
return a, ok
6262
}

coderd/authzquery/job.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,7 @@ func (q *AuthzQuerier) UpdateProvisionerJobWithCancelByID(ctx context.Context, a
3838
// Would be nice to have a way in the rbac rego to do this.
3939
if !template.AllowUserCancelWorkspaceJobs {
4040
// Only owners can cancel workspace builds
41-
actor, ok := actorFromContext(ctx)
41+
actor, ok := ActorFromContext(ctx)
4242
if !ok {
4343
return xerrors.Errorf("no actor in context")
4444
}

coderd/authzquery/organization.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -85,7 +85,7 @@ func (q *AuthzQuerier) UpdateMemberRoles(ctx context.Context, arg database.Updat
8585
}
8686

8787
func (q *AuthzQuerier) canAssignRoles(ctx context.Context, orgID *uuid.UUID, added, removed []string) error {
88-
actor, ok := actorFromContext(ctx)
88+
actor, ok := ActorFromContext(ctx)
8989
if !ok {
9090
return xerrors.Errorf("no authorization actor in context")
9191
}

coderd/authzquery/user.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -76,7 +76,7 @@ func (q *AuthzQuerier) GetUsersWithCount(ctx context.Context, arg database.GetUs
7676
return []database.User{}, 0, nil
7777
}
7878

79-
act, ok := actorFromContext(ctx)
79+
act, ok := ActorFromContext(ctx)
8080
if !ok {
8181
return nil, -1, xerrors.Errorf("no authorization actor in context")
8282
}

coderd/authzquery/workspace.go

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -258,6 +258,23 @@ func (q *AuthzQuerier) GetWorkspaceResourceMetadataByResourceIDs(ctx context.Con
258258
func (q *AuthzQuerier) GetWorkspaceResourcesByJobID(ctx context.Context, jobID uuid.UUID) ([]database.WorkspaceResource, error) {
259259
build, err := q.database.GetWorkspaceBuildByJobID(ctx, jobID)
260260
if err != nil {
261+
job, err := q.database.GetProvisionerJobByID(ctx, jobID)
262+
if err == nil && job.Type == database.ProvisionerJobTypeTemplateVersionDryRun {
263+
// TODO: We should really remove this branch path. It is kinda jank.
264+
// This is really annoying, but if a job is a dry run, there is no workspace
265+
// for this job. So we need to make up an rbac object for the workspace.
266+
tv, err := authorizedTemplateVersionFromJob(ctx, q, job)
267+
if err != nil {
268+
return nil, err
269+
}
270+
271+
err = q.authorizeContext(ctx, rbac.ActionRead, rbac.ResourceWorkspace.InOrg(tv.OrganizationID).WithOwner(job.InitiatorID.String()))
272+
if err != nil {
273+
return nil, err
274+
}
275+
276+
return q.database.GetWorkspaceResourcesByJobID(ctx, jobID)
277+
}
261278
return nil, err
262279
}
263280

coderd/provisionerjobs.go

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -16,9 +16,10 @@ import (
1616
"nhooyr.io/websocket"
1717

1818
"cdr.dev/slog"
19-
19+
"github.com/coder/coder/coderd/authzquery"
2020
"github.com/coder/coder/coderd/database"
2121
"github.com/coder/coder/coderd/httpapi"
22+
"github.com/coder/coder/coderd/rbac"
2223
"github.com/coder/coder/codersdk"
2324
)
2425

@@ -32,6 +33,7 @@ import (
3233
func (api *API) provisionerJobLogs(rw http.ResponseWriter, r *http.Request, job database.ProvisionerJob) {
3334
var (
3435
ctx = r.Context()
36+
actor, _ = authzquery.ActorFromContext(ctx)
3537
logger = api.Logger.With(slog.F("job_id", job.ID))
3638
follow = r.URL.Query().Has("follow")
3739
afterRaw = r.URL.Query().Get("after")
@@ -49,7 +51,7 @@ func (api *API) provisionerJobLogs(rw http.ResponseWriter, r *http.Request, job
4951
// of processed IDs.
5052
var bufferedLogs <-chan database.ProvisionerJobLog
5153
if follow {
52-
bl, closeFollow, err := api.followLogs(job.ID)
54+
bl, closeFollow, err := api.followLogs(actor, job.ID)
5355
if err != nil {
5456
httpapi.Write(ctx, rw, http.StatusInternalServerError, codersdk.Response{
5557
Message: "Internal error watching provisioner logs.",
@@ -367,7 +369,7 @@ type provisionerJobLogsMessage struct {
367369
EndOfLogs bool `json:"end_of_logs,omitempty"`
368370
}
369371

370-
func (api *API) followLogs(jobID uuid.UUID) (<-chan database.ProvisionerJobLog, func(), error) {
372+
func (api *API) followLogs(actor rbac.Subject, jobID uuid.UUID) (<-chan database.ProvisionerJobLog, func(), error) {
371373
logger := api.Logger.With(slog.F("job_id", jobID))
372374

373375
var (
@@ -378,6 +380,7 @@ func (api *API) followLogs(jobID uuid.UUID) (<-chan database.ProvisionerJobLog,
378380
closeSubscribe, err := api.Pubsub.Subscribe(
379381
provisionerJobLogsChannel(jobID),
380382
func(ctx context.Context, message []byte) {
383+
ctx = authzquery.WithAuthorizeContext(ctx, actor)
381384
select {
382385
case <-closed:
383386
return

0 commit comments

Comments
 (0)