|
|
//
|
|
|
// Copyright (C) 2024 veypi <i@veypi.com>
|
|
|
// 2024-09-20 16:10:16
|
|
|
// Distributed under terms of the MIT license.
|
|
|
//
|
|
|
|
|
|
package models
|
|
|
|
|
|
import (
|
|
|
"fmt"
|
|
|
"time"
|
|
|
|
|
|
"github.com/veypi/vbase/cfg"
|
|
|
"github.com/veypi/vbase/libs/crypto"
|
|
|
"github.com/veypi/vigo"
|
|
|
"github.com/veypi/vigo/contrib/event"
|
|
|
)
|
|
|
|
|
|
var AllModels = &vigo.ModelList{}
|
|
|
|
|
|
func init() {
|
|
|
// 注册所有模型
|
|
|
AllModels.Add(&User{})
|
|
|
AllModels.Add(&Identity{})
|
|
|
AllModels.Add(&Session{})
|
|
|
AllModels.Add(&Org{})
|
|
|
AllModels.Add(&OrgMember{})
|
|
|
|
|
|
// Auth 模块模型
|
|
|
AllModels.Add(&Permission{})
|
|
|
AllModels.Add(&Role{})
|
|
|
AllModels.Add(&RolePermission{})
|
|
|
AllModels.Add(&UserRole{})
|
|
|
AllModels.Add(&UserPermission{})
|
|
|
|
|
|
// OAuth 模型
|
|
|
AllModels.Add(&OAuthClient{})
|
|
|
AllModels.Add(&OAuthAuthorizationCode{})
|
|
|
AllModels.Add(&OAuthToken{})
|
|
|
|
|
|
// 配置 & 验证码 & 邮件
|
|
|
AllModels.Add(&Setting{})
|
|
|
AllModels.Add(&VerificationCode{})
|
|
|
AllModels.Add(&EmailLog{})
|
|
|
AllModels.Add(&OAuthProvider{})
|
|
|
event.Add("vb.init.settings", InitSettings)
|
|
|
event.Add("vb.init.oauth", InitOAuthProviders)
|
|
|
event.Add("vb.init.admin", initAdminUser, event.After("vb.init.auth"))
|
|
|
}
|
|
|
|
|
|
func Migrate() error {
|
|
|
return AllModels.AutoMigrate(cfg.DB())
|
|
|
}
|
|
|
|
|
|
func Drop() error {
|
|
|
return AllModels.AutoDrop(cfg.DB())
|
|
|
}
|
|
|
|
|
|
// initAdminUser 如果用户表为空且配置了 init_admin,则自动创建管理员
|
|
|
func initAdminUser() error {
|
|
|
db := cfg.DB()
|
|
|
|
|
|
// 检查用户表是否为空
|
|
|
var userCount int64
|
|
|
if err := db.Model(&User{}).Count(&userCount).Error; err != nil {
|
|
|
return err
|
|
|
}
|
|
|
|
|
|
// 已有用户,跳过
|
|
|
if userCount > 0 {
|
|
|
return nil
|
|
|
}
|
|
|
|
|
|
// 检查 init_admin 配置
|
|
|
adminCfg := cfg.Global.InitAdmin
|
|
|
if adminCfg.Username == "" || adminCfg.Password == "" {
|
|
|
// 未配置初始管理员,跳过
|
|
|
return nil
|
|
|
}
|
|
|
|
|
|
// 查找 admin 角色
|
|
|
var adminRole Role
|
|
|
if err := db.Where("code = ? AND org_id IS NULL", RoleCodeAdmin).First(&adminRole).Error; err != nil {
|
|
|
return fmt.Errorf("admin role not found, please ensure roles are initialized: %w", err)
|
|
|
}
|
|
|
|
|
|
// 哈希密码(使用默认 bcrypt cost = 12)
|
|
|
hashedPassword, err := crypto.HashPassword(adminCfg.Password, 12)
|
|
|
if err != nil {
|
|
|
return fmt.Errorf("hash password failed: %w", err)
|
|
|
}
|
|
|
|
|
|
// 创建用户
|
|
|
var email *string
|
|
|
if adminCfg.Email != "" {
|
|
|
email = &adminCfg.Email
|
|
|
}
|
|
|
|
|
|
now := time.Now()
|
|
|
user := &User{
|
|
|
Username: adminCfg.Username,
|
|
|
Password: hashedPassword,
|
|
|
Email: email,
|
|
|
Nickname: adminCfg.Username,
|
|
|
Status: UserStatusActive,
|
|
|
EmailVerified: email != nil,
|
|
|
LastLoginAt: &now,
|
|
|
}
|
|
|
|
|
|
if err := db.Create(user).Error; err != nil {
|
|
|
return fmt.Errorf("create admin user failed: %w", err)
|
|
|
}
|
|
|
|
|
|
// 授予 admin 角色
|
|
|
userRole := &UserRole{
|
|
|
UserID: user.ID,
|
|
|
RoleID: adminRole.ID,
|
|
|
OrgID: nil, // 系统级 admin
|
|
|
}
|
|
|
|
|
|
if err := db.Create(userRole).Error; err != nil {
|
|
|
return fmt.Errorf("grant admin role failed: %w", err)
|
|
|
}
|
|
|
|
|
|
fmt.Printf("[vbase] Initial admin user '%s' created successfully\n", adminCfg.Username)
|
|
|
return nil
|
|
|
}
|