Skip to content

Commit 6125358

Browse files
fix: fetch custom roles from workspace agent context (cherry-pick #16237) (#16246)
Co-authored-by: Steven Masley <Emyrk@users.noreply.github.com>
1 parent 803e2c7 commit 6125358

File tree

2 files changed

+88
-24
lines changed

2 files changed

+88
-24
lines changed

coderd/httpmw/workspaceagent.go

+7-24
Original file line numberDiff line numberDiff line change
@@ -109,37 +109,20 @@ func ExtractWorkspaceAgentAndLatestBuild(opts ExtractWorkspaceAgentAndLatestBuil
109109
return
110110
}
111111

112-
//nolint:gocritic // System needs to be able to get owner roles.
113-
roles, err := opts.DB.GetAuthorizationUserRoles(dbauthz.AsSystemRestricted(ctx), row.WorkspaceTable.OwnerID)
112+
subject, _, err := UserRBACSubject(ctx, opts.DB, row.WorkspaceTable.OwnerID, rbac.WorkspaceAgentScope(rbac.WorkspaceAgentScopeParams{
113+
WorkspaceID: row.WorkspaceTable.ID,
114+
OwnerID: row.WorkspaceTable.OwnerID,
115+
TemplateID: row.WorkspaceTable.TemplateID,
116+
VersionID: row.WorkspaceBuild.TemplateVersionID,
117+
}))
114118
if err != nil {
115119
httpapi.Write(ctx, rw, http.StatusInternalServerError, codersdk.Response{
116-
Message: "Internal error checking workspace agent authorization.",
120+
Message: "Internal error with workspace agent authorization context.",
117121
Detail: err.Error(),
118122
})
119123
return
120124
}
121125

122-
roleNames, err := roles.RoleNames()
123-
if err != nil {
124-
httpapi.Write(ctx, rw, http.StatusInternalServerError, codersdk.Response{
125-
Message: "Internal server error",
126-
Detail: err.Error(),
127-
})
128-
return
129-
}
130-
131-
subject := rbac.Subject{
132-
ID: row.WorkspaceTable.OwnerID.String(),
133-
Roles: rbac.RoleIdentifiers(roleNames),
134-
Groups: roles.Groups,
135-
Scope: rbac.WorkspaceAgentScope(rbac.WorkspaceAgentScopeParams{
136-
WorkspaceID: row.WorkspaceTable.ID,
137-
OwnerID: row.WorkspaceTable.OwnerID,
138-
TemplateID: row.WorkspaceTable.TemplateID,
139-
VersionID: row.WorkspaceBuild.TemplateVersionID,
140-
}),
141-
}.WithCachedASTValue()
142-
143126
ctx = context.WithValue(ctx, workspaceAgentContextKey{}, row.WorkspaceAgent)
144127
ctx = context.WithValue(ctx, latestBuildContextKey{}, row.WorkspaceBuild)
145128
// Also set the dbauthz actor for the request.

enterprise/coderd/gitsshkey_test.go

+81
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,81 @@
1+
package coderd_test
2+
3+
import (
4+
"context"
5+
"testing"
6+
7+
"github.com/google/uuid"
8+
"github.com/stretchr/testify/require"
9+
10+
"github.com/coder/coder/v2/coderd/coderdtest"
11+
"github.com/coder/coder/v2/coderd/rbac"
12+
"github.com/coder/coder/v2/codersdk"
13+
"github.com/coder/coder/v2/codersdk/agentsdk"
14+
"github.com/coder/coder/v2/enterprise/coderd/coderdenttest"
15+
"github.com/coder/coder/v2/enterprise/coderd/license"
16+
"github.com/coder/coder/v2/provisioner/echo"
17+
"github.com/coder/coder/v2/testutil"
18+
)
19+
20+
// TestAgentGitSSHKeyCustomRoles tests that the agent can fetch its git ssh key when
21+
// the user has a custom role in a second workspace.
22+
func TestAgentGitSSHKeyCustomRoles(t *testing.T) {
23+
t.Parallel()
24+
25+
owner, _ := coderdenttest.New(t, &coderdenttest.Options{
26+
Options: &coderdtest.Options{
27+
IncludeProvisionerDaemon: true,
28+
},
29+
LicenseOptions: &coderdenttest.LicenseOptions{
30+
Features: license.Features{
31+
codersdk.FeatureCustomRoles: 1,
32+
codersdk.FeatureMultipleOrganizations: 1,
33+
codersdk.FeatureExternalProvisionerDaemons: 1,
34+
},
35+
},
36+
})
37+
38+
// When custom roles exist in a second organization
39+
org := coderdenttest.CreateOrganization(t, owner, coderdenttest.CreateOrganizationOptions{
40+
IncludeProvisionerDaemon: true,
41+
})
42+
43+
ctx := testutil.Context(t, testutil.WaitShort)
44+
//nolint:gocritic // required to make orgs
45+
newRole, err := owner.CreateOrganizationRole(ctx, codersdk.Role{
46+
Name: "custom",
47+
OrganizationID: org.ID.String(),
48+
DisplayName: "",
49+
SitePermissions: nil,
50+
OrganizationPermissions: codersdk.CreatePermissions(map[codersdk.RBACResource][]codersdk.RBACAction{
51+
codersdk.ResourceTemplate: {codersdk.ActionRead, codersdk.ActionCreate, codersdk.ActionUpdate},
52+
}),
53+
UserPermissions: nil,
54+
})
55+
require.NoError(t, err)
56+
57+
// Create the new user
58+
client, _ := coderdtest.CreateAnotherUser(t, owner, org.ID, rbac.RoleIdentifier{Name: newRole.Name, OrganizationID: org.ID})
59+
60+
// Create the workspace + agent
61+
authToken := uuid.NewString()
62+
version := coderdtest.CreateTemplateVersion(t, client, org.ID, &echo.Responses{
63+
Parse: echo.ParseComplete,
64+
ProvisionPlan: echo.PlanComplete,
65+
ProvisionApply: echo.ProvisionApplyWithAgent(authToken),
66+
})
67+
project := coderdtest.CreateTemplate(t, client, org.ID, version.ID)
68+
coderdtest.AwaitTemplateVersionJobCompleted(t, client, version.ID)
69+
workspace := coderdtest.CreateWorkspace(t, client, project.ID)
70+
coderdtest.AwaitWorkspaceBuildJobCompleted(t, client, workspace.LatestBuild.ID)
71+
72+
agentClient := agentsdk.New(client.URL)
73+
agentClient.SetSessionToken(authToken)
74+
75+
ctx, cancel := context.WithTimeout(context.Background(), testutil.WaitLong)
76+
defer cancel()
77+
78+
agentKey, err := agentClient.GitSSHKey(ctx)
79+
require.NoError(t, err)
80+
require.NotEmpty(t, agentKey.PrivateKey)
81+
}

0 commit comments

Comments
 (0)