130 lines
3.9 KiB
Go
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)
|
|
}
|
|
}
|