229 lines
6.4 KiB
Go
229 lines
6.4 KiB
Go
package user
|
|
|
|
import (
|
|
"bsm/full/module/base/mgt/internal/impl"
|
|
"bsm/full/module/base/mgt/internal/libs"
|
|
mgtmw "bsm/full/module/base/mgt/internal/middleware"
|
|
"bsm/full/module/base/mgt/internal/models"
|
|
"bsm/full/module/base/mgt/internal/types"
|
|
|
|
"git.apinb.com/bsm-sdk/core/errcode"
|
|
"git.apinb.com/bsm-sdk/core/infra"
|
|
"git.apinb.com/bsm-sdk/core/middleware"
|
|
"github.com/gin-gonic/gin"
|
|
"gorm.io/gorm"
|
|
)
|
|
|
|
const permissionPreloadSelect = "id,identity,title,title_en,sort_key,parent_id,menu_path,menu_icon,code,component,is_web_page,is_new_tab,is_full,hide_menu,web_url,app_id"
|
|
|
|
func permissionOrder(db *gorm.DB) *gorm.DB { return db.Order("sort_key asc") }
|
|
|
|
func pmnPreloadWithWorkspace(workspace string) func(*gorm.DB) *gorm.DB {
|
|
return func(db *gorm.DB) *gorm.DB {
|
|
db = db.Select(permissionPreloadSelect)
|
|
if workspace != "" {
|
|
db = db.Where("app_id = (SELECT id FROM mgt_application WHERE workspace = ?)", workspace)
|
|
}
|
|
return permissionOrder(db)
|
|
}
|
|
}
|
|
|
|
func mergeEffectivePermissions(u *models.MgtUser) []models.MgtPermission {
|
|
seen := make(map[uint]struct{})
|
|
out := make([]models.MgtPermission, 0)
|
|
|
|
add := func(list []models.MgtPermission) {
|
|
for _, p := range list {
|
|
if p.ID == 0 {
|
|
continue
|
|
}
|
|
if _, ok := seen[p.ID]; ok {
|
|
continue
|
|
}
|
|
seen[p.ID] = struct{}{}
|
|
out = append(out, p)
|
|
}
|
|
}
|
|
|
|
add(u.Permissions)
|
|
for i := range u.Roles {
|
|
add(u.Roles[i].Permissions)
|
|
}
|
|
for i := range u.Departments {
|
|
add(u.Departments[i].Permissions)
|
|
for j := range u.Departments[i].Roles {
|
|
add(u.Departments[i].Roles[j].Permissions)
|
|
}
|
|
}
|
|
return out
|
|
}
|
|
|
|
func PermissionsFetch(c *gin.Context) {
|
|
var (
|
|
request = types.FetchBase{}
|
|
data = make([]models.MgtUser, 0)
|
|
db = impl.DBService.Model(&models.MgtUser{})
|
|
)
|
|
if err := c.ShouldBindJSON(&request); err != nil {
|
|
infra.Response.Error(c, errcode.ErrJsonUnmarshal)
|
|
return
|
|
}
|
|
if err := libs.ValidateStruct(&request); err != nil {
|
|
infra.Response.Error(c, errcode.ErrInvalidArgument)
|
|
return
|
|
}
|
|
auth, err := middleware.ParseAuth(c)
|
|
if err != nil {
|
|
infra.Response.Error(c, errcode.ErrTokenAuthParseFail)
|
|
return
|
|
}
|
|
if request.ID == 0 {
|
|
request.ID = auth.ID
|
|
}
|
|
if !mgtmw.EnsureSelfOrAdmin(c, request.ID) {
|
|
return
|
|
}
|
|
|
|
ws := request.Workspace
|
|
db = db.Where("id = ?", request.ID).Select("id", "identity", "name").
|
|
Preload("Permissions", pmnPreloadWithWorkspace(ws)).
|
|
Preload("Roles", func(db *gorm.DB) *gorm.DB {
|
|
return db.Select("id", "identity", "name").Preload("Permissions", pmnPreloadWithWorkspace(ws))
|
|
}).
|
|
Preload("Departments", func(db *gorm.DB) *gorm.DB {
|
|
return db.Select("id", "identity", "name").
|
|
Preload("Permissions", pmnPreloadWithWorkspace(ws)).
|
|
Preload("Roles", func(db *gorm.DB) *gorm.DB {
|
|
return db.Select("id", "identity", "name").Preload("Permissions", pmnPreloadWithWorkspace(ws))
|
|
})
|
|
})
|
|
|
|
if err := db.Find(&data).Error; err != nil {
|
|
infra.Response.Error(c, errcode.ErrDB)
|
|
return
|
|
}
|
|
|
|
if len(data) == 0 {
|
|
infra.Response.Success(c, data)
|
|
return
|
|
}
|
|
merged := mergeEffectivePermissions(&data[0])
|
|
data[0].Permissions = merged
|
|
infra.Response.Success(c, data)
|
|
}
|
|
|
|
func PermissionsFetchTree(c *gin.Context) {
|
|
var (
|
|
request = types.FetchBase{}
|
|
data = make([]models.MgtUser, 0)
|
|
)
|
|
if err := c.ShouldBindJSON(&request); err != nil {
|
|
infra.Response.Error(c, errcode.ErrJsonUnmarshal)
|
|
return
|
|
}
|
|
if err := libs.ValidateStruct(&request); err != nil {
|
|
infra.Response.Error(c, errcode.ErrInvalidArgument)
|
|
return
|
|
}
|
|
auth, err := middleware.ParseAuth(c)
|
|
if err != nil {
|
|
infra.Response.Error(c, errcode.ErrTokenAuthParseFail)
|
|
return
|
|
}
|
|
if request.ID == 0 {
|
|
request.ID = auth.ID
|
|
}
|
|
if !mgtmw.EnsureSelfOrAdmin(c, request.ID) {
|
|
return
|
|
}
|
|
|
|
db := impl.DBService.Model(&models.MgtUser{}).Where("id = ?", request.ID).
|
|
Select("id", "identity", "name").
|
|
Preload("Permissions", func(db *gorm.DB) *gorm.DB {
|
|
return db.Select(permissionPreloadSelect).Order("sort_key asc")
|
|
}).
|
|
Preload("Roles", func(db *gorm.DB) *gorm.DB {
|
|
return db.Select("id", "identity", "name").Preload("Permissions", func(db *gorm.DB) *gorm.DB {
|
|
return db.Select(permissionPreloadSelect).Order("sort_key asc")
|
|
})
|
|
}).
|
|
Preload("Departments", func(db *gorm.DB) *gorm.DB {
|
|
return db.Select("id", "identity", "name").
|
|
Preload("Permissions", func(db *gorm.DB) *gorm.DB {
|
|
return db.Select(permissionPreloadSelect).Order("sort_key asc")
|
|
}).
|
|
Preload("Roles", func(db *gorm.DB) *gorm.DB {
|
|
return db.Select("id", "identity", "name").Preload("Permissions", func(db *gorm.DB) *gorm.DB {
|
|
return db.Select(permissionPreloadSelect).Order("sort_key asc")
|
|
})
|
|
})
|
|
})
|
|
if err := db.Find(&data).Error; err != nil {
|
|
infra.Response.Error(c, errcode.ErrDB)
|
|
return
|
|
}
|
|
if len(data) == 0 {
|
|
infra.Response.Success(c, data)
|
|
return
|
|
}
|
|
|
|
merged := mergeEffectivePermissions(&data[0])
|
|
pmnIdsByApp := make(map[uint][]uint)
|
|
for _, p := range merged {
|
|
if p.Appid == 0 {
|
|
continue
|
|
}
|
|
pmnIdsByApp[p.Appid] = append(pmnIdsByApp[p.Appid], p.ID)
|
|
}
|
|
|
|
appDb := impl.DBService.Model(&models.MgtUser{}).Where("id = ?", request.ID).
|
|
Select("id", "identity", "name")
|
|
appDb = appDb.Preload("Application", func(db *gorm.DB) *gorm.DB {
|
|
db = db.Select("id", "identity", "title", "workspace")
|
|
if request.Workspace != "" {
|
|
db = db.Where("workspace = ?", request.Workspace)
|
|
}
|
|
return db
|
|
})
|
|
var userWithApp []models.MgtUser
|
|
if err := appDb.Find(&userWithApp).Error; err != nil || len(userWithApp) == 0 {
|
|
infra.Response.Success(c, data)
|
|
return
|
|
}
|
|
|
|
apps := userWithApp[0].Application
|
|
if len(apps) == 0 {
|
|
data[0].Application = nil
|
|
infra.Response.Success(c, data)
|
|
return
|
|
}
|
|
|
|
treeSelect := "id,identity,title,title_en,sort_key,parent_id,menu_path,menu_icon,code,component,is_web_page,is_new_tab,web_url,app_id"
|
|
for i := range apps {
|
|
ids := pmnIdsByApp[apps[i].ID]
|
|
if len(ids) == 0 {
|
|
apps[i].UsersPmn = nil
|
|
apps[i].RolesPmn = nil
|
|
continue
|
|
}
|
|
var tree []models.MgtPermission
|
|
err := impl.DBService.Model(&models.MgtPermission{}).
|
|
Select(treeSelect).
|
|
Where("app_id = ? AND parent_id = 0 AND id IN ?", apps[i].ID, ids).
|
|
Order("sort_key asc").
|
|
Preload("Children", func(db *gorm.DB) *gorm.DB {
|
|
return db.Select(treeSelect).Where("id IN ?", ids).Order("sort_key asc")
|
|
}).
|
|
Find(&tree).Error
|
|
if err != nil {
|
|
apps[i].UsersPmn = nil
|
|
apps[i].RolesPmn = nil
|
|
continue
|
|
}
|
|
apps[i].UsersPmn = tree
|
|
}
|
|
|
|
data[0].Application = apps
|
|
infra.Response.Success(c, data)
|
|
}
|