Files
Agent-System-Backend/internal/app/super_admin_test.go
T

130 lines
3.9 KiB
Go

package app
import (
"bytes"
"errors"
"log"
"os"
"path/filepath"
"strings"
"testing"
"agent-system-backend/internal/config"
"agent-system-backend/internal/store"
)
const appSuperAdminPassword = "Sup3r-Secret-Value"
func openSuperAdminStore(t *testing.T) *store.Store {
t.Helper()
st, err := store.OpenSQLite(filepath.Join(t.TempDir(), "agent-system.db"))
if err != nil {
t.Fatal(err)
}
t.Cleanup(func() { st.Close() })
return st
}
func captureLog(t *testing.T) *bytes.Buffer {
t.Helper()
var buf bytes.Buffer
prev, flags := log.Writer(), log.Flags()
log.SetOutput(&buf)
t.Cleanup(func() { log.SetOutput(prev); log.SetFlags(flags) })
return &buf
}
func TestValidateSuperAdminStartupGate(t *testing.T) {
cases := []struct {
name string
sa config.SuperAdmin
}{
{"both absent", config.SuperAdmin{}},
{"owner only", config.NewSuperAdmin("root", "")},
{"password only", config.NewSuperAdmin("", appSuperAdminPassword)},
{"invalid password", config.NewSuperAdmin("root", "short")},
}
for _, tc := range cases {
t.Run(tc.name, func(t *testing.T) {
err := ValidateSuperAdmin(true, tc.sa)
if !errors.Is(err, config.ErrSuperAdminConfig) {
t.Fatalf("authentication-enabled startup accepted %s: %v", tc.name, err)
}
if err := ValidateSuperAdmin(false, tc.sa); err != nil {
t.Fatalf("unauthenticated mode must not require credentials: %v", err)
}
})
}
if err := ValidateSuperAdmin(true, config.NewSuperAdmin("root", appSuperAdminPassword)); err != nil {
t.Fatal(err)
}
}
func TestBootstrapSuperAdminStartup(t *testing.T) {
st := openSuperAdminStore(t)
logs := captureLog(t)
sa := config.NewSuperAdmin("root", appSuperAdminPassword)
for i := 0; i < 2; i++ {
if err := BootstrapSuperAdmin(st, true, sa); err != nil {
t.Fatalf("bootstrap %d: %v", i, err)
}
}
account, err := st.GetAccountByOwner("root")
if err != nil {
t.Fatal(err)
}
if !account.IsSuperAdmin || !account.IsAdmin {
t.Fatalf("startup did not establish super admin: %+v", account)
}
if strings.Contains(logs.String(), appSuperAdminPassword) || strings.Contains(logs.String(), "argon2") {
t.Fatalf("startup log leaks credential material: %s", logs.String())
}
if !strings.Contains(logs.String(), "established account") || !strings.Contains(logs.String(), "already established") {
t.Fatalf("startup log lacks bootstrap outcome: %s", logs.String())
}
}
func TestBootstrapSuperAdminStartupFailsClosed(t *testing.T) {
st := openSuperAdminStore(t)
if err := st.CreateAccount("root", "", "", false); err != nil {
t.Fatal(err)
}
err := BootstrapSuperAdmin(st, true, config.NewSuperAdmin("root", appSuperAdminPassword))
if !errors.Is(err, store.ErrSuperAdminConflict) {
t.Fatalf("conflicting owner did not stop startup: %v", err)
}
if strings.Contains(err.Error(), appSuperAdminPassword) {
t.Fatalf("startup error leaks password: %v", err)
}
if err := BootstrapSuperAdmin(st, true, config.NewSuperAdmin("root", "short")); !errors.Is(err, config.ErrSuperAdminConfig) {
t.Fatalf("invalid password reached storage: %v", err)
}
}
func TestBootstrapSuperAdminSkippedWithoutAuthentication(t *testing.T) {
st := openSuperAdminStore(t)
if err := BootstrapSuperAdmin(st, false, config.SuperAdmin{}); err != nil {
t.Fatal(err)
}
users, err := st.ListUsersAdmin()
if err != nil {
t.Fatal(err)
}
if len(users) != 0 {
t.Fatalf("unauthenticated mode created accounts: %d", len(users))
}
}
func TestCLIAccountPathsCannotAppointAdministrators(t *testing.T) {
dir := t.TempDir()
if _, _, err := CreateUserAccount("", dir, "mallory", "", "", true, true, false); !errors.Is(err, ErrCLIAdminAppointment) {
t.Fatalf("CLI create --admin: %v", err)
}
if _, err := BootstrapAdmin("", dir, "mallory", false); !errors.Is(err, ErrCLIBootstrapAdminDisabled) {
t.Fatalf("CLI bootstrap-admin: %v", err)
}
if _, err := os.Stat(filepath.Join(dir, "agent-system.db")); !os.IsNotExist(err) {
t.Fatalf("rejected CLI paths touched storage: %v", err)
}
}