Skip to content

Commit 24448e7

Browse files
fix: prevent extending if template disallows (#13182)
1 parent c73d5a2 commit 24448e7

File tree

4 files changed

+66
-2
lines changed

4 files changed

+66
-2
lines changed

coderd/workspaces.go

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1052,6 +1052,18 @@ func (api *API) putExtendWorkspace(rw http.ResponseWriter, r *http.Request) {
10521052
return xerrors.Errorf("workspace shutdown is manual")
10531053
}
10541054

1055+
tmpl, err := s.GetTemplateByID(ctx, workspace.TemplateID)
1056+
if err != nil {
1057+
code = http.StatusInternalServerError
1058+
resp.Message = "Error fetching template."
1059+
return xerrors.Errorf("get template: %w", err)
1060+
}
1061+
if !tmpl.AllowUserAutostop {
1062+
code = http.StatusBadRequest
1063+
resp.Message = "Cannot extend workspace: template does not allow user autostop."
1064+
return xerrors.New("cannot extend workspace: template does not allow user autostop")
1065+
}
1066+
10551067
newDeadline := req.Deadline.UTC()
10561068
if err := validWorkspaceDeadline(job.CompletedAt.Time, newDeadline); err != nil {
10571069
// NOTE(Cian): Putting the error in the Message field on request from the FE folks.

enterprise/coderd/workspaces_test.go

Lines changed: 33 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -913,8 +913,12 @@ func TestWorkspaceAutobuild(t *testing.T) {
913913
ws = coderdtest.MustWorkspace(t, client, ws.ID)
914914
require.Equal(t, version2.ID, ws.LatestBuild.TemplateVersionID)
915915
})
916+
}
917+
918+
func TestTemplateDoesNotAllowUserAutostop(t *testing.T) {
919+
t.Parallel()
916920

917-
t.Run("TemplateDoesNotAllowUserAutostop", func(t *testing.T) {
921+
t.Run("TTLSetByTemplate", func(t *testing.T) {
918922
t.Parallel()
919923
client := coderdtest.New(t, &coderdtest.Options{
920924
IncludeProvisionerDaemon: true,
@@ -951,6 +955,34 @@ func TestWorkspaceAutobuild(t *testing.T) {
951955
require.Equal(t, templateTTL, template.DefaultTTLMillis)
952956
require.Equal(t, templateTTL, *workspace.TTLMillis)
953957
})
958+
959+
t.Run("ExtendIsNotEnabledByTemplate", func(t *testing.T) {
960+
t.Parallel()
961+
client := coderdtest.New(t, &coderdtest.Options{
962+
IncludeProvisionerDaemon: true,
963+
TemplateScheduleStore: schedule.NewEnterpriseTemplateScheduleStore(agplUserQuietHoursScheduleStore()),
964+
})
965+
user := coderdtest.CreateFirstUser(t, client)
966+
version := coderdtest.CreateTemplateVersion(t, client, user.OrganizationID, nil)
967+
template := coderdtest.CreateTemplate(t, client, user.OrganizationID, version.ID, func(ctr *codersdk.CreateTemplateRequest) {
968+
ctr.AllowUserAutostop = ptr.Ref(false)
969+
})
970+
coderdtest.AwaitTemplateVersionJobCompleted(t, client, version.ID)
971+
workspace := coderdtest.CreateWorkspace(t, client, user.OrganizationID, template.ID)
972+
coderdtest.AwaitWorkspaceBuildJobCompleted(t, client, workspace.LatestBuild.ID)
973+
974+
require.Equal(t, false, template.AllowUserAutostop, "template should have AllowUserAutostop as false")
975+
976+
ctx := testutil.Context(t, testutil.WaitShort)
977+
ttl := 8 * time.Hour
978+
newDeadline := time.Now().Add(ttl + time.Hour).UTC()
979+
980+
err := client.PutExtendWorkspace(ctx, workspace.ID, codersdk.PutExtendWorkspaceRequest{
981+
Deadline: newDeadline,
982+
})
983+
984+
require.ErrorContains(t, err, "template does not allow user autostop")
985+
})
954986
}
955987

956988
// Blocked by autostart requirements

site/src/pages/WorkspacePage/WorkspaceTopbar.stories.tsx

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -275,3 +275,21 @@ export const WithQuota: Story = {
275275
],
276276
},
277277
};
278+
279+
export const TemplateDoesNotAllowAutostop: Story = {
280+
args: {
281+
workspace: {
282+
...MockWorkspace,
283+
latest_build: {
284+
...MockWorkspace.latest_build,
285+
get deadline() {
286+
return addHours(new Date(), 8).toISOString();
287+
},
288+
},
289+
},
290+
template: {
291+
...MockTemplate,
292+
allow_user_autostop: false,
293+
},
294+
},
295+
};

site/src/pages/WorkspacePage/WorkspaceTopbar.tsx

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -204,7 +204,9 @@ export const WorkspaceTopbar: FC<WorkspaceProps> = ({
204204
<WorkspaceScheduleControls
205205
workspace={workspace}
206206
template={template}
207-
canUpdateSchedule={canUpdateWorkspace}
207+
canUpdateSchedule={
208+
canUpdateWorkspace && template.allow_user_autostop
209+
}
208210
/>
209211
)}
210212

0 commit comments

Comments
 (0)
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