package secretstore import ( "bytes" "os" "path/filepath" "runtime" "testing" ) func TestStorePersistsSecretsOutsideCallerSnapshots(t *testing.T) { path := filepath.Join(t.TempDir(), "secrets.json") store, err := Open(path) if err != nil { t.Fatal(err) } want := []byte("operation password") if err := store.Set("port.pending.ch01.1", want); err != nil { t.Fatal(err) } reloaded, err := Open(path) if err != nil { t.Fatal(err) } actual, ok := reloaded.Get("port.pending.ch01.1") if !ok || !bytes.Equal(actual, want) { t.Fatalf("Get() = %q, %t", actual, ok) } if runtime.GOOS != "windows" { info, err := os.Stat(path) if err != nil { t.Fatal(err) } if info.Mode().Perm() != 0o600 { t.Fatalf("mode = %o", info.Mode().Perm()) } } if err := reloaded.Copy("port.pending.ch01.1", "port.running.ch01.1"); err != nil { t.Fatal(err) } if err := reloaded.Delete("port.pending.ch01.1"); err != nil { t.Fatal(err) } if _, ok := reloaded.Get("port.pending.ch01.1"); ok { t.Fatal("deleted secret is still present") } } func TestStoreRejectsUnsafeKeysAndEmptyValues(t *testing.T) { store, _ := Open("") if err := store.Set("../escape", []byte("secret")); err == nil { t.Fatal("unsafe key accepted") } if err := store.Set("safe.key", nil); err == nil { t.Fatal("empty secret accepted") } } func TestStoreDeletePrefixesRemovesOnlySelectedNamespaces(t *testing.T) { path := filepath.Join(t.TempDir(), "secrets.json") store, err := Open(path) if err != nil { t.Fatal(err) } for key, value := range map[string]string{ "port.pending.ch01.1": "pending-port", "config/pending/smtp/password": "pending-smtp", "external/pending/radius/server1": "pending-radius", "port.running.ch01.1": "running-port", "config/persistent/smtp/password": "saved-smtp", } { if err := store.Set(key, []byte(value)); err != nil { t.Fatal(err) } } if err := store.DeletePrefixes("port.pending.", "config/pending/", "external/pending/"); err != nil { t.Fatal(err) } for _, key := range []string{"port.pending.ch01.1", "config/pending/smtp/password", "external/pending/radius/server1"} { if store.Has(key) { t.Fatalf("pending secret %q was not removed", key) } } for _, key := range []string{"port.running.ch01.1", "config/persistent/smtp/password"} { if !store.Has(key) { t.Fatalf("non-pending secret %q was removed", key) } } if err := store.DeletePrefixes(); err == nil { t.Fatal("empty prefix list was accepted") } if err := store.DeletePrefixes("../"); err == nil { t.Fatal("unsafe prefix was accepted") } }