package rest import ( "context" "crypto/rand" "log/slog" "math/big" "strings" "goAuth/internal/user" ) const ( AdminLogin = "admin" adminPasswordLength = 16 adminPasswordAlphabet = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789" ) // seed creates the initial admin user with a random password, but only on the // first startup when no users exist yet. func seed(ctx context.Context, users *user.Service) error { count, err := users.CountUsers(ctx, true) if err != nil { return err } if count > 0 { return nil } password, err := generatePassword(adminPasswordLength) if err != nil { return err } admin, err := users.CreateAdmin(ctx, AdminLogin, password) if err != nil { return err } slog.Info("seeded admin user", slog.String("op", "rest.seed"), slog.Int64("user_id", admin.Id), slog.String("login", admin.Login), slog.String("password", password), ) return nil } func generatePassword(length int) (string, error) { alphabetLen := big.NewInt(int64(len(adminPasswordAlphabet))) var builder strings.Builder builder.Grow(length) for range length { randIndex, err := rand.Int(rand.Reader, alphabetLen) if err != nil { slog.Error("generate admin password", slog.String("op", "rest.generatePassword"), slog.Any("error", err)) return "", err } builder.WriteByte(adminPasswordAlphabet[randIndex.Int64()]) } return builder.String(), nil }