mirror of
https://github.com/coder/coder.git
synced 2025-07-13 21:36:50 +00:00
feat: don't return 200 for deleted workspaces (#1556)
This commit is contained in:
@ -4,6 +4,7 @@ import (
|
||||
"context"
|
||||
"fmt"
|
||||
"os"
|
||||
"strings"
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
@ -470,6 +471,9 @@ func mustTransitionWorkspace(t *testing.T, client *codersdk.Client, workspaceID
|
||||
func mustWorkspace(t *testing.T, client *codersdk.Client, workspaceID uuid.UUID) codersdk.Workspace {
|
||||
ctx := context.Background()
|
||||
ws, err := client.Workspace(ctx, workspaceID)
|
||||
if err != nil && strings.Contains(err.Error(), "status code 410") {
|
||||
ws, err = client.DeletedWorkspace(ctx, workspaceID)
|
||||
}
|
||||
require.NoError(t, err, "no workspace found with id %s", workspaceID)
|
||||
return ws
|
||||
}
|
||||
|
@ -7,6 +7,7 @@ import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"net/http"
|
||||
"strconv"
|
||||
"time"
|
||||
|
||||
"github.com/go-chi/chi/v5"
|
||||
@ -34,6 +35,40 @@ func (api *api) workspace(rw http.ResponseWriter, r *http.Request) {
|
||||
return
|
||||
}
|
||||
|
||||
if !api.Authorize(rw, r, rbac.ActionRead,
|
||||
rbac.ResourceWorkspace.InOrg(workspace.OrganizationID).WithOwner(workspace.OwnerID.String()).WithID(workspace.ID.String())) {
|
||||
return
|
||||
}
|
||||
|
||||
// The `deleted` query parameter (which defaults to `false`) MUST match the
|
||||
// `Deleted` field on the workspace otherwise you will get a 410 Gone.
|
||||
var (
|
||||
deletedStr = r.URL.Query().Get("deleted")
|
||||
showDeleted = false
|
||||
)
|
||||
if deletedStr != "" {
|
||||
var err error
|
||||
showDeleted, err = strconv.ParseBool(deletedStr)
|
||||
if err != nil {
|
||||
httpapi.Write(rw, http.StatusBadRequest, httpapi.Response{
|
||||
Message: fmt.Sprintf("invalid bool for 'deleted' query param: %s", err),
|
||||
})
|
||||
return
|
||||
}
|
||||
}
|
||||
if workspace.Deleted && !showDeleted {
|
||||
httpapi.Write(rw, http.StatusGone, httpapi.Response{
|
||||
Message: fmt.Sprintf("workspace %q was deleted, you can view this workspace by specifying '?deleted=true' and trying again", workspace.ID.String()),
|
||||
})
|
||||
return
|
||||
}
|
||||
if !workspace.Deleted && showDeleted {
|
||||
httpapi.Write(rw, http.StatusBadRequest, httpapi.Response{
|
||||
Message: fmt.Sprintf("workspace %q is not deleted, please remove '?deleted=true' and try again", workspace.ID.String()),
|
||||
})
|
||||
return
|
||||
}
|
||||
|
||||
build, err := api.Database.GetLatestWorkspaceBuildByWorkspaceID(r.Context(), workspace.ID)
|
||||
if err != nil {
|
||||
httpapi.Write(rw, http.StatusInternalServerError, httpapi.Response{
|
||||
|
@ -20,6 +20,58 @@ import (
|
||||
"github.com/coder/coder/provisionersdk/proto"
|
||||
)
|
||||
|
||||
func TestWorkspace(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
t.Run("OK", func(t *testing.T) {
|
||||
t.Parallel()
|
||||
client := coderdtest.New(t, nil)
|
||||
user := coderdtest.CreateFirstUser(t, client)
|
||||
coderdtest.NewProvisionerDaemon(t, client)
|
||||
version := coderdtest.CreateTemplateVersion(t, client, user.OrganizationID, nil)
|
||||
coderdtest.AwaitTemplateVersionJob(t, client, version.ID)
|
||||
template := coderdtest.CreateTemplate(t, client, user.OrganizationID, version.ID)
|
||||
workspace := coderdtest.CreateWorkspace(t, client, user.OrganizationID, template.ID)
|
||||
|
||||
_, err := client.Workspace(context.Background(), workspace.ID)
|
||||
require.NoError(t, err)
|
||||
})
|
||||
|
||||
t.Run("Deleted", func(t *testing.T) {
|
||||
t.Parallel()
|
||||
client := coderdtest.New(t, nil)
|
||||
user := coderdtest.CreateFirstUser(t, client)
|
||||
coderdtest.NewProvisionerDaemon(t, client)
|
||||
version := coderdtest.CreateTemplateVersion(t, client, user.OrganizationID, nil)
|
||||
coderdtest.AwaitTemplateVersionJob(t, client, version.ID)
|
||||
template := coderdtest.CreateTemplate(t, client, user.OrganizationID, version.ID)
|
||||
workspace := coderdtest.CreateWorkspace(t, client, user.OrganizationID, template.ID)
|
||||
coderdtest.AwaitWorkspaceBuildJob(t, client, workspace.LatestBuild.ID)
|
||||
|
||||
// Getting with deleted=true should fail.
|
||||
_, err := client.DeletedWorkspace(context.Background(), workspace.ID)
|
||||
require.Error(t, err)
|
||||
require.ErrorContains(t, err, "400") // bad request
|
||||
|
||||
// Delete the workspace
|
||||
build, err := client.CreateWorkspaceBuild(context.Background(), workspace.ID, codersdk.CreateWorkspaceBuildRequest{
|
||||
Transition: database.WorkspaceTransitionDelete,
|
||||
})
|
||||
require.NoError(t, err, "delete the workspace")
|
||||
coderdtest.AwaitWorkspaceBuildJob(t, client, build.ID)
|
||||
|
||||
// Getting with deleted=true should work.
|
||||
workspaceNew, err := client.DeletedWorkspace(context.Background(), workspace.ID)
|
||||
require.NoError(t, err)
|
||||
require.Equal(t, workspace.ID, workspaceNew.ID)
|
||||
|
||||
// Getting with deleted=false should not work.
|
||||
_, err = client.Workspace(context.Background(), workspace.ID)
|
||||
require.Error(t, err)
|
||||
require.ErrorContains(t, err, "410") // gone
|
||||
})
|
||||
}
|
||||
|
||||
func TestAdminViewAllWorkspaces(t *testing.T) {
|
||||
t.Parallel()
|
||||
client := coderdtest.New(t, nil)
|
||||
|
Reference in New Issue
Block a user