59 lines
2.0 KiB
Go
59 lines
2.0 KiB
Go
package app
|
|
|
|
import (
|
|
"errors"
|
|
"fmt"
|
|
"log"
|
|
|
|
"agent-system-backend/internal/config"
|
|
"agent-system-backend/internal/server"
|
|
"agent-system-backend/internal/store"
|
|
)
|
|
|
|
// ErrCLIAdminAppointment rejects every local CLI attempt to create an
|
|
// administrator (R4, R5): only the server-side super administrator appoints.
|
|
var ErrCLIAdminAppointment = errors.New("administrator appointment is reserved to the super administrator; no CLI path may create an administrator")
|
|
|
|
// ErrCLIBootstrapAdminDisabled rejects the retired local bootstrap-admin path:
|
|
// only service startup establishes the super administrator (KTD4).
|
|
var ErrCLIBootstrapAdminDisabled = errors.New("bootstrap-admin is disabled; the super administrator is established at service startup from SUPER_ADMIN_OWNER and SUPER_ADMIN_PASSWORD")
|
|
|
|
// ValidateSuperAdmin is the startup gate for R1: with authentication enabled,
|
|
// missing, partial or policy-violating configuration refuses startup. The
|
|
// unauthenticated embedded mode neither requires nor uses the credentials.
|
|
func ValidateSuperAdmin(authOn bool, sa config.SuperAdmin) error {
|
|
if !authOn {
|
|
return nil
|
|
}
|
|
if err := sa.Validate(server.ValidatePassword); err != nil {
|
|
return fmt.Errorf("super admin: %w", err)
|
|
}
|
|
return nil
|
|
}
|
|
|
|
// BootstrapSuperAdmin establishes the configured super administrator in
|
|
// persistent account state (KTD4). Identity conflicts stop startup; logs carry
|
|
// the owner only, never the password or its hash.
|
|
func BootstrapSuperAdmin(st *store.Store, authOn bool, sa config.SuperAdmin) error {
|
|
if !authOn {
|
|
return nil
|
|
}
|
|
if err := ValidateSuperAdmin(authOn, sa); err != nil {
|
|
return err
|
|
}
|
|
hash, err := store.HashPassword(sa.Password())
|
|
if err != nil {
|
|
return fmt.Errorf("super admin: hash password: %w", err)
|
|
}
|
|
out, err := st.BootstrapSuperAdmin(sa.Owner, hash)
|
|
if err != nil {
|
|
return fmt.Errorf("super admin %q: %w", sa.Owner, err)
|
|
}
|
|
if out.Created {
|
|
log.Printf("super admin: established account %q", sa.Owner)
|
|
} else {
|
|
log.Printf("super admin: account %q already established", sa.Owner)
|
|
}
|
|
return nil
|
|
}
|