package middleware import ( "context" "kra/internal/conf" "kra/internal/modules/system/biz" "kra/internal/modules/system/service" "kra/internal/modules/system/transport/httpx" "github.com/gin-gonic/gin" ) type accessController interface { Authorize(context.Context, uint, string, string) (bool, error) ContextWithDataScope(context.Context, uint, uint) (context.Context, error) } func AccessControl(runtime *conf.Runtime, access accessController) gin.HandlerFunc { return func(c *gin.Context) { claims := Claims(c) if claims == nil { httpx.NoAuth(c, "未登录或非法访问") return } path := c.Request.URL.Path policyPath := path if config := runtime.Admin(); config != nil { policyPath = service.NormalizeRoutePath(policyPath, config.RouterPrefix) } allowed, err := access.Authorize(c.Request.Context(), claims.AuthorityID, policyPath, c.Request.Method) if err != nil || !allowed { httpx.Write(c, httpx.CodeError, gin.H{}, "权限不足") c.Abort() return } requestContext, err := access.ContextWithDataScope(c.Request.Context(), claims.AuthorityID, claims.ID) if err != nil { httpx.Write(c, httpx.CodeError, gin.H{}, "数据权限解析失败") c.Abort() return } if scope, ok := biz.DataScopeFromContext(requestContext); ok { requestID, _ := c.Get("request_id") scope.RequestID, _ = requestID.(string) scope.Method, scope.Path = c.Request.Method, path requestContext = biz.NewDataScopeContext(requestContext, scope) } requestContext = biz.NewActorContext(requestContext, biz.Actor{UserID: claims.ID, AuthorityID: claims.AuthorityID}) c.Request = c.Request.WithContext(requestContext) c.Next() } }