All checks were successful
Build and Push Image / docker-build-and-push (push) Successful in 6m2s
115 lines
3.1 KiB
Go
115 lines
3.1 KiB
Go
package vault
|
|
|
|
import (
|
|
"bytes"
|
|
"os"
|
|
"path/filepath"
|
|
"testing"
|
|
|
|
"filippo.io/age"
|
|
)
|
|
|
|
func TestStoreEncryptsUpdatesAndDeletesSecrets(t *testing.T) {
|
|
identity, err := age.GenerateX25519Identity()
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
path := filepath.Join(t.TempDir(), "vault", "secrets.age")
|
|
if err := Initialize(path, identity); err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
store := New(path, identity)
|
|
first, err := store.Set("database_password", []byte("correct horse battery staple"))
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
record := first.Secrets["database_password"]
|
|
if record.Revision == "" || string(record.Value) != "correct horse battery staple" {
|
|
t.Fatalf("record = %#v", record)
|
|
}
|
|
encrypted, err := os.ReadFile(path)
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
if bytes.Contains(encrypted, []byte("correct horse battery staple")) || bytes.Contains(encrypted, []byte("database_password")) {
|
|
t.Fatal("encrypted file contains plaintext secret material")
|
|
}
|
|
|
|
unchanged, err := store.Set("database_password", []byte("correct horse battery staple"))
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
if unchanged.Secrets["database_password"].Revision != record.Revision {
|
|
t.Fatal("setting the same value changed its revision")
|
|
}
|
|
rotated, err := store.Set("database_password", []byte("new value"))
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
if rotated.Secrets["database_password"].Revision == record.Revision {
|
|
t.Fatal("rotating a value did not change its revision")
|
|
}
|
|
if _, err := store.Delete("database_password"); err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
loaded, err := store.Load()
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
if len(loaded.Secrets) != 0 {
|
|
t.Fatalf("secrets = %#v", loaded.Secrets)
|
|
}
|
|
}
|
|
|
|
func TestStoreRejectsWrongIdentityAndInvalidValues(t *testing.T) {
|
|
identity, err := age.GenerateX25519Identity()
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
path := filepath.Join(t.TempDir(), "secrets.age")
|
|
if err := Initialize(path, identity); err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
store := New(path, identity)
|
|
if _, err := store.Set("../unsafe", []byte("value")); err == nil {
|
|
t.Fatal("Set() accepted unsafe name")
|
|
}
|
|
if _, err := store.Set("empty", nil); err == nil {
|
|
t.Fatal("Set() accepted empty value")
|
|
}
|
|
wrongIdentity, err := age.GenerateX25519Identity()
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
if _, err := New(path, wrongIdentity).Load(); err == nil {
|
|
t.Fatal("Load() succeeded with wrong identity")
|
|
}
|
|
}
|
|
|
|
func TestOpenOrInitializeCreatesReusableEmptyVault(t *testing.T) {
|
|
identity, err := age.GenerateX25519Identity()
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
directory := t.TempDir()
|
|
identityPath := filepath.Join(directory, "identity.txt")
|
|
if err := os.WriteFile(identityPath, []byte(identity.String()), 0o600); err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
path := filepath.Join(directory, "state", "secrets.age")
|
|
store, err := OpenOrInitialize(path, identityPath)
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
snapshot, err := store.Load()
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
if len(snapshot.Secrets) != 0 {
|
|
t.Fatalf("initial secrets = %#v", snapshot.Secrets)
|
|
}
|
|
if _, err := OpenOrInitialize(path, identityPath); err != nil {
|
|
t.Fatalf("OpenOrInitialize existing vault: %v", err)
|
|
}
|
|
}
|