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) }