fix: require update permission to recreate devcontainers (#25812)

- The httpmw upstream from this endpoint only checks for read perms to the
workspace agent. Recreating a dev container should require `update`
perms since it mutates state. This also matches the behavior of the
`DELETE` endpoint
This commit is contained in:
Jon Ayers
2026-05-28 15:34:36 -05:00
committed by GitHub
parent c248dfb437
commit bb11946bd4
2 changed files with 50 additions and 0 deletions
+5
View File
@@ -1096,6 +1096,11 @@ func (api *API) workspaceAgentRecreateDevcontainer(rw http.ResponseWriter, r *ht
ctx := r.Context()
waws := httpmw.WorkspaceAgentAndWorkspaceParam(r)
if !api.Authorize(r, policy.ActionUpdate, waws.WorkspaceTable) {
httpapi.Forbidden(rw)
return
}
devcontainer := chi.URLParam(r, "devcontainer")
if devcontainer == "" {
httpapi.Write(ctx, rw, http.StatusBadRequest, codersdk.Response{
+45
View File
@@ -1876,6 +1876,51 @@ func TestWorkspaceAgentRecreateDevcontainer(t *testing.T) {
})
}
func TestWorkspaceAgentRecreateDevcontainerAuthorization(t *testing.T) {
t.Parallel()
for _, tc := range []struct {
name string
role func(uuid.UUID) rbac.RoleIdentifier
}{
{
name: "TemplateAdmin",
role: func(uuid.UUID) rbac.RoleIdentifier {
return rbac.RoleTemplateAdmin()
},
},
{
name: "OrgTemplateAdmin",
role: rbac.ScopedRoleOrgTemplateAdmin,
},
} {
t.Run(tc.name, func(t *testing.T) {
t.Parallel()
var (
ctx = testutil.Context(t, testutil.WaitMedium)
client, db = coderdtest.NewWithDatabase(t, nil)
admin = coderdtest.CreateFirstUser(t, client)
_, workspaceOwner = coderdtest.CreateAnotherUser(t, client, admin.OrganizationID)
templateAdminClient, _ = coderdtest.CreateAnotherUser(t, client, admin.OrganizationID, tc.role(admin.OrganizationID))
workspace = dbfake.WorkspaceBuild(t, db, database.WorkspaceTable{
OrganizationID: admin.OrganizationID,
OwnerID: workspaceOwner.ID,
}).WithAgent(func(agents []*proto.Agent) []*proto.Agent {
return agents
}).Do()
)
_, err := templateAdminClient.WorkspaceAgentRecreateDevcontainer(ctx, workspace.Agents[0].ID, uuid.NewString())
require.Error(t, err)
var sdkErr *codersdk.Error
require.ErrorAs(t, err, &sdkErr)
require.Equal(t, http.StatusForbidden, sdkErr.StatusCode())
})
}
}
func TestWorkspaceAgentDeleteDevcontainer(t *testing.T) {
t.Parallel()