fix(auth): validate stopped workspace restore

This commit is contained in:
2026-08-18 00:06:28 +02:00
parent e8b9995ed0
commit 0651f3316f
6 changed files with 300 additions and 11 deletions
+85
View File
@@ -5,6 +5,7 @@ import (
"bytes"
"context"
"errors"
"fmt"
"io"
"os"
"path/filepath"
@@ -511,6 +512,90 @@ func (runner *authenticationStateResetRunner) Stream(context.Context, []string,
func (*authenticationStateResetRunner) SessionInventoryScope() string { return "mine" }
type workspaceVerificationRunner struct {
running bool
result compose.Result
err error
calls []string
}
func (runner *workspaceVerificationRunner) Run(_ context.Context, args []string, _ io.Reader) (compose.Result, error) {
command := strings.Join(args, " ")
runner.calls = append(runner.calls, command)
if strings.Contains(command, " ps --all --format json") {
if runner.running {
return compose.Result{Stdout: healthyServicesPayload()}, nil
}
return compose.Result{}, nil
}
if strings.Contains(command, "operator-command.js workspace-integrity") {
return runner.result, runner.err
}
return compose.Result{}, fmt.Errorf("unexpected workspace verification command: %s", command)
}
func (*workspaceVerificationRunner) Stream(context.Context, []string, io.Reader, io.Writer) (compose.Result, error) {
return compose.Result{}, errors.New("workspace verification must not stream")
}
func (*workspaceVerificationRunner) SessionInventoryScope() string { return "mine" }
func TestVerifyRestoreWorkspaceUsesFixedNonNetworkOperatorPath(t *testing.T) {
installation := preflightTestInstallation(t)
for _, test := range []struct {
name string
running bool
payload string
prefix string
}{
{name: "stopped uninitialized", payload: `{"ready":true,"state":"uninitialized","workspaces":0}`, prefix: "run --rm --no-deps --no-TTY core"},
{name: "running active", running: true, payload: `{"ready":true,"state":"active","workspaces":1}`, prefix: "exec -T core"},
} {
t.Run(test.name, func(t *testing.T) {
runner := &workspaceVerificationRunner{
running: test.running,
result: compose.Result{Stdout: test.payload},
}
if err := verifyRestoreWorkspace(context.Background(), installation, runner); err != nil {
t.Fatalf("verify restored workspace: %v", err)
}
if len(runner.calls) != 2 || !strings.Contains(runner.calls[1], test.prefix+" node /app/backend/dist/operator-command.js workspace-integrity") {
t.Fatalf("workspace verification calls = %#v", runner.calls)
}
for _, call := range runner.calls {
if strings.Contains(call, "curl") || strings.Contains(call, "-e const") || strings.Contains(strings.ToLower(call), "header") {
t.Fatalf("workspace verification used an unsafe command: %s", call)
}
}
})
}
}
func TestVerifyRestoreWorkspaceRejectsInvalidOperatorResults(t *testing.T) {
installation := preflightTestInstallation(t)
for _, test := range []struct {
name string
result compose.Result
err error
}{
{name: "empty"},
{name: "malformed", result: compose.Result{Stdout: `{malformed`}},
{name: "trailing document", result: compose.Result{Stdout: `{"ready":true,"state":"active","workspaces":1}{}`}},
{name: "unknown field", result: compose.Result{Stdout: `{"ready":true,"state":"active","workspaces":1,"detail":"unsafe"}`}},
{name: "not ready", result: compose.Result{Stdout: `{"ready":false,"state":"uninitialized","workspaces":0}`}},
{name: "unknown state", result: compose.Result{Stdout: `{"ready":true,"state":"unknown","workspaces":0}`}},
{name: "inconsistent count", result: compose.Result{Stdout: `{"ready":true,"state":"uninitialized","workspaces":1}`}},
{name: "nonzero", result: compose.Result{ExitCode: 2}, err: errors.New("exit status 2")},
} {
t.Run(test.name, func(t *testing.T) {
runner := &workspaceVerificationRunner{result: test.result, err: test.err}
if err := verifyRestoreWorkspace(context.Background(), installation, runner); err == nil {
t.Fatal("invalid workspace verification result was accepted")
}
})
}
}
func (lock fakeRestoreLock) Release() error {
if lock.release != nil {
lock.release()