Files
Agent-System-Backend/internal/store/owner_initialization_test.go
weichen b9c0a344b6 Implement owner-confirmed account recovery and account controls
Why: Administrator-issued password and login-key paths could take over target accounts, while old credentials and plugin handles ignored current account state.

Evidence: SELF receipts /tmp/iam-u3-backend-all-replay.json, /tmp/iam-u3-backend-final-pg-core.json, /tmp/iam-u3-backend-build.json, and focused HTTP/concurrency receipts in /tmp/iam-u3-*.json.

Impact: Adds trusted pending-account initialization and reissue, preexisting owner-session proof, proposal/rotation/grant transactions, server-side admin search, current Host guards, and legacy HTTP/CLI closure. Production cutover and downstream pins remain pending.

Refs: IAM U3 r1 stages 4-5; Dev feature/iam-u3-account-directory-recovery
2026-10-14 04:20:48 +00:00

57 lines
2.1 KiB
Go

package store
import (
"errors"
"testing"
)
func TestOwnerInitializationReissuesSamePendingIdentityAndClosesAfterCompletion(t *testing.T) {
st := openTestStore(t)
t.Logf("owner initialization dialect=%s", st.Dialect())
if err := st.CreateAccount("admin", "", "admin-hash", true); err != nil {
t.Fatal(err)
}
pending, err := st.CreatePendingAccount("admin", "alice", AccountProfile{Name: "Alice"})
if err != nil {
t.Fatal(err)
}
first, err := st.InitializePendingAccount(pending.ID, pending.StateVersion, pending.InitializationGeneration)
if err != nil || first == "" {
t.Fatalf("initialize pending: %v", err)
}
firstSession, owner, err := st.RedeemLoginKey(first)
if err != nil || owner != "alice" {
t.Fatalf("redeem first activation: %v %q", err, owner)
}
stillPending, err := st.GetAccount(pending.ID)
if err != nil {
t.Fatal(err)
}
second, err := st.InitializePendingAccount(pending.ID, stillPending.StateVersion, stillPending.InitializationGeneration)
if err != nil || second == first {
t.Fatalf("reissue: %v", err)
}
if _, _, ok := st.SessionInfo(firstSession); ok {
t.Fatal("reissue left old restricted session active")
}
secondSession, owner, err := st.RedeemLoginKey(second)
if err != nil || owner != "alice" {
t.Fatalf("redeem second activation: %v %q", err, owner)
}
hash, err := HashPassword("alice-initialized-password")
if err != nil {
t.Fatal(err)
}
if _, err := st.CompleteSetPasswordChecked(secondSession, hash); err != nil {
t.Fatalf("complete initial password: %v", err)
}
completed, err := st.GetAccount(pending.ID)
if err != nil || completed.ID != pending.ID || completed.Owner != pending.Owner || completed.InitializationState != InitializationInitialized ||
completed.CredentialOrigin != CredentialOriginOwnerInitialization || !completed.HasPassword {
t.Fatalf("completion changed identity or lost trusted lineage: %+v %v", completed, err)
}
if _, err := st.InitializePendingAccount(pending.ID, completed.StateVersion, completed.InitializationGeneration); !errors.Is(err, ErrAccountForbidden) {
t.Fatalf("completed account could be initialized again: %v", err)
}
}