67 lines
1.4 KiB
Go
67 lines
1.4 KiB
Go
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
|
|
}
|