2025-12-02 10:33:19 +08:00
|
|
|
package database
|
|
|
|
|
|
|
|
|
|
import (
|
|
|
|
|
"carrotskin/internal/model"
|
|
|
|
|
|
|
|
|
|
"go.uber.org/zap"
|
|
|
|
|
"golang.org/x/crypto/bcrypt"
|
|
|
|
|
"gorm.io/gorm"
|
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
// 默认管理员配置
|
|
|
|
|
const (
|
|
|
|
|
defaultAdminUsername = "admin"
|
|
|
|
|
defaultAdminEmail = "admin@example.com"
|
2025-12-08 19:12:30 +08:00
|
|
|
defaultAdminPassword = "admin123456" // 首次登录后请立即修改,部署到生产环境后删除
|
2025-12-02 10:33:19 +08:00
|
|
|
)
|
|
|
|
|
|
|
|
|
|
// defaultCasbinRules 默认Casbin权限规则
|
2025-12-08 19:12:30 +08:00
|
|
|
// 规则格式: {PType: "p", V0: "角色", V1: "资源", V2: "操作"}
|
|
|
|
|
// PType "p" 表示策略规则,"g" 表示角色继承
|
2025-12-02 10:33:19 +08:00
|
|
|
var defaultCasbinRules = []model.CasbinRule{
|
2025-12-08 19:12:30 +08:00
|
|
|
// ==================== 管理员权限 ====================
|
|
|
|
|
// 管理员拥有所有权限(通配符)
|
2025-12-02 10:33:19 +08:00
|
|
|
{PType: "p", V0: "admin", V1: "*", V2: "*"},
|
2025-12-08 19:12:30 +08:00
|
|
|
|
|
|
|
|
// ==================== 普通用户权限 ====================
|
|
|
|
|
// --- 用户资源 (user) ---
|
|
|
|
|
{PType: "p", V0: "user", V1: "user", V2: "read_own"}, // 查看自己的信息
|
|
|
|
|
{PType: "p", V0: "user", V1: "user", V2: "update_own"}, // 更新自己的信息
|
|
|
|
|
|
|
|
|
|
// --- 材质资源 (texture) ---
|
|
|
|
|
{PType: "p", V0: "user", V1: "texture", V2: "read"}, // 查看材质(公开)
|
|
|
|
|
{PType: "p", V0: "user", V1: "texture", V2: "create"}, // 上传材质
|
|
|
|
|
{PType: "p", V0: "user", V1: "texture", V2: "update_own"}, // 更新自己的材质
|
|
|
|
|
{PType: "p", V0: "user", V1: "texture", V2: "delete_own"}, // 删除自己的材质
|
|
|
|
|
{PType: "p", V0: "user", V1: "texture", V2: "favorite"}, // 收藏材质
|
|
|
|
|
|
|
|
|
|
// --- 档案资源 (profile) ---
|
|
|
|
|
{PType: "p", V0: "user", V1: "profile", V2: "read"}, // 查看档案(公开)
|
|
|
|
|
{PType: "p", V0: "user", V1: "profile", V2: "create"}, // 创建档案
|
|
|
|
|
{PType: "p", V0: "user", V1: "profile", V2: "update_own"}, // 更新自己的档案
|
|
|
|
|
{PType: "p", V0: "user", V1: "profile", V2: "delete_own"}, // 删除自己的档案
|
|
|
|
|
|
|
|
|
|
// --- Yggdrasil资源 (yggdrasil) ---
|
|
|
|
|
{PType: "p", V0: "user", V1: "yggdrasil", V2: "auth"}, // Yggdrasil认证
|
|
|
|
|
{PType: "p", V0: "user", V1: "yggdrasil", V2: "reset_password"}, // 重置Yggdrasil密码
|
|
|
|
|
|
|
|
|
|
// ==================== 角色继承 ====================
|
|
|
|
|
// admin 继承 user 的所有权限
|
2025-12-02 10:33:19 +08:00
|
|
|
{PType: "g", V0: "admin", V1: "user"},
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Seed 初始化种子数据
|
|
|
|
|
func Seed(logger *zap.Logger) error {
|
|
|
|
|
db, err := GetDB()
|
|
|
|
|
if err != nil {
|
|
|
|
|
return err
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
logger.Info("开始初始化种子数据...")
|
|
|
|
|
|
|
|
|
|
// 初始化默认管理员用户
|
|
|
|
|
if err := seedAdminUser(db, logger); err != nil {
|
|
|
|
|
return err
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 初始化Casbin权限规则
|
|
|
|
|
if err := seedCasbinRules(db, logger); err != nil {
|
|
|
|
|
return err
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
logger.Info("种子数据初始化完成")
|
|
|
|
|
return nil
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// seedAdminUser 初始化默认管理员用户
|
|
|
|
|
func seedAdminUser(db *gorm.DB, logger *zap.Logger) error {
|
|
|
|
|
// 检查是否已存在管理员用户
|
|
|
|
|
var count int64
|
|
|
|
|
if err := db.Model(&model.User{}).Where("role = ?", "admin").Count(&count).Error; err != nil {
|
|
|
|
|
logger.Error("检查管理员用户失败", zap.Error(err))
|
|
|
|
|
return err
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 如果已存在管理员,跳过创建
|
|
|
|
|
if count > 0 {
|
|
|
|
|
logger.Info("管理员用户已存在,跳过创建")
|
|
|
|
|
return nil
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 加密密码
|
|
|
|
|
hashedPassword, err := bcrypt.GenerateFromPassword([]byte(defaultAdminPassword), bcrypt.DefaultCost)
|
|
|
|
|
if err != nil {
|
|
|
|
|
logger.Error("密码加密失败", zap.Error(err))
|
|
|
|
|
return err
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 创建默认管理员
|
|
|
|
|
admin := &model.User{
|
|
|
|
|
Username: defaultAdminUsername,
|
|
|
|
|
Email: defaultAdminEmail,
|
|
|
|
|
Password: string(hashedPassword),
|
|
|
|
|
Role: "admin",
|
|
|
|
|
Status: 1,
|
|
|
|
|
Points: 0,
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if err := db.Create(admin).Error; err != nil {
|
|
|
|
|
logger.Error("创建管理员用户失败", zap.Error(err))
|
|
|
|
|
return err
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
logger.Info("默认管理员用户创建成功",
|
|
|
|
|
zap.String("username", defaultAdminUsername),
|
|
|
|
|
zap.String("email", defaultAdminEmail),
|
|
|
|
|
)
|
|
|
|
|
logger.Warn("请立即登录并修改默认管理员密码!默认密码请查看源码中的 defaultAdminPassword 常量")
|
|
|
|
|
|
|
|
|
|
return nil
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// seedCasbinRules 初始化Casbin权限规则
|
|
|
|
|
func seedCasbinRules(db *gorm.DB, logger *zap.Logger) error {
|
|
|
|
|
for _, rule := range defaultCasbinRules {
|
|
|
|
|
// 检查规则是否已存在
|
|
|
|
|
var existing model.CasbinRule
|
|
|
|
|
query := db.Where("ptype = ? AND v0 = ? AND v1 = ? AND v2 = ?", rule.PType, rule.V0, rule.V1, rule.V2)
|
|
|
|
|
result := query.First(&existing)
|
|
|
|
|
if result.Error == gorm.ErrRecordNotFound {
|
|
|
|
|
if err := db.Create(&rule).Error; err != nil {
|
|
|
|
|
logger.Error("创建Casbin规则失败", zap.String("ptype", rule.PType), zap.Error(err))
|
|
|
|
|
return err
|
|
|
|
|
}
|
|
|
|
|
logger.Info("创建Casbin规则", zap.String("ptype", rule.PType), zap.String("v0", rule.V0), zap.String("v1", rule.V1))
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
return nil
|
|
|
|
|
}
|