From 19b213a35e440b30067019c1a5fbf870d0212246 Mon Sep 17 00:00:00 2001 From: Steven Masley Date: Wed, 22 Jan 2025 17:48:16 -0600 Subject: [PATCH 1/3] fix: fetching custom roles from workspace agent context --- coderd/httpmw/workspaceagent.go | 36 ++++++--------------------------- 1 file changed, 6 insertions(+), 30 deletions(-) diff --git a/coderd/httpmw/workspaceagent.go b/coderd/httpmw/workspaceagent.go index b27af7d0093a0..fb2a7e005ae75 100644 --- a/coderd/httpmw/workspaceagent.go +++ b/coderd/httpmw/workspaceagent.go @@ -109,36 +109,12 @@ func ExtractWorkspaceAgentAndLatestBuild(opts ExtractWorkspaceAgentAndLatestBuil return } - //nolint:gocritic // System needs to be able to get owner roles. - roles, err := opts.DB.GetAuthorizationUserRoles(dbauthz.AsSystemRestricted(ctx), row.WorkspaceTable.OwnerID) - if err != nil { - httpapi.Write(ctx, rw, http.StatusInternalServerError, codersdk.Response{ - Message: "Internal error checking workspace agent authorization.", - Detail: err.Error(), - }) - return - } - - roleNames, err := roles.RoleNames() - if err != nil { - httpapi.Write(ctx, rw, http.StatusInternalServerError, codersdk.Response{ - Message: "Internal server error", - Detail: err.Error(), - }) - return - } - - subject := rbac.Subject{ - ID: row.WorkspaceTable.OwnerID.String(), - Roles: rbac.RoleIdentifiers(roleNames), - Groups: roles.Groups, - Scope: rbac.WorkspaceAgentScope(rbac.WorkspaceAgentScopeParams{ - WorkspaceID: row.WorkspaceTable.ID, - OwnerID: row.WorkspaceTable.OwnerID, - TemplateID: row.WorkspaceTable.TemplateID, - VersionID: row.WorkspaceBuild.TemplateVersionID, - }), - }.WithCachedASTValue() + subject, _, err := UserRBACSubject(ctx, opts.DB, row.WorkspaceTable.OwnerID, rbac.WorkspaceAgentScope(rbac.WorkspaceAgentScopeParams{ + WorkspaceID: row.WorkspaceTable.ID, + OwnerID: row.WorkspaceTable.OwnerID, + TemplateID: row.WorkspaceTable.TemplateID, + VersionID: row.WorkspaceBuild.TemplateVersionID, + })) ctx = context.WithValue(ctx, workspaceAgentContextKey{}, row.WorkspaceAgent) ctx = context.WithValue(ctx, latestBuildContextKey{}, row.WorkspaceBuild) From a5c7938a3920639f262eb2d888bb438a250dcc6d Mon Sep 17 00:00:00 2001 From: Steven Masley Date: Thu, 23 Jan 2025 08:19:57 -0600 Subject: [PATCH 2/3] add unit test --- coderd/httpmw/workspaceagent.go | 7 +++ enterprise/coderd/gitsshkey_test.go | 80 +++++++++++++++++++++++++++++ 2 files changed, 87 insertions(+) create mode 100644 enterprise/coderd/gitsshkey_test.go diff --git a/coderd/httpmw/workspaceagent.go b/coderd/httpmw/workspaceagent.go index fb2a7e005ae75..241fa385681e6 100644 --- a/coderd/httpmw/workspaceagent.go +++ b/coderd/httpmw/workspaceagent.go @@ -115,6 +115,13 @@ func ExtractWorkspaceAgentAndLatestBuild(opts ExtractWorkspaceAgentAndLatestBuil TemplateID: row.WorkspaceTable.TemplateID, VersionID: row.WorkspaceBuild.TemplateVersionID, })) + if err != nil { + httpapi.Write(ctx, rw, http.StatusInternalServerError, codersdk.Response{ + Message: "Internal error with workspace agent authorization context.", + Detail: err.Error(), + }) + return + } ctx = context.WithValue(ctx, workspaceAgentContextKey{}, row.WorkspaceAgent) ctx = context.WithValue(ctx, latestBuildContextKey{}, row.WorkspaceBuild) diff --git a/enterprise/coderd/gitsshkey_test.go b/enterprise/coderd/gitsshkey_test.go new file mode 100644 index 0000000000000..8faad4ee703d8 --- /dev/null +++ b/enterprise/coderd/gitsshkey_test.go @@ -0,0 +1,80 @@ +package coderd_test + +import ( + "context" + "testing" + + "github.com/google/uuid" + "github.com/stretchr/testify/require" + + "github.com/coder/coder/v2/coderd/coderdtest" + "github.com/coder/coder/v2/coderd/rbac" + "github.com/coder/coder/v2/codersdk" + "github.com/coder/coder/v2/codersdk/agentsdk" + "github.com/coder/coder/v2/enterprise/coderd/coderdenttest" + "github.com/coder/coder/v2/enterprise/coderd/license" + "github.com/coder/coder/v2/provisioner/echo" + "github.com/coder/coder/v2/testutil" +) + +// TestAgentGitSSHKeyCustomRoles tests that the agent can fetch its git ssh key when +// the user has a custom role in a second workspace. +func TestAgentGitSSHKeyCustomRoles(t *testing.T) { + t.Parallel() + + owner, _ := coderdenttest.New(t, &coderdenttest.Options{ + Options: &coderdtest.Options{ + IncludeProvisionerDaemon: true, + }, + LicenseOptions: &coderdenttest.LicenseOptions{ + Features: license.Features{ + codersdk.FeatureCustomRoles: 1, + codersdk.FeatureMultipleOrganizations: 1, + codersdk.FeatureExternalProvisionerDaemons: 1, + }, + }, + }) + + // When custom roles exist in a second organization + org := coderdenttest.CreateOrganization(t, owner, coderdenttest.CreateOrganizationOptions{ + IncludeProvisionerDaemon: true, + }) + + ctx := testutil.Context(t, testutil.WaitShort) + newRole, err := owner.CreateOrganizationRole(ctx, codersdk.Role{ + Name: "custom", + OrganizationID: org.ID.String(), + DisplayName: "", + SitePermissions: nil, + OrganizationPermissions: codersdk.CreatePermissions(map[codersdk.RBACResource][]codersdk.RBACAction{ + codersdk.ResourceTemplate: {codersdk.ActionRead, codersdk.ActionCreate, codersdk.ActionUpdate}, + }), + UserPermissions: nil, + }) + require.NoError(t, err) + + // Create the new user + client, _ := coderdtest.CreateAnotherUser(t, owner, org.ID, rbac.RoleIdentifier{Name: newRole.Name, OrganizationID: org.ID}) + + // Create the workspace + agent + authToken := uuid.NewString() + version := coderdtest.CreateTemplateVersion(t, client, org.ID, &echo.Responses{ + Parse: echo.ParseComplete, + ProvisionPlan: echo.PlanComplete, + ProvisionApply: echo.ProvisionApplyWithAgent(authToken), + }) + project := coderdtest.CreateTemplate(t, client, org.ID, version.ID) + coderdtest.AwaitTemplateVersionJobCompleted(t, client, version.ID) + workspace := coderdtest.CreateWorkspace(t, client, project.ID) + coderdtest.AwaitWorkspaceBuildJobCompleted(t, client, workspace.LatestBuild.ID) + + agentClient := agentsdk.New(client.URL) + agentClient.SetSessionToken(authToken) + + ctx, cancel := context.WithTimeout(context.Background(), testutil.WaitLong) + defer cancel() + + agentKey, err := agentClient.GitSSHKey(ctx) + require.NoError(t, err) + require.NotEmpty(t, agentKey.PrivateKey) +} From 98db9e169c868ba0b7f3be7ff3326ca6759a084e Mon Sep 17 00:00:00 2001 From: Steven Masley Date: Thu, 23 Jan 2025 08:54:09 -0600 Subject: [PATCH 3/3] linting --- enterprise/coderd/gitsshkey_test.go | 1 + 1 file changed, 1 insertion(+) diff --git a/enterprise/coderd/gitsshkey_test.go b/enterprise/coderd/gitsshkey_test.go index 8faad4ee703d8..a4978ac8fdad3 100644 --- a/enterprise/coderd/gitsshkey_test.go +++ b/enterprise/coderd/gitsshkey_test.go @@ -41,6 +41,7 @@ func TestAgentGitSSHKeyCustomRoles(t *testing.T) { }) ctx := testutil.Context(t, testutil.WaitShort) + //nolint:gocritic // required to make orgs newRole, err := owner.CreateOrganizationRole(ctx, codersdk.Role{ Name: "custom", OrganizationID: org.ID.String(), 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