package bootstrap import ( "baron-sso-backend/internal/domain" "log/slog" "os" "strings" "time" "gorm.io/gorm" ) // SyncAdminRole updates the role of the admin user in the local DB. // It ensures the admin user exists in the local DB with the correct Kratos ID. func SyncAdminRole(db *gorm.DB, kratosID string) error { adminEmail := strings.TrimSpace(os.Getenv("ADMIN_EMAIL")) if adminEmail == "" { slog.Warn("[Bootstrap] ADMIN_EMAIL not set. Skipping admin role sync.") return nil } adminName := strings.TrimSpace(os.Getenv("ADMIN_NAME")) if adminName == "" { adminName = "System Admin" } // Find user by email var user domain.User if err := db.Where("email = ?", adminEmail).First(&user).Error; err != nil { if err == gorm.ErrRecordNotFound { if kratosID == "" { slog.Warn("[Bootstrap] Admin user not found in local DB and Kratos ID is missing. Cannot create local user.", "email", adminEmail) return nil } // Create new admin user in local DB newUser := domain.User{ ID: kratosID, Email: adminEmail, Name: adminName, Role: domain.RoleSuperAdmin, Status: "active", CreatedAt: time.Now(), UpdatedAt: time.Now(), Metadata: domain.JSONMap{"source": "bootstrap_seed"}, } if err := db.Create(&newUser).Error; err != nil { return err } slog.Info("[Bootstrap] Created admin user in local DB", "email", adminEmail, "id", kratosID) return nil } return err } // Update role if needed updates := map[string]any{} if user.Role != domain.RoleSuperAdmin { updates["role"] = domain.RoleSuperAdmin } // Also ensure ID matches if it was somehow different (though changing PK is hard, at least log it) if kratosID != "" && user.ID != kratosID { slog.Warn("[Bootstrap] Admin user exists but ID mismatch with Kratos", "local_id", user.ID, "kratos_id", kratosID) // We generally don't change UUID PKs, just warn. } if len(updates) > 0 { if err := db.Model(&user).Updates(updates).Error; err != nil { return err } slog.Info("[Bootstrap] Updated admin user role to super_admin", "email", adminEmail) } else { slog.Info("[Bootstrap] Admin user already has super_admin role", "email", adminEmail) } return nil }