Pulse/internal/bootstrap/token_store_test.go
2026-03-18 16:06:30 +00:00

107 lines
2.7 KiB
Go

package bootstrap
import (
"errors"
"os"
"path/filepath"
"strings"
"testing"
)
func createToken() (string, error) {
return "0123456789abcdef0123456789abcdef0123456789abcdef", nil
}
func TestLoadOrCreate_CreatesEncryptedTokenFile(t *testing.T) {
dataPath := t.TempDir()
token, created, path, migrated, err := LoadOrCreate(dataPath, createToken)
if err != nil {
t.Fatalf("LoadOrCreate() error = %v", err)
}
if !created {
t.Fatal("expected created=true")
}
if migrated {
t.Fatal("expected migrated=false")
}
if token == "" {
t.Fatal("expected token")
}
data, err := os.ReadFile(path)
if err != nil {
t.Fatalf("ReadFile() error = %v", err)
}
if strings.Contains(string(data), token) {
t.Fatalf("bootstrap token persisted in plaintext: %q", string(data))
}
reloaded, loadPath, migrated, err := Load(dataPath)
if err != nil {
t.Fatalf("Load() error = %v", err)
}
if migrated {
t.Fatal("expected migrated=false on encrypted read")
}
if loadPath != path {
t.Fatalf("load path = %q, want %q", loadPath, path)
}
if reloaded != token {
t.Fatalf("reloaded token = %q, want %q", reloaded, token)
}
}
func TestLoadOrCreate_MigratesLegacyPlaintextFile(t *testing.T) {
dataPath := t.TempDir()
path := filepath.Join(dataPath, TokenFilename)
const legacyToken = "legacy-bootstrap-token"
if err := os.WriteFile(path, []byte(legacyToken+"\n"), 0o600); err != nil {
t.Fatalf("WriteFile() error = %v", err)
}
token, created, gotPath, migrated, err := LoadOrCreate(dataPath, createToken)
if err != nil {
t.Fatalf("LoadOrCreate() error = %v", err)
}
if created {
t.Fatal("expected created=false")
}
if !migrated {
t.Fatal("expected migrated=true")
}
if gotPath != path {
t.Fatalf("path = %q, want %q", gotPath, path)
}
if token != legacyToken {
t.Fatalf("token = %q, want %q", token, legacyToken)
}
data, err := os.ReadFile(path)
if err != nil {
t.Fatalf("ReadFile() error = %v", err)
}
if strings.Contains(string(data), legacyToken) {
t.Fatalf("expected legacy token to be rewritten encrypted, got %q", string(data))
}
}
func TestLoad_MissingFile(t *testing.T) {
_, _, _, err := Load(t.TempDir())
if !errors.Is(err, os.ErrNotExist) {
t.Fatalf("Load() error = %v, want ErrNotExist", err)
}
}
func TestLoad_InvalidEncryptedPayload(t *testing.T) {
dataPath := t.TempDir()
path := filepath.Join(dataPath, TokenFilename)
if err := os.WriteFile(path, []byte(`{"version":2,"token_ciphertext":"broken","token_hash":"abc"}`), 0o600); err != nil {
t.Fatalf("WriteFile() error = %v", err)
}
_, _, _, err := Load(dataPath)
if err == nil || !strings.Contains(err.Error(), "decrypt bootstrap token") {
t.Fatalf("Load() error = %v, want decrypt bootstrap token", err)
}
}