92 lines
2.5 KiB
Go
92 lines
2.5 KiB
Go
package platform
|
|
|
|
import (
|
|
"strings"
|
|
|
|
"git.apinb.com/bsm-sdk/core/errcode"
|
|
"git.apinb.com/bsm-sdk/core/infra"
|
|
"git.apinb.com/bsm-sdk/core/middleware"
|
|
"git.apinb.com/heqiapp/platforms/backend/api/internal/impl"
|
|
"git.apinb.com/heqiapp/platforms/backend/api/internal/models"
|
|
"github.com/gin-gonic/gin"
|
|
)
|
|
|
|
const platformMenusContextKey = "platform_authorized_menus"
|
|
|
|
func loadPlatformMenus(roleCode string) ([]models.PlatformMenu, error) {
|
|
var menus []models.PlatformMenu
|
|
if roleCode == "root" {
|
|
err := impl.DBService.Order("sort_no asc, id asc").Find(&menus).Error
|
|
return menus, err
|
|
}
|
|
|
|
var role models.PlatformRole
|
|
if err := impl.DBService.Where("role_code = ? AND status = ?", roleCode, "enabled").First(&role).Error; err != nil {
|
|
return nil, err
|
|
}
|
|
err := impl.DBService.
|
|
Select("platform_menu.*").
|
|
Joins("JOIN platform_role_menu_relation ON platform_role_menu_relation.platform_menu_id = platform_menu.id").
|
|
Where("platform_role_menu_relation.platform_role_id = ? AND platform_menu.status = ?", role.ID, "enabled").
|
|
Order("sort_no asc, id asc").
|
|
Find(&menus).Error
|
|
return menus, err
|
|
}
|
|
|
|
func platformMenuAllowsPath(menus []models.PlatformMenu, requestPath string) bool {
|
|
marker := "/platform/v1/"
|
|
index := strings.Index(requestPath, marker)
|
|
if index < 0 {
|
|
return false
|
|
}
|
|
relative := strings.Trim(requestPath[index+len(marker):], "/")
|
|
domain := strings.Split(relative, "/")[0]
|
|
for _, menu := range menus {
|
|
if menu.MenuCode == domain {
|
|
return true
|
|
}
|
|
menuPath := strings.Trim(menu.Path, "/")
|
|
if menuPath != "" && strings.Split(menuPath, "/")[0] == domain {
|
|
return true
|
|
}
|
|
}
|
|
return false
|
|
}
|
|
|
|
// RequirePlatformMenuAccess enforces role-menu authorization after JWT authentication.
|
|
func RequirePlatformMenuAccess() gin.HandlerFunc {
|
|
return func(ctx *gin.Context) {
|
|
if strings.Contains(ctx.Request.URL.Path, "/platform/v1/auth/") {
|
|
ctx.Next()
|
|
return
|
|
}
|
|
claims, err := middleware.ParseAuth(ctx)
|
|
if err != nil {
|
|
infra.Response.Error(ctx, err)
|
|
ctx.Abort()
|
|
return
|
|
}
|
|
if claims.Role == "root" {
|
|
ctx.Next()
|
|
return
|
|
}
|
|
menus, err := loadPlatformMenus(claims.Role)
|
|
if err != nil || !platformMenuAllowsPath(menus, ctx.Request.URL.Path) {
|
|
infra.Response.Error(ctx, errcode.ErrPermissionDenied)
|
|
ctx.Abort()
|
|
return
|
|
}
|
|
ctx.Set(platformMenusContextKey, menus)
|
|
ctx.Next()
|
|
}
|
|
}
|
|
|
|
func requirePlatformRoot(ctx *gin.Context) bool {
|
|
claims, err := middleware.ParseAuth(ctx)
|
|
if err == nil && claims.Role == "root" {
|
|
return true
|
|
}
|
|
infra.Response.Error(ctx, errcode.ErrPermissionDenied)
|
|
return false
|
|
}
|