Skip to content

Commit 8c4a0f5

Browse files
Callum Styanclaude
andcommitted
refactor: introduce ContextInject helper to reduce code duplication
Created CachedWorkspaceFields.ContextInject() to consolidate the repeated pattern of injecting workspace RBAC into context across connectionlog.go, metadata.go, and stats.go. This reduces code duplication and makes the codebase more maintainable by centralizing the RBAC injection logic with consistent error handling. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
1 parent 2d980ba commit 8c4a0f5

File tree

4 files changed

+29
-31
lines changed

4 files changed

+29
-31
lines changed

coderd/agentapi/cached_workspace.go

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,12 @@
11
package agentapi
22

33
import (
4+
"context"
45
"sync"
56

7+
"cdr.dev/slog"
68
"github.com/coder/coder/v2/coderd/database"
9+
"github.com/coder/coder/v2/coderd/database/dbauthz"
710
)
811

912
// CachedWorkspaceFields contains workspace data that is safe to cache for the
@@ -50,3 +53,26 @@ func (cws *CachedWorkspaceFields) AsWorkspaceIdentity() (database.WorkspaceIdent
5053
}
5154
return cws.identity, true
5255
}
56+
57+
// ContextInject attempts to inject the cached workspace RBAC object into the context.
58+
// This enables the dbauthz fast path and avoids expensive database calls like GetWorkspaceByAgentID.
59+
// If the cache is empty or RBAC injection fails, the original context is returned.
60+
//
61+
// Parameters:
62+
// - ctx: the original context
63+
// - log: logger for debug messages (optional, can be nil to skip logging)
64+
//
65+
// Returns the context with RBAC injected if successful, otherwise the original context.
66+
func (cws *CachedWorkspaceFields) ContextInject(ctx context.Context, log slog.Logger) context.Context {
67+
if dbws, ok := cws.AsWorkspaceIdentity(); ok {
68+
rbacCtx, err := dbauthz.WithWorkspaceRBAC(ctx, dbws.RBACObject())
69+
if err != nil {
70+
// Don't error level log here, will exit the function. We want to fall back to GetWorkspaceByAgentID.
71+
//nolint:gocritic
72+
log.Debug(ctx, "Cached workspace was present but RBAC object was invalid", slog.F("err", err))
73+
return ctx
74+
}
75+
return rbacCtx
76+
}
77+
return ctx
78+
}

coderd/agentapi/connectionlog.go

Lines changed: 1 addition & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,6 @@ import (
1414
"github.com/coder/coder/v2/coderd/connectionlog"
1515
"github.com/coder/coder/v2/coderd/database"
1616
"github.com/coder/coder/v2/coderd/database/db2sdk"
17-
"github.com/coder/coder/v2/coderd/database/dbauthz"
1817
)
1918

2019
type ConnLogAPI struct {
@@ -55,16 +54,10 @@ func (a *ConnLogAPI) ReportConnection(ctx context.Context, req *agentproto.Repor
5554

5655
// Inject RBAC object into context for dbauthz fast path, avoid having to
5756
// call GetWorkspaceByAgentID on every metadata update.
58-
rbacCtx := ctx
57+
rbacCtx := a.Workspace.ContextInject(ctx, a.Log)
5958
var ws database.WorkspaceIdentity
6059
if dbws, ok := a.Workspace.AsWorkspaceIdentity(); ok {
6160
ws = dbws
62-
rbacCtx, err = dbauthz.WithWorkspaceRBAC(ctx, dbws.RBACObject())
63-
if err != nil {
64-
// Don't error level log here, will exit the function. We want to fall back to GetWorkspaceByAgentID.
65-
//nolint:gocritic
66-
a.Log.Debug(ctx, "Cached workspace was present but RBAC object was invalid", slog.F("err", err))
67-
}
6861
}
6962

7063
// Fetch contextual data for this connection log event.

coderd/agentapi/metadata.go

Lines changed: 1 addition & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,6 @@ import (
1212
"cdr.dev/slog"
1313
agentproto "github.com/coder/coder/v2/agent/proto"
1414
"github.com/coder/coder/v2/coderd/database"
15-
"github.com/coder/coder/v2/coderd/database/dbauthz"
1615
"github.com/coder/coder/v2/coderd/database/dbtime"
1716
"github.com/coder/coder/v2/coderd/database/pubsub"
1817
)
@@ -49,16 +48,7 @@ func (a *MetadataAPI) BatchUpdateMetadata(ctx context.Context, req *agentproto.B
4948

5049
// Inject RBAC object into context for dbauthz fast path, avoid having to
5150
// call GetWorkspaceByAgentID on every metadata update.
52-
var err error
53-
rbacCtx := ctx
54-
if dbws, ok := a.Workspace.AsWorkspaceIdentity(); ok {
55-
rbacCtx, err = dbauthz.WithWorkspaceRBAC(ctx, dbws.RBACObject())
56-
if err != nil {
57-
// Don't error level log here, will exit the function. We want to fall back to GetWorkspaceByAgentID.
58-
//nolint:gocritic
59-
a.Log.Debug(ctx, "Cached workspace was present but RBAC object was invalid", slog.F("err", err))
60-
}
61-
}
51+
rbacCtx := a.Workspace.ContextInject(ctx, a.Log)
6252

6353
workspaceAgent, err := a.AgentFn(rbacCtx)
6454
if err != nil {

coderd/agentapi/stats.go

Lines changed: 1 addition & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,6 @@ import (
1010
"cdr.dev/slog"
1111
agentproto "github.com/coder/coder/v2/agent/proto"
1212
"github.com/coder/coder/v2/coderd/database"
13-
"github.com/coder/coder/v2/coderd/database/dbauthz"
1413
"github.com/coder/coder/v2/coderd/database/dbtime"
1514
"github.com/coder/coder/v2/coderd/workspacestats"
1615
"github.com/coder/coder/v2/codersdk"
@@ -46,17 +45,7 @@ func (a *StatsAPI) UpdateStats(ctx context.Context, req *agentproto.UpdateStatsR
4645

4746
// Inject RBAC object into context for dbauthz fast path, avoid having to
4847
// call GetWorkspaceAgentByID on every stats update.
49-
50-
rbacCtx := ctx
51-
if dbws, ok := a.Workspace.AsWorkspaceIdentity(); ok {
52-
var err error
53-
rbacCtx, err = dbauthz.WithWorkspaceRBAC(ctx, dbws.RBACObject())
54-
if err != nil {
55-
// Don't error level log here, will exit the function. We want to fall back to GetWorkspaceByAgentID.
56-
//nolint:gocritic
57-
a.Log.Debug(ctx, "Cached workspace was present but RBAC object was invalid", slog.F("err", err))
58-
}
59-
}
48+
rbacCtx := a.Workspace.ContextInject(ctx, a.Log)
6049

6150
workspaceAgent, err := a.AgentFn(rbacCtx)
6251
if err != nil {

0 commit comments

Comments
 (0)