Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit fe867d0

Browse files
authored
fix: correct perms for forbidden error in TemplateScheduleStore.Load (coder#11286)
* chore: TemplateScheduleStore.Load() throwing forbidden error * fix: workspace agent scope to include template
1 parent 20dff2a commit fe867d0

File tree

8 files changed

+49
-16
lines changed

8 files changed

+49
-16
lines changed

coderd/agentapi/stats.go

+1-1
Original file line numberDiff line numberDiff line change
@@ -61,7 +61,7 @@ func (a *StatsAPI) UpdateStats(ctx context.Context, req *agentproto.UpdateStatsR
6161
templateSchedule, err := (*(a.TemplateScheduleStore.Load())).Get(ctx, a.Database, workspace.TemplateID)
6262
// If the template schedule fails to load, just default to bumping without the next trasition and log it.
6363
if err != nil {
64-
a.Log.Warn(ctx, "failed to load template schedule bumping activity, defaulting to bumping by 60min",
64+
a.Log.Error(ctx, "failed to load template schedule bumping activity, defaulting to bumping by 60min",
6565
slog.F("workspace_id", workspace.ID),
6666
slog.F("template_id", workspace.TemplateID),
6767
slog.Error(err),

coderd/database/dbmem/dbmem.go

+2
Original file line numberDiff line numberDiff line change
@@ -3796,6 +3796,7 @@ func (q *FakeQuerier) GetWorkspaceAgentAndOwnerByAuthToken(_ context.Context, au
37963796
}
37973797
var row database.GetWorkspaceAgentAndOwnerByAuthTokenRow
37983798
row.WorkspaceID = ws.ID
3799+
row.TemplateID = ws.TemplateID
37993800
usr, err := q.getUserByIDNoLock(ws.OwnerID)
38003801
if err != nil {
38013802
return database.GetWorkspaceAgentAndOwnerByAuthTokenRow{}, sql.ErrNoRows
@@ -3805,6 +3806,7 @@ func (q *FakeQuerier) GetWorkspaceAgentAndOwnerByAuthToken(_ context.Context, au
38053806
// We also need to get org roles for the user
38063807
row.OwnerName = usr.Username
38073808
row.WorkspaceAgent = agt
3809+
row.TemplateVersionID = build.TemplateVersionID
38083810
for _, mem := range q.organizationMembers {
38093811
if mem.UserID == usr.ID {
38103812
row.OwnerRoles = append(row.OwnerRoles, fmt.Sprintf("organization-member:%s", mem.OrganizationID.String()))

coderd/database/queries.sql.go

+15-8
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

coderd/database/queries/workspaceagents.sql

+4-1
Original file line numberDiff line numberDiff line change
@@ -219,6 +219,8 @@ SELECT
219219
users.id AS owner_id,
220220
users.username AS owner_name,
221221
users.status AS owner_status,
222+
workspaces.template_id AS template_id,
223+
workspace_builds.template_version_id AS template_version_id,
222224
array_cat(
223225
array_append(users.rbac_roles, 'member'),
224226
array_append(ARRAY[]::text[], 'organization-member:' || organization_members.organization_id::text)
@@ -261,7 +263,8 @@ GROUP BY
261263
workspaces.id,
262264
users.id,
263265
organization_members.organization_id,
264-
workspace_builds.build_number
266+
workspace_builds.build_number,
267+
workspace_builds.template_version_id
265268
ORDER BY
266269
workspace_builds.build_number DESC
267270
LIMIT 1;

coderd/httpmw/workspaceagent.go

+6-1
Original file line numberDiff line numberDiff line change
@@ -97,7 +97,12 @@ func ExtractWorkspaceAgent(opts ExtractWorkspaceAgentConfig) func(http.Handler)
9797
ID: row.OwnerID.String(),
9898
Roles: rbac.RoleNames(row.OwnerRoles),
9999
Groups: row.OwnerGroups,
100-
Scope: rbac.WorkspaceAgentScope(row.WorkspaceID, row.OwnerID),
100+
Scope: rbac.WorkspaceAgentScope(rbac.WorkspaceAgentScopeParams{
101+
WorkspaceID: row.WorkspaceID,
102+
OwnerID: row.OwnerID,
103+
TemplateID: row.TemplateID,
104+
VersionID: row.TemplateVersionID,
105+
}),
101106
}.WithCachedASTValue()
102107

103108
ctx = context.WithValue(ctx, workspaceAgentContextKey{}, row.WorkspaceAgent)

coderd/prometheusmetrics/prometheusmetrics_test.go

+2
Original file line numberDiff line numberDiff line change
@@ -394,12 +394,14 @@ func TestAgentStats(t *testing.T) {
394394
require.NoError(t, err, "create stats batcher failed")
395395
t.Cleanup(closeBatcher)
396396

397+
tLogger := slogtest.Make(t, nil)
397398
// Build sample workspaces with test agents and fake agent client
398399
client, _, _ := coderdtest.NewWithAPI(t, &coderdtest.Options{
399400
Database: db,
400401
IncludeProvisionerDaemon: true,
401402
Pubsub: pubsub,
402403
StatsBatcher: batcher,
404+
Logger: &tLogger,
403405
})
404406

405407
user := coderdtest.CreateFirstUser(t, client)

coderd/rbac/scopes.go

+18-4
Original file line numberDiff line numberDiff line change
@@ -8,10 +8,21 @@ import (
88
"golang.org/x/xerrors"
99
)
1010

11+
type WorkspaceAgentScopeParams struct {
12+
WorkspaceID uuid.UUID
13+
OwnerID uuid.UUID
14+
TemplateID uuid.UUID
15+
VersionID uuid.UUID
16+
}
17+
1118
// WorkspaceAgentScope returns a scope that is the same as ScopeAll but can only
1219
// affect resources in the allow list. Only a scope is returned as the roles
1320
// should come from the workspace owner.
14-
func WorkspaceAgentScope(workspaceID, ownerID uuid.UUID) Scope {
21+
func WorkspaceAgentScope(params WorkspaceAgentScopeParams) Scope {
22+
if params.WorkspaceID == uuid.Nil || params.OwnerID == uuid.Nil || params.TemplateID == uuid.Nil || params.VersionID == uuid.Nil {
23+
panic("all uuids must be non-nil, this is a developer error")
24+
}
25+
1526
allScope, err := ScopeAll.Expand()
1627
if err != nil {
1728
panic("failed to expand scope all, this should never happen")
@@ -23,10 +34,13 @@ func WorkspaceAgentScope(workspaceID, ownerID uuid.UUID) Scope {
2334
// and evolving.
2435
Role: allScope.Role,
2536
// This prevents the agent from being able to access any other resource.
37+
// Include the list of IDs of anything that is required for the
38+
// agent to function.
2639
AllowIDList: []string{
27-
workspaceID.String(),
28-
ownerID.String(),
29-
// TODO: Might want to include the template the workspace uses too?
40+
params.WorkspaceID.String(),
41+
params.TemplateID.String(),
42+
params.VersionID.String(),
43+
params.OwnerID.String(),
3044
},
3145
}
3246
}

coderd/workspaceagents.go

+1-1
Original file line numberDiff line numberDiff line change
@@ -1488,7 +1488,7 @@ func (api *API) workspaceAgentReportStats(rw http.ResponseWriter, r *http.Reques
14881488
templateSchedule, err := (*(api.TemplateScheduleStore.Load())).Get(ctx, api.Database, workspace.TemplateID)
14891489
// If the template schedule fails to load, just default to bumping without the next transition and log it.
14901490
if err != nil {
1491-
api.Logger.Warn(ctx, "failed to load template schedule bumping activity, defaulting to bumping by 60min",
1491+
api.Logger.Error(ctx, "failed to load template schedule bumping activity, defaulting to bumping by 60min",
14921492
slog.F("workspace_id", workspace.ID),
14931493
slog.F("template_id", workspace.TemplateID),
14941494
slog.Error(err),

0 commit comments

Comments
 (0)