fix: harden target recovery metadata safety

This commit is contained in:
proxyctl coordinator
2026-07-17 10:59:14 +08:00
parent a5360028ca
commit 613fe56540
7 changed files with 436 additions and 10 deletions
+37
View File
@@ -77,6 +77,43 @@ func TestShellAdapterRunsReusableTargetContract(t *testing.T) {
}
}
func TestIncompleteRecoveryMetadataRejectsRestoreWithoutChangingShellConfiguration(t *testing.T) {
fingerprint := strings.Repeat("a", 64)
cases := map[string]string{
"empty object": `{}`,
"missing restoration": `{"version":1,"fingerprint":"` + fingerprint + `","original":null}`,
"invalid fingerprint": `{"version":1,"fingerprint":"short","original":{}}`,
"conflicting originals": `{"version":1,"fingerprint":"` + fingerprint + `","original":{"HTTP_PROXY":"http://prior.example:3128"},"originalScript":"export HTTP_PROXY=http://prior.example:3128\\n"}`,
}
for name, metadata := range cases {
t.Run(name, func(t *testing.T) {
a := newAdapter(t, "/bin/bash", nil)
environment := []byte("export HTTP_PROXY='http://managed.example:8080'\n")
for path, data := range map[string][]byte{a.EnvironmentPath(): environment, a.RecoveryPath(): []byte(metadata)} {
if err := os.MkdirAll(filepath.Dir(path), 0o700); err != nil {
t.Fatal(err)
}
if err := os.WriteFile(path, data, 0o600); err != nil {
t.Fatal(err)
}
}
if inspection := a.Inspect(context.Background(), nil); inspection.State != target.Drifted {
t.Fatalf("inspection = %#v", inspection)
}
result := a.SetDesired(context.Background(), false, nil)
if result.Err == nil || result.Inspection.State != target.Drifted {
t.Fatalf("unsafe disable = %#v", result)
}
if got := readFile(t, a.EnvironmentPath()); got != string(environment) {
t.Fatalf("environment changed to %q", got)
}
if got := readFile(t, a.RecoveryPath()); got != metadata {
t.Fatalf("recovery changed to %q", got)
}
})
}
}
func TestRecoveryFailureRetryPreservesOriginalShellState(t *testing.T) {
files := &failingFS{FileSystem: shell.OSFileSystem{}, failRecoveryOnce: true}
a := newAdapterWithFS(t, "/bin/bash", map[string]string{"HTTP_PROXY": "http://prior.example:3128"}, files)