109 lines
2.8 KiB
Go
109 lines
2.8 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 TestGenerateIdentityDoesNotOverwrite(t *testing.T) {
|
|
path := filepath.Join(t.TempDir(), "identity.txt")
|
|
recipient, err := GenerateIdentity(path)
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
if recipient == "" {
|
|
t.Fatal("recipient is empty")
|
|
}
|
|
if _, err := GenerateIdentity(path); err == nil {
|
|
t.Fatal("GenerateIdentity() overwrote existing identity")
|
|
}
|
|
info, err := os.Stat(path)
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
if info.Mode().Perm() != 0o600 {
|
|
t.Fatalf("identity permissions = %o", info.Mode().Perm())
|
|
}
|
|
}
|