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