refactor(bookmark): 重构书签服务入口文件并整合用户权限功能

将 bookmark.go 重命名为 main.go,并调整包引用路径。将 bookmarks 和 user_np
两个模块的处理逻辑合并到同一个服务中,统一注册路由。同时更新了相关 API
的引用路径,确保生成代码与内部实现正确绑定。

此外,移除了独立的 user_np 服务入口文件,其功能已整合至 bookmark 服务中。

配置文件中调整了 user_np 和 vfs 服务的端口及部分接口定义,完善了用户
相关操作的路径参数和请求体结构。
This commit is contained in:
zzy
2025-09-25 09:50:35 +08:00
parent 1e81e603de
commit 24f238f377
23 changed files with 1173 additions and 601 deletions

89
internal/vfs/vfs_auth.go Normal file
View File

@ -0,0 +1,89 @@
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()
}
}