package vfs import ( _ "embed" "net/http" "strings" api "git.zzyxyz.com/zzy/zzyxyz_go_api/gen/vfs" "git.zzyxyz.com/zzy/zzyxyz_go_api/internal/vfs/models" "github.com/gin-gonic/gin" ) //go:embed vfs_model.conf var CasbinModel string func NewVfsPermission() (*api.GinServerOptions, error) { return &api.GinServerOptions{ Middlewares: []api.MiddlewareFunc{VfsMiddleware()}, }, nil } func (v *VfsImpl) CheckPermission(token, path, action string) (bool, error) { // 根据 token 获取用户信息 user, err := v.vfs.GetUserByToken(token) if err != nil { // 匿名用户 user = &models.VfsUser{Name: "", Token: ""} } // 特殊处理:admin 用户拥有所有权限 if token == v.config.AdminToken && len(token) != 0 { // admin 用户拥有所有权限 return true, nil } // 允许任何人读取 public 目录 if strings.HasPrefix(path, "/public") && action == "GET" { return true, nil } // 如果是普通用户访问自己的主目录,则允许 if user.Name != "" && strings.HasPrefix(path, "/home/"+user.Name) { return true, nil } // 构造 Casbin 请求 // 对于普通用户,需要将策略中的 {{username}} 替换为实际用户名 obj := path sub := user.Name // 使用 Casbin 检查权限 allowed, err := v.enfocer.Enforce(sub, obj, action) if err != nil { return false, err } return allowed, nil } func (v *VfsImpl) CheckPermissionMiddleware(c *gin.Context, path string) bool { token := c.GetHeader("X-VFS-Token") allowed, err := v.CheckPermission(token, path, c.Request.Method) // log.Println("CheckPermission:", allowed, err) if err != nil { c.JSON(http.StatusInternalServerError, api.Error{ Errtype: "PermissionCheckError", Message: "Failed to check permission: " + err.Error(), }) return false } if !allowed { c.JSON(http.StatusForbidden, api.Error{ Errtype: "AccessDenied", Message: "Access denied", }) return false } return true } func VfsMiddleware() api.MiddlewareFunc { return func(c *gin.Context) { // 检查当前请求是否需要认证 if _, exists := c.Get(api.ApiKeyAuthScopes); exists { // 提取 API Key apiKey := c.GetHeader("X-VFS-Token") c.Set(api.ApiKeyAuthScopes, apiKey) } c.Next() } }