Skip to content

Commit cc895f6

Browse files
fix: require update permission to recreate devcontainers (#25812) (#26244)
Cherry-pick backport to `release/2.32`. Co-authored-by: Jon Ayers <jon@coder.com>
1 parent 027cf9a commit cc895f6

2 files changed

Lines changed: 50 additions & 0 deletions

File tree

coderd/workspaceagents.go

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1093,6 +1093,11 @@ func (api *API) workspaceAgentRecreateDevcontainer(rw http.ResponseWriter, r *ht
10931093
ctx := r.Context()
10941094
waws := httpmw.WorkspaceAgentAndWorkspaceParam(r)
10951095

1096+
if !api.Authorize(r, policy.ActionUpdate, waws.WorkspaceTable) {
1097+
httpapi.Forbidden(rw)
1098+
return
1099+
}
1100+
10961101
devcontainer := chi.URLParam(r, "devcontainer")
10971102
if devcontainer == "" {
10981103
httpapi.Write(ctx, rw, http.StatusBadRequest, codersdk.Response{

coderd/workspaceagents_test.go

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1832,6 +1832,51 @@ func TestWorkspaceAgentRecreateDevcontainer(t *testing.T) {
18321832
})
18331833
}
18341834

1835+
func TestWorkspaceAgentRecreateDevcontainerAuthorization(t *testing.T) {
1836+
t.Parallel()
1837+
1838+
for _, tc := range []struct {
1839+
name string
1840+
role func(uuid.UUID) rbac.RoleIdentifier
1841+
}{
1842+
{
1843+
name: "TemplateAdmin",
1844+
role: func(uuid.UUID) rbac.RoleIdentifier {
1845+
return rbac.RoleTemplateAdmin()
1846+
},
1847+
},
1848+
{
1849+
name: "OrgTemplateAdmin",
1850+
role: rbac.ScopedRoleOrgTemplateAdmin,
1851+
},
1852+
} {
1853+
t.Run(tc.name, func(t *testing.T) {
1854+
t.Parallel()
1855+
1856+
var (
1857+
ctx = testutil.Context(t, testutil.WaitMedium)
1858+
client, db = coderdtest.NewWithDatabase(t, nil)
1859+
admin = coderdtest.CreateFirstUser(t, client)
1860+
_, workspaceOwner = coderdtest.CreateAnotherUser(t, client, admin.OrganizationID)
1861+
templateAdminClient, _ = coderdtest.CreateAnotherUser(t, client, admin.OrganizationID, tc.role(admin.OrganizationID))
1862+
workspace = dbfake.WorkspaceBuild(t, db, database.WorkspaceTable{
1863+
OrganizationID: admin.OrganizationID,
1864+
OwnerID: workspaceOwner.ID,
1865+
}).WithAgent(func(agents []*proto.Agent) []*proto.Agent {
1866+
return agents
1867+
}).Do()
1868+
)
1869+
1870+
_, err := templateAdminClient.WorkspaceAgentRecreateDevcontainer(ctx, workspace.Agents[0].ID, uuid.NewString())
1871+
require.Error(t, err)
1872+
1873+
var sdkErr *codersdk.Error
1874+
require.ErrorAs(t, err, &sdkErr)
1875+
require.Equal(t, http.StatusForbidden, sdkErr.StatusCode())
1876+
})
1877+
}
1878+
}
1879+
18351880
func TestWorkspaceAgentDeleteDevcontainer(t *testing.T) {
18361881
t.Parallel()
18371882

0 commit comments

Comments
 (0)