1
0
forked from baron/baron-sso
Files
baron-sso/backend/internal/bootstrap/kratos_seed.go
chan 31d107ff2e feat(user): support fixed UUID registration and enhance bulk import results
- Added support for fixed UUIDs during bulk registration (Search-first + ExternalID mapping)
- Implemented idempotency and visibility restoration for soft-deleted users
- Enhanced bulk upload UI to show 'New/Updated/Unchanged' status and modified fields
- Added logic to reclaim identifiers (login_id) from colliding records
- Added frontend E2E and backend unit tests for UUID integrity and conflict handling
- Fixed i18n, formatting, and mock tests to satisfy code-check
- Applied 'go fix' for 'omitzero' tags and general Go standards
2026-06-01 15:34:08 +09:00

76 lines
2.1 KiB
Go

package bootstrap
import (
"baron-sso-backend/internal/domain"
"log/slog"
"os"
"strings"
"time"
)
// SeedAdminIdentity creates the initial admin identity in the configured IDP.
// Returns the Kratos Identity ID and error.
func SeedAdminIdentity(idp domain.IdentityProvider) (string, error) {
if idp == nil {
return "", nil
}
adminEmail := strings.TrimSpace(os.Getenv("ADMIN_EMAIL"))
adminPassword := os.Getenv("ADMIN_PASSWORD")
if adminEmail == "" || adminPassword == "" {
slog.Warn("[Bootstrap] ADMIN_EMAIL or ADMIN_PASSWORD not set. Skipping admin identity seed.")
return "", nil
}
adminName := strings.TrimSpace(os.Getenv("ADMIN_NAME"))
if adminName == "" {
adminName = "System Admin"
}
user := &domain.BrokerUser{
Email: adminEmail,
Name: adminName,
PhoneNumber: "",
Attributes: map[string]any{
"department": "Admin",
"affiliationType": "internal",
"grade": "",
"role": "super_admin", // Explicitly set role for Kratos traits
},
}
// Retry logic for Kratos connection
maxRetries := 5
var err error
var identityID string
for i := range maxRetries {
identityID, err = idp.CreateUser(user, adminPassword)
if err == nil {
slog.Info("[Bootstrap] Admin identity created in IDP", "email", adminEmail, "idp", idp.Name(), "id", identityID)
return identityID, nil
}
if strings.Contains(err.Error(), "already exists") {
slog.Info("[Bootstrap] Admin identity already exists in IDP. Attempting to retrieve ID...", "email", adminEmail)
// Try to sign in to get the identity ID
authInfo, err := idp.SignIn(adminEmail, adminPassword)
if err == nil && authInfo != nil {
slog.Info("[Bootstrap] Retrieved existing admin identity ID", "id", authInfo.Subject)
return authInfo.Subject, nil
}
slog.Warn("[Bootstrap] Failed to retrieve existing admin identity ID via SignIn", "error", err)
return "", nil // Return nil error to avoid stopping bootstrap, but ID is missing
}
slog.Warn("[Bootstrap] Failed to seed admin identity (retrying...)",
"attempt", i+1,
"max_retries", maxRetries,
"error", err,
)
time.Sleep(2 * time.Second)
}
return "", err
}