go-quasar-partial-ssr/backend/internal/seed/seed.go

105 lines
2.5 KiB
Go

package seed
import (
"crypto/rand"
"encoding/hex"
"fmt"
"time"
"github.com/brianvoe/gofakeit/v6"
"gorm.io/gorm"
"server/internal/auth"
"server/internal/models"
)
// Credential exposes the plaintext password generated for a seeded user.
type Credential struct {
Email string
Password string
}
// SeedUsers generates n fake users and persists them. Returns the created slice.
func SeedUsers(db *gorm.DB, n int) ([]models.User, []Credential, error) {
if n <= 0 {
return nil, nil, fmt.Errorf("seed size must be greater than zero")
}
gofakeit.Seed(time.Now().UnixNano())
items := make([]models.User, 0, n)
creds := make([]Credential, 0, n)
for i := 0; i < n; i++ {
now := time.Now().UTC()
uuid := gofakeit.UUID()
email := gofakeit.Email()
pw, err := randomPassword()
if err != nil {
return nil, nil, fmt.Errorf("generate password: %w", err)
}
passwordHash, err := auth.HashPassword(pw)
if err != nil {
return nil, nil, fmt.Errorf("hash seed password: %w", err)
}
item := models.User{
Email: email,
Name: gofakeit.Name(),
Password: passwordHash,
Roles: models.UserRoles{"user"},
Status: models.UserStatusActive,
Types: models.UserTypes{"internal"},
UUID: uuid,
Details: &models.UserDetails{
Title: gofakeit.JobTitle(),
FirstName: gofakeit.FirstName(),
LastName: gofakeit.LastName(),
Phone: gofakeit.Phone(),
Address: gofakeit.Street(),
City: gofakeit.City(),
ZipCode: gofakeit.Zip(),
Country: gofakeit.Country(),
},
Preferences: &models.UserPreferences{
UseIdle: gofakeit.Bool(),
IdleTimeout: gofakeit.Number(1, 30),
UseIdlePassword: gofakeit.Bool(),
IdlePin: gofakeit.DigitN(6),
UseDirectLogin: gofakeit.Bool(),
UseQuadcodeLogin: gofakeit.Bool(),
SendNoticesMail: gofakeit.Bool(),
Language: gofakeit.Language(),
},
Avatar: nil,
CreatedAt: now,
UpdatedAt: now,
ActivatedAt: func() *time.Time {
ts := now
return &ts
}(),
}
items = append(items, item)
creds = append(creds, Credential{
Email: email,
Password: pw,
})
}
if err := db.Create(&items).Error; err != nil {
return nil, nil, fmt.Errorf("insert users: %w", err)
}
return items, creds, nil
}
func randomPassword() (string, error) {
buf := make([]byte, 12)
if _, err := rand.Read(buf); err != nil {
return "", err
}
// hex-encoded -> 24 characters.
return hex.EncodeToString(buf), nil
}