124 lines
4.8 KiB
Go
124 lines
4.8 KiB
Go
package version
|
|
|
|
import (
|
|
"fmt"
|
|
"runtime"
|
|
|
|
"gorm.io/gorm"
|
|
"gorm.io/gorm/clause"
|
|
|
|
"git.ilapage.cn/ila/yovision/Sense/server/app/sense/credential"
|
|
deviceModels "git.ilapage.cn/ila/yovision/Sense/server/app/sense/device/models"
|
|
"git.ilapage.cn/ila/yovision/Sense/server/cmd/migrate/migration"
|
|
migrationModels "git.ilapage.cn/ila/yovision/Sense/server/cmd/migrate/migration/models"
|
|
common "git.ilapage.cn/ila/yovision/Sense/server/common/models"
|
|
)
|
|
|
|
type deviceCasbinRule 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 (deviceCasbinRule) TableName() string { return "casbin_rule" }
|
|
|
|
func init() {
|
|
_, fileName, _, _ := runtime.Caller(0)
|
|
migration.Migrate.SetVersion(migration.GetFilename(fileName), migrateSenseDeviceLedger)
|
|
}
|
|
|
|
func migrateSenseDeviceLedger(db *gorm.DB, version string) error {
|
|
return db.Transaction(func(tx *gorm.DB) error {
|
|
if err := tx.AutoMigrate(&deviceModels.Device{}, &credential.DeviceCredential{}, &deviceCasbinRule{}); err != nil {
|
|
return err
|
|
}
|
|
page, err := ensureDeviceMenu(tx, migrationModels.SysMenu{
|
|
MenuName: "SenseDeviceManage", Title: "设备管理", Icon: "monitor", Path: "/sense/devices",
|
|
MenuType: "C", Permission: "sense:device:list", ParentId: 0, Component: "/sense/device/index",
|
|
Sort: 5, Visible: "0", IsFrame: "1",
|
|
})
|
|
if err != nil {
|
|
return err
|
|
}
|
|
buttons := make([]migrationModels.SysMenu, 0, 4)
|
|
for index, definition := range []struct{ name, title, action, permission string }{
|
|
{"SenseDeviceAdd", "新增设备", "POST", "sense:device:add"},
|
|
{"SenseDeviceEdit", "编辑设备", "PUT", "sense:device:edit"},
|
|
{"SenseDeviceDisable", "停用设备", "PUT", "sense:device:disable"},
|
|
{"SenseDeviceCredential", "更新设备凭据", "PUT", "sense:device:credential"},
|
|
} {
|
|
button, err := ensureDeviceMenu(tx, migrationModels.SysMenu{
|
|
MenuName: definition.name, Title: definition.title, MenuType: "F", Action: definition.action,
|
|
Permission: definition.permission, ParentId: page.MenuId, Paths: fmt.Sprintf("/0/%d", page.MenuId),
|
|
Sort: index + 1, Visible: "1", IsFrame: "1",
|
|
})
|
|
if err != nil {
|
|
return err
|
|
}
|
|
buttons = append(buttons, button)
|
|
}
|
|
if err = attachDeviceRole(tx, "implementation_operator", append([]migrationModels.SysMenu{page}, buttons...)); err != nil {
|
|
return err
|
|
}
|
|
if err = attachDeviceRole(tx, "site_admin", append([]migrationModels.SysMenu{page}, buttons...)); err != nil {
|
|
return err
|
|
}
|
|
if err = attachDeviceRole(tx, "viewer", []migrationModels.SysMenu{page}); err != nil {
|
|
return err
|
|
}
|
|
readPolicies := [][2]string{{"/api/v1/devices", "GET"}, {"/api/v1/devices/:id", "GET"}}
|
|
writePolicies := [][2]string{{"/api/v1/devices", "POST"}, {"/api/v1/devices/:id", "PUT"}, {"/api/v1/devices/:id/disable", "PUT"}, {"/api/v1/devices/:id/credentials", "PUT"}}
|
|
for _, role := range []string{"implementation_operator", "site_admin", "viewer"} {
|
|
policies := append([][2]string{}, readPolicies...)
|
|
if role != "viewer" {
|
|
policies = append(policies, writePolicies...)
|
|
}
|
|
for _, policy := range policies {
|
|
rule := deviceCasbinRule{Ptype: "p", V0: role, 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 ensureDeviceMenu(tx *gorm.DB, desired migrationModels.SysMenu) (migrationModels.SysMenu, error) {
|
|
var menu migrationModels.SysMenu
|
|
err := tx.Where("menu_name = ?", desired.MenuName).First(&menu).Error
|
|
if err != nil && err != gorm.ErrRecordNotFound {
|
|
return menu, err
|
|
}
|
|
if err == gorm.ErrRecordNotFound {
|
|
menu = desired
|
|
if err = tx.Create(&menu).Error; err != nil {
|
|
return menu, err
|
|
}
|
|
}
|
|
paths := desired.Paths
|
|
if desired.ParentId == 0 {
|
|
paths = fmt.Sprintf("/0/%d", menu.MenuId)
|
|
}
|
|
err = tx.Model(&menu).Updates(map[string]any{
|
|
"title": desired.Title, "icon": desired.Icon, "path": desired.Path, "paths": paths,
|
|
"menu_type": desired.MenuType, "action": desired.Action, "permission": desired.Permission,
|
|
"parent_id": desired.ParentId, "component": desired.Component, "sort": desired.Sort,
|
|
"visible": desired.Visible, "is_frame": desired.IsFrame,
|
|
}).Error
|
|
return menu, err
|
|
}
|
|
|
|
func attachDeviceRole(tx *gorm.DB, roleKey string, menus []migrationModels.SysMenu) error {
|
|
var role migrationModels.SysRole
|
|
if err := tx.Where("role_key = ?", roleKey).First(&role).Error; err != nil {
|
|
return err
|
|
}
|
|
return tx.Model(&role).Association("SysMenu").Append(menus)
|
|
}
|