Files
yovision/Sense/server/cmd/migrate/migration/version/2026081412000_identity.go

125 lines
4.7 KiB
Go

package version
import (
"runtime"
"gorm.io/gorm"
"gorm.io/gorm/clause"
"git.ilapage.cn/ila/yovision/Sense/server/cmd/migrate/migration"
"git.ilapage.cn/ila/yovision/Sense/server/cmd/migrate/migration/models"
common "git.ilapage.cn/ila/yovision/Sense/server/common/models"
)
type identityRoleDefinition struct {
name string
key string
sort int
menuIDs []int
policies [][2]string
}
type identityCasbinRule struct {
ID uint `gorm:"primaryKey;autoIncrement"`
Ptype string `gorm:"size:512;uniqueIndex:unique_index"`
V0 string `gorm:"size:512;uniqueIndex:unique_index"`
V1 string `gorm:"size:512;uniqueIndex:unique_index"`
V2 string `gorm:"size:512;uniqueIndex:unique_index"`
V3 string `gorm:"size:512;uniqueIndex:unique_index"`
V4 string `gorm:"size:512;uniqueIndex:unique_index"`
V5 string `gorm:"size:512;uniqueIndex:unique_index"`
}
func (identityCasbinRule) TableName() string { return "casbin_rule" }
func init() {
_, fileName, _, _ := runtime.Caller(0)
migration.Migrate.SetVersion(migration.GetFilename(fileName), migrateSenseIdentityBaseline)
}
func migrateSenseIdentityBaseline(db *gorm.DB, version string) error {
return db.Transaction(func(tx *gorm.DB) error {
if err := tx.AutoMigrate(&identityCasbinRule{}); err != nil {
return err
}
resetPasswordMenu, err := ensureIdentityButton(tx, "SenseResetPassword", "重置用户密码", "admin:sysUser:resetPassword", 154)
if err != nil {
return err
}
changeStatusMenu, err := ensureIdentityButton(tx, "SenseChangeUserStatus", "启停用户", "admin:sysUser:edit", 155)
if err != nil {
return err
}
definitions := []identityRoleDefinition{
{name: "系统管理员", key: "admin", sort: 1},
{
name: "实施运维", key: "implementation_operator", sort: 10,
menuIDs: []int{2, 211, 212, 216, 248, 250},
policies: [][2]string{{"/api/v1/sys-login-log", "GET"}, {"/api/v1/sys-login-log/:id", "GET"}, {"/api/v1/sys-opera-log", "GET"}, {"/api/v1/sys-opera-log/:id", "GET"}, {"/api/v1/dict-data/option-select", "GET"}},
},
{
name: "站点管理员", key: "site_admin", sort: 20,
menuIDs: []int{2, 3, 43, 44, 45, resetPasswordMenu.MenuId, changeStatusMenu.MenuId},
policies: [][2]string{{"/api/v1/sys-user", "GET"}, {"/api/v1/sys-user/:id", "GET"}, {"/api/v1/sys-user", "POST"}, {"/api/v1/sys-user", "PUT"}, {"/api/v1/user/pwd/reset", "PUT"}, {"/api/v1/user/status", "PUT"}, {"/api/v1/deptTree", "GET"}, {"/api/v1/post", "GET"}, {"/api/v1/role", "GET"}, {"/api/v1/dict-data/option-select", "GET"}},
},
{name: "只读用户", key: "viewer", sort: 30},
}
for _, definition := range definitions {
role, err := ensureIdentityRole(tx, definition)
if err != nil {
return err
}
if err = attachIdentityMenus(tx, &role, definition.menuIDs); err != nil {
return err
}
for _, policy := range definition.policies {
rule := identityCasbinRule{Ptype: "p", V0: definition.key, V1: policy[0], V2: policy[1]}
if err = tx.Clauses(clause.OnConflict{DoNothing: true}).Create(&rule).Error; err != nil {
return err
}
}
}
return tx.Create(&common.Migration{Version: version}).Error
})
}
func ensureIdentityRole(tx *gorm.DB, definition identityRoleDefinition) (models.SysRole, error) {
var role models.SysRole
err := tx.Where("role_key = ?", definition.key).First(&role).Error
if err != nil && err != gorm.ErrRecordNotFound {
return role, err
}
if err == gorm.ErrRecordNotFound {
role = models.SysRole{RoleName: definition.name, RoleKey: definition.key, RoleSort: definition.sort, Status: "2", Admin: definition.key == "admin", DataScope: "1", Remark: "Sense 内置最小权限角色"}
return role, tx.Create(&role).Error
}
err = tx.Model(&role).Updates(map[string]interface{}{"role_name": definition.name, "status": "2", "role_sort": definition.sort, "admin": definition.key == "admin"}).Error
return role, err
}
func ensureIdentityButton(tx *gorm.DB, name, title, permission string, apiID int) (models.SysMenu, error) {
menu := models.SysMenu{MenuName: name, Title: title, MenuType: "F", Action: "PUT", Permission: permission, ParentId: 3, Paths: "/0/2/3", Sort: 25, Visible: "1", IsFrame: "1"}
if err := tx.Where("menu_name = ?", name).FirstOrCreate(&menu).Error; err != nil {
return menu, err
}
var api models.SysApi
if err := tx.First(&api, apiID).Error; err != nil {
return menu, err
}
return menu, tx.Model(&menu).Association("SysApi").Append(&api)
}
func attachIdentityMenus(tx *gorm.DB, role *models.SysRole, menuIDs []int) error {
if len(menuIDs) == 0 {
return nil
}
var menus []models.SysMenu
if err := tx.Where("menu_id IN ?", menuIDs).Find(&menus).Error; err != nil {
return err
}
return tx.Model(role).Association("SysMenu").Append(&menus)
}