feat(identity): 增加统一认证管理接口

提供接入码配对、配置查询、本地策略修改、验证、激活、回滚、禁用和公开运行时状态接口。写操作强制 Idempotency-Key 与 If-Match,后台 Exchange 支持重启恢复和过期收敛,并记录脱敏 Trace 与审计。\n\n验证:go test 相关 identity、store、identityruntime、httpapi 包;go vet ./apps/api/...
This commit is contained in:
2026-07-17 12:10:44 +08:00
parent a9e23cb237
commit 1fce3a535d
10 changed files with 767 additions and 33 deletions
@@ -154,3 +154,26 @@ func TestPairingRetriesWithRotatedCredentialAfterSecretStoreFailure(t *testing.T
t.Fatalf("revision did not retain SecretStore references: %#v", repository.revision)
}
}
func TestPairingExpirationIsPersistedAndExchangeTokenIsDestroyed(t *testing.T) {
repository := &pairingRepositoryFake{exchange: PairingExchange{
ID: "pairing", RevisionID: "revision", ExchangeTokenRef: "identity-exchange-pairing",
Status: PairingPreparing, RemoteVersion: 2, ExpiresAt: time.Now().Add(-time.Minute), Version: 4,
}}
secrets := &secretStoreFake{values: map[string][]byte{"identity-exchange-pairing": []byte("temporary-token")}}
service := NewPairingService(repository, secrets, func(string) (OnboardingRemote, error) {
t.Fatal("expired exchange must not call the remote service")
return nil, nil
}, nil)
expired, err := service.Continue(context.Background(), "pairing")
if err != nil {
t.Fatal(err)
}
if expired.Status != PairingExpired || expired.LastErrorCategory != "exchange_expired" {
t.Fatalf("expired pairing was not persisted: %#v", expired)
}
if _, exists := secrets.values["identity-exchange-pairing"]; exists {
t.Fatal("expired exchange token remained in SecretStore")
}
}