Files
web/server/handlers/permission.go
2026-03-17 01:00:11 +08:00

97 lines
2.3 KiB
Go
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
package handlers
import (
"context"
"net/http"
"time"
"go.mongodb.org/mongo-driver/v2/bson"
"go.mongodb.org/mongo-driver/v2/mongo"
"yh_web/server/config"
"yh_web/server/models"
"github.com/gin-gonic/gin"
)
// roleIDFromContext 从 context 安全取 role_idJWT 等可能解码为 float64
func roleIDFromContext(c *gin.Context) (int, bool) {
roleIDVal, ok := c.Get("role_id")
if !ok {
return 0, false
}
switch v := roleIDVal.(type) {
case int:
return v, true
case float64:
return int(v), true
default:
return 0, false
}
}
// getPermissionsByRoleID 从 role_permissions 读取某角色的权限9527 默认拥有全部
func getPermissionsByRoleID(ctx context.Context, roleID int) []string {
if roleID == models.RoleIDSuperAdmin {
return allPermissionKeys()
}
coll := config.GetDB(config.DBName).Collection("role_permissions")
var doc models.RolePermissionsDoc
err := coll.FindOne(ctx, bson.M{"role_id": roleID}).Decode(&doc)
if err != nil {
if err == mongo.ErrNoDocuments {
return nil
}
return nil
}
return doc.Permissions
}
func allPermissionKeys() []string {
keys := make([]string, 0, len(models.AllPermissions))
for _, p := range models.AllPermissions {
keys = append(keys, p.Key)
}
return keys
}
// RequirePermission 要求当前用户拥有指定权限(在 AuthRequired 之后使用)
func RequirePermission(permission string) gin.HandlerFunc {
return func(c *gin.Context) {
roleID, ok := roleIDFromContext(c)
if !ok {
c.JSON(http.StatusForbidden, gin.H{"error": "无权限"})
c.Abort()
return
}
if roleID == models.RoleIDSuperAdmin {
c.Next()
return
}
ctx, cancel := context.WithTimeout(context.Background(), 3*time.Second)
defer cancel()
perms := getPermissionsByRoleID(ctx, roleID)
for _, p := range perms {
if p == permission {
c.Next()
return
}
}
c.JSON(http.StatusForbidden, gin.H{"error": "无此操作权限"})
c.Abort()
}
}
// GetMyPermissions 返回当前用户权限列表(供前端菜单、按钮显隐)
func GetMyPermissions(c *gin.Context) {
roleID, ok := roleIDFromContext(c)
if !ok {
c.JSON(http.StatusOK, gin.H{"permissions": []string{}})
return
}
ctx, cancel := context.WithTimeout(context.Background(), 3*time.Second)
defer cancel()
perms := getPermissionsByRoleID(ctx, roleID)
c.JSON(http.StatusOK, gin.H{"permissions": perms})
}