refactor(vfs): 重构VFS模块,拆分数据访问逻辑与路径解析逻辑
将原先的 `vfs.go` 文件中的功能进行拆分,创建了独立的 DAO 层文件 `vfs_dao.go` 和路径处理文件 `vfs_path.go`,以提升代码结构清晰度和可维护性。 - 将数据库操作相关方法迁移至 `VfsDAO` 结构体中 - 新增 `vfs_dao.go` 文件用于管理底层数据访问对象 - 新增 `vfs_path.go` 文件专门处理路径解析逻辑 - 移除了原 `vfs.go` 中的数据库初始化、用户及节点操作等冗余代码
This commit is contained in:
396
internal/vfs/services/vfs_core.go
Normal file
396
internal/vfs/services/vfs_core.go
Normal file
@ -0,0 +1,396 @@
|
||||
package vfs_service
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
"git.zzyxyz.com/zzy/zzyxyz_go_api/internal/vfs/models"
|
||||
)
|
||||
|
||||
type VfsCoreService struct {
|
||||
vfs *models.VfsDAO
|
||||
}
|
||||
|
||||
type VfsCallback func(this any, node *models.VfsNode, input []byte) ([]byte, error)
|
||||
|
||||
func NewVfsCoreService(vfs *models.VfsDAO) *VfsCoreService {
|
||||
return &VfsCoreService{vfs: vfs}
|
||||
}
|
||||
|
||||
type CreateVFSNodeResult struct {
|
||||
Node *models.VfsNode
|
||||
Content []byte // 回调处理后的结果
|
||||
}
|
||||
|
||||
func (s *VfsCoreService) CreateVFSNode(path string, content []byte, callback VfsCallback, thisArg any) (*CreateVFSNodeResult, *VFSError) {
|
||||
// 解析路径组件
|
||||
parentPath, nodeName, nodeType, err := models.ParsePathComponents(path)
|
||||
if err != nil {
|
||||
return nil, &VFSError{
|
||||
Type: ErrorTypeInvalidPath,
|
||||
Error: err,
|
||||
}
|
||||
}
|
||||
|
||||
parentNode, err := s.vfs.GetNodeByPath(parentPath)
|
||||
if err != nil {
|
||||
return nil, &VFSError{
|
||||
Type: ErrorTypePathNotFound,
|
||||
Error: err,
|
||||
}
|
||||
}
|
||||
|
||||
node := models.VfsNode{
|
||||
Name: nodeName,
|
||||
ParentID: parentNode.ID,
|
||||
Type: nodeType,
|
||||
}
|
||||
|
||||
if err := s.vfs.CreateNode(node); err != nil {
|
||||
return nil, &VFSError{
|
||||
Type: ErrorTypeNodeCreationFailed,
|
||||
Error: err,
|
||||
}
|
||||
}
|
||||
|
||||
// 获取创建后的完整节点信息
|
||||
createdNode, err := s.vfs.GetNodeByParentIDAndName(parentNode.ID, nodeName)
|
||||
if err != nil {
|
||||
// 回滚
|
||||
s.vfs.DeleteNode(node.ID)
|
||||
return nil, &VFSError{
|
||||
Type: ErrorTypeNodeCreationFailed,
|
||||
Error: err,
|
||||
}
|
||||
}
|
||||
|
||||
// 执行回调处理
|
||||
var resultContent []byte
|
||||
if callback != nil && createdNode.Type == models.VfsNodeTypeService {
|
||||
ret, err := callback(thisArg, createdNode, content)
|
||||
if err != nil {
|
||||
// 回滚操作
|
||||
s.vfs.DeleteNode(createdNode.ID)
|
||||
return nil, &VFSError{
|
||||
Type: ErrorTypeServiceProxyFailed,
|
||||
Error: err,
|
||||
}
|
||||
}
|
||||
resultContent = ret
|
||||
}
|
||||
|
||||
return &CreateVFSNodeResult{
|
||||
Node: createdNode,
|
||||
Content: resultContent,
|
||||
}, nil
|
||||
}
|
||||
|
||||
func (s *VfsCoreService) DeleteVFSNodeRecursively(path string, callback VfsCallback, thisArg any) (*models.VfsNode, *VFSError) {
|
||||
// 获取节点
|
||||
node, err := s.vfs.GetNodeByPath(path)
|
||||
if err != nil {
|
||||
return nil, &VFSError{
|
||||
Type: ErrorTypeNodeNotFound,
|
||||
Error: err,
|
||||
}
|
||||
}
|
||||
|
||||
// 递归删除节点
|
||||
if err := s.deleteNodeRecursively(node, callback, thisArg); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return node, nil
|
||||
}
|
||||
|
||||
// deleteNodeRecursively 递归删除节点及其所有子节点
|
||||
func (s *VfsCoreService) deleteNodeRecursively(node *models.VfsNode, callback VfsCallback, thisArg any) *VFSError {
|
||||
// 如果是目录,先递归删除所有子节点
|
||||
if node.Type == models.VfsNodeTypeDirectory {
|
||||
// 获取所有子节点
|
||||
children, err := s.vfs.GetChildren(node.ID)
|
||||
if err != nil {
|
||||
return &VFSError{
|
||||
Type: ErrorTypeInternal,
|
||||
Error: fmt.Errorf("failed to get directory children: %v", err),
|
||||
}
|
||||
}
|
||||
|
||||
// 递归删除每个子节点
|
||||
for _, childEntry := range children {
|
||||
// 根据子条目获取完整节点信息
|
||||
childNode, err := s.vfs.GetNodeByParentIDAndName(node.ID, childEntry.Name)
|
||||
if err != nil {
|
||||
return &VFSError{
|
||||
Type: ErrorTypeNodeNotFound,
|
||||
Error: fmt.Errorf("failed to get child node %s: %v", childEntry.Name, err),
|
||||
}
|
||||
}
|
||||
|
||||
// 递归删除子节点
|
||||
if err := s.deleteNodeRecursively(childNode, callback, thisArg); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
} else if node.Type == models.VfsNodeTypeService {
|
||||
// 对于服务节点,执行回调
|
||||
if callback != nil {
|
||||
_, err := callback(thisArg, node, nil)
|
||||
if err != nil {
|
||||
return &VFSError{
|
||||
Type: ErrorTypeServiceProxyFailed,
|
||||
Error: fmt.Errorf("failed to execute callback for service %s: %v", node.Name, err),
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 删除当前节点
|
||||
if err := s.vfs.DeleteNode(node.ID); err != nil {
|
||||
return &VFSError{
|
||||
Type: ErrorTypeNodeDeletionFailed,
|
||||
Error: fmt.Errorf("failed to delete node %s: %v", node.Name, err),
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (s *VfsCoreService) DeleteVFSNode(path string, callback VfsCallback, thisArg any) (*models.VfsNode, *VFSError) {
|
||||
// 获取节点
|
||||
node, err := s.vfs.GetNodeByPath(path)
|
||||
if err != nil {
|
||||
return nil, &VFSError{
|
||||
Type: ErrorTypeNodeNotFound,
|
||||
Error: err,
|
||||
}
|
||||
}
|
||||
|
||||
// 根据节点类型进行不同处理
|
||||
switch node.Type {
|
||||
case models.VfsNodeTypeService:
|
||||
if callback != nil {
|
||||
_, err := callback(thisArg, node, nil)
|
||||
if err != nil {
|
||||
return nil, &VFSError{
|
||||
Type: ErrorTypeServiceProxyFailed,
|
||||
Error: err,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
case models.VfsNodeTypeDirectory:
|
||||
// 检查目录是否为空
|
||||
children, err := s.vfs.GetChildren(node.ID)
|
||||
if err != nil {
|
||||
return nil, &VFSError{
|
||||
Type: ErrorTypeInternal,
|
||||
Error: fmt.Errorf("failed to get directory children: %v", err),
|
||||
}
|
||||
}
|
||||
|
||||
if len(children) != 0 {
|
||||
return nil, &VFSError{
|
||||
Type: ErrorTypeConflict,
|
||||
Error: fmt.Errorf("directory is not empty"),
|
||||
}
|
||||
}
|
||||
default:
|
||||
return nil, &VFSError{
|
||||
Type: ErrorTypeInvalidArgument,
|
||||
Error: fmt.Errorf("node type not supported for deletion"),
|
||||
}
|
||||
}
|
||||
|
||||
// 执行实际的删除操作
|
||||
if err := s.vfs.DeleteNode(node.ID); err != nil {
|
||||
return nil, &VFSError{
|
||||
Type: ErrorTypeNodeDeletionFailed,
|
||||
Error: fmt.Errorf("failed to delete node: %v", err),
|
||||
}
|
||||
}
|
||||
|
||||
// 成功删除返回204状态
|
||||
return node, nil
|
||||
}
|
||||
|
||||
// GetVFSNodeResult 获取节点的返回结果
|
||||
type GetVFSNodeResult struct {
|
||||
Node *models.VfsNode
|
||||
Entries []models.VfsDirEntry
|
||||
Content []byte
|
||||
}
|
||||
|
||||
// GetVFSNode 获取VFS节点
|
||||
func (s *VfsCoreService) GetVFSNode(path string, callback VfsCallback, thisArg any) (*GetVFSNodeResult, *VFSError) {
|
||||
// 获取节点
|
||||
node, err := s.vfs.GetNodeByPath(path)
|
||||
if err != nil {
|
||||
return nil, &VFSError{
|
||||
Type: ErrorTypeNodeNotFound,
|
||||
Error: err,
|
||||
}
|
||||
}
|
||||
|
||||
// 根据节点类型进行不同处理
|
||||
switch node.Type {
|
||||
case models.VfsNodeTypeDirectory:
|
||||
// 处理目录类型
|
||||
entries, err := s.vfs.GetChildren(node.ID)
|
||||
if err != nil {
|
||||
return nil, &VFSError{
|
||||
Type: ErrorTypeInternal,
|
||||
Error: err,
|
||||
}
|
||||
}
|
||||
|
||||
return &GetVFSNodeResult{
|
||||
Node: node,
|
||||
Entries: entries,
|
||||
}, nil
|
||||
|
||||
case models.VfsNodeTypeService:
|
||||
// 处理服务类型
|
||||
var resultContent []byte
|
||||
if callback != nil {
|
||||
ret, err := callback(thisArg, node, nil)
|
||||
if err != nil {
|
||||
return nil, &VFSError{
|
||||
Type: ErrorTypeServiceProxyFailed,
|
||||
Error: err,
|
||||
}
|
||||
}
|
||||
resultContent = ret
|
||||
}
|
||||
|
||||
return &GetVFSNodeResult{
|
||||
Node: node,
|
||||
Content: resultContent,
|
||||
}, nil
|
||||
|
||||
default:
|
||||
return &GetVFSNodeResult{
|
||||
Node: node,
|
||||
}, nil
|
||||
}
|
||||
}
|
||||
|
||||
// UpdateOperation 更新操作类型
|
||||
type UpdateOperation int
|
||||
|
||||
const (
|
||||
UpdateOperationRename UpdateOperation = iota
|
||||
UpdateOperationChange
|
||||
UpdateOperationMove
|
||||
UpdateOperationCopy
|
||||
)
|
||||
|
||||
// UpdateVFSNode 更新VFS节点
|
||||
func (s *VfsCoreService) UpdateVFSNode(path string, operation UpdateOperation, data []byte, callback VfsCallback, thisArg any) (*models.VfsNode, *VFSError) {
|
||||
// 获取节点
|
||||
node, err := s.vfs.GetNodeByPath(path)
|
||||
if err != nil {
|
||||
return nil, &VFSError{
|
||||
Type: ErrorTypeNodeNotFound,
|
||||
Error: err,
|
||||
}
|
||||
}
|
||||
|
||||
// 根据操作类型进行不同处理
|
||||
switch operation {
|
||||
case UpdateOperationRename:
|
||||
// TODO:
|
||||
// if err := s.vfs.CheckNameValid(string(data)); err != nil {
|
||||
// return nil, &VFSError{
|
||||
// Type: ErrorTypeBadRequest,
|
||||
// Error: err,
|
||||
// }
|
||||
// }
|
||||
// FIXME: 检查新名称是否合法
|
||||
// 对于服务类型节点,可能需要保留特定后缀
|
||||
// 更新节点名称
|
||||
node.Name = string(data)
|
||||
if err := s.vfs.UpdateNode(node); err != nil {
|
||||
return nil, &VFSError{
|
||||
Type: ErrorTypeNodeUpdateFailed,
|
||||
Error: fmt.Errorf("failed to rename node: %v", err),
|
||||
}
|
||||
}
|
||||
|
||||
case UpdateOperationChange:
|
||||
// Change操作仅适用于文件和服务类型节点
|
||||
if node.Type != models.VfsNodeTypeFile && node.Type != models.VfsNodeTypeService {
|
||||
return nil, &VFSError{
|
||||
Type: ErrorTypeBadRequest,
|
||||
Error: fmt.Errorf("change operation is only supported for file and service nodes"),
|
||||
}
|
||||
}
|
||||
|
||||
if callback != nil && node.Type == models.VfsNodeTypeService {
|
||||
_, err := callback(thisArg, node, data)
|
||||
if err != nil {
|
||||
return nil, &VFSError{
|
||||
Type: ErrorTypeServiceProxyFailed,
|
||||
Error: fmt.Errorf("failed to proxy change to service: %v", err),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
case UpdateOperationMove:
|
||||
// FIXME: 需要添加权限控制
|
||||
if len(data) == 0 {
|
||||
return nil, &VFSError{
|
||||
Type: ErrorTypeBadRequest,
|
||||
Error: fmt.Errorf("target path cannot be empty"),
|
||||
}
|
||||
}
|
||||
|
||||
// 移动节点到新路径
|
||||
parentPath, nodeName, nodeType, err := models.ParsePathComponents(string(data))
|
||||
if err != nil {
|
||||
return nil, &VFSError{
|
||||
Type: ErrorTypeInvalidPath,
|
||||
Error: err,
|
||||
}
|
||||
}
|
||||
|
||||
if nodeType != node.Type {
|
||||
return nil, &VFSError{
|
||||
Type: ErrorTypeInvalidArgument,
|
||||
Error: fmt.Errorf("invalid path type"),
|
||||
}
|
||||
}
|
||||
|
||||
parentNode, err := s.vfs.GetNodeByPath(parentPath)
|
||||
if err != nil {
|
||||
return nil, &VFSError{
|
||||
Type: ErrorTypePathNotFound,
|
||||
Error: err,
|
||||
}
|
||||
}
|
||||
|
||||
sameNode, err := s.vfs.GetNodeByParentIDAndName(parentNode.ID, nodeName)
|
||||
if sameNode != nil || err != nil {
|
||||
return nil, &VFSError{
|
||||
Type: ErrorTypeNodeMoveFailed,
|
||||
Error: err,
|
||||
}
|
||||
}
|
||||
|
||||
node.ParentID = parentNode.ID
|
||||
if err := s.vfs.UpdateNode(node); err != nil {
|
||||
return nil, &VFSError{
|
||||
Type: ErrorTypeNodeMoveFailed,
|
||||
Error: fmt.Errorf("failed to move node: %v", err),
|
||||
}
|
||||
}
|
||||
|
||||
default:
|
||||
return nil, &VFSError{
|
||||
Type: ErrorTypeBadRequest,
|
||||
Error: fmt.Errorf("unsupported operation type"),
|
||||
}
|
||||
}
|
||||
|
||||
// 返回更新后的节点信息
|
||||
return node, nil
|
||||
}
|
50
internal/vfs/services/vfs_error.go
Normal file
50
internal/vfs/services/vfs_error.go
Normal file
@ -0,0 +1,50 @@
|
||||
package vfs_service
|
||||
|
||||
type VFSErrorType int
|
||||
|
||||
const (
|
||||
ErrorTypeNoError = iota
|
||||
|
||||
// 通用错误类型
|
||||
ErrorTypeNotFound
|
||||
ErrorTypeAlreadyExists
|
||||
ErrorTypeForbidden
|
||||
ErrorTypeInternal
|
||||
ErrorTypeBadRequest
|
||||
ErrorTypeUnauthorized
|
||||
ErrorTypeConflict
|
||||
ErrorTypeNotImplemented
|
||||
ErrorTypeInvalidArgument
|
||||
|
||||
// 用户相关错误
|
||||
ErrorTypeUserNotFound
|
||||
ErrorTypeUserAlreadyExists
|
||||
ErrorTypeUserCreationFailed
|
||||
ErrorTypeUserDeletionFailed
|
||||
|
||||
// 节点相关错误
|
||||
ErrorTypeNodeNotFound
|
||||
ErrorTypeNodeAlreadyExists
|
||||
ErrorTypeNodeCreationFailed
|
||||
ErrorTypeNodeDeletionFailed
|
||||
ErrorTypeNodeUpdateFailed
|
||||
ErrorTypeNodeMoveFailed
|
||||
ErrorTypeNodeAccessDenied
|
||||
|
||||
// 权限相关错误
|
||||
ErrorTypePermissionDenied
|
||||
ErrorTypeInvalidToken
|
||||
|
||||
// 服务代理相关错误
|
||||
ErrorTypeServiceProxyNotFound
|
||||
ErrorTypeServiceProxyFailed
|
||||
|
||||
// 路径相关错误
|
||||
ErrorTypeInvalidPath
|
||||
ErrorTypePathNotFound
|
||||
)
|
||||
|
||||
type VFSError struct {
|
||||
Type VFSErrorType
|
||||
Error error
|
||||
}
|
119
internal/vfs/services/vfs_proxy.go
Normal file
119
internal/vfs/services/vfs_proxy.go
Normal file
@ -0,0 +1,119 @@
|
||||
package vfs_service
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"net/http"
|
||||
"strings"
|
||||
"sync"
|
||||
|
||||
"git.zzyxyz.com/zzy/zzyxyz_go_api/internal/vfs/models"
|
||||
)
|
||||
|
||||
// ServiceProxy 服务代理接口
|
||||
type ServiceProxy interface {
|
||||
// Get 从后端服务获取数据
|
||||
Get(servicePath string, node *models.VfsNode) ([]byte, error)
|
||||
|
||||
// Create 在后端服务创建资源
|
||||
Create(servicePath string, node *models.VfsNode, data []byte) ([]byte, error) // 返回创建的资源ID
|
||||
|
||||
// Update 更新后端服务资源
|
||||
Update(servicePath string, node *models.VfsNode, data []byte) error
|
||||
|
||||
// Delete 删除后端服务资源
|
||||
Delete(servicePath string, node *models.VfsNode) error
|
||||
|
||||
// GetName 获取代理名称
|
||||
GetName() string
|
||||
}
|
||||
|
||||
// ProxyEntry 代理表条目
|
||||
type ProxyEntry struct {
|
||||
Name string
|
||||
MatchExt string
|
||||
Proxy ServiceProxy // 对应的代理实现
|
||||
}
|
||||
|
||||
type ProxyService struct {
|
||||
Proxies []*ProxyEntry
|
||||
proxyMutex sync.RWMutex
|
||||
}
|
||||
|
||||
func NewProxyService() *ProxyService {
|
||||
return &ProxyService{
|
||||
Proxies: make([]*ProxyEntry, 0),
|
||||
proxyMutex: sync.RWMutex{},
|
||||
}
|
||||
}
|
||||
|
||||
// FindProxyByServiceName 根据服务节点名称查找对应的代理
|
||||
func (s *ProxyService) findProxyByServiceName(serviceName string) ServiceProxy {
|
||||
s.proxyMutex.RLock()
|
||||
defer s.proxyMutex.RUnlock()
|
||||
|
||||
if serviceName == "" {
|
||||
return nil
|
||||
}
|
||||
|
||||
// 根据服务名称匹配前缀
|
||||
for _, entry := range s.Proxies {
|
||||
if entry.MatchExt == serviceName {
|
||||
return entry.Proxy
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (s *ProxyService) RegisterProxy(entry *ProxyEntry) {
|
||||
s.proxyMutex.Lock()
|
||||
defer s.proxyMutex.Unlock()
|
||||
|
||||
s.Proxies = append(s.Proxies, entry)
|
||||
}
|
||||
|
||||
func (s *ProxyService) StrictProxy2Service(method string, data []byte, node *models.VfsNode) ([]byte, error) {
|
||||
if node.Type != models.VfsNodeTypeService {
|
||||
return nil, fmt.Errorf("node is not a service")
|
||||
}
|
||||
exts := strings.Split(node.Name, ".")
|
||||
var serviceName = exts[1]
|
||||
// log.Println("Proxy2Service: ", serviceName)
|
||||
// 查找对应的代理
|
||||
proxy := s.findProxyByServiceName(serviceName)
|
||||
if proxy == nil {
|
||||
return nil, fmt.Errorf("service proxy not found for: %s", serviceName)
|
||||
}
|
||||
|
||||
// 根据HTTP方法调用相应的代理方法
|
||||
switch method {
|
||||
case http.MethodGet:
|
||||
result, err := proxy.Get(serviceName, node)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to get service data: %v", err)
|
||||
}
|
||||
return result, nil
|
||||
case http.MethodPost:
|
||||
// 读取请求体数据
|
||||
result, err := proxy.Create(serviceName, node, data)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to create service resource: %v", err)
|
||||
}
|
||||
return result, nil
|
||||
case http.MethodPut, http.MethodPatch:
|
||||
// 读取请求体数据
|
||||
err := proxy.Update(serviceName, node, data)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to update service resource: %v", err)
|
||||
}
|
||||
return nil, nil
|
||||
case http.MethodDelete:
|
||||
err := proxy.Delete(serviceName, node)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to delete service resource: %v", err)
|
||||
}
|
||||
return nil, nil
|
||||
default:
|
||||
return nil, fmt.Errorf("method not allowed")
|
||||
}
|
||||
}
|
82
internal/vfs/services/vfs_user.go
Normal file
82
internal/vfs/services/vfs_user.go
Normal file
@ -0,0 +1,82 @@
|
||||
package vfs_service
|
||||
|
||||
import (
|
||||
"crypto/rand"
|
||||
"fmt"
|
||||
"log"
|
||||
"time"
|
||||
|
||||
"git.zzyxyz.com/zzy/zzyxyz_go_api/internal/vfs/models"
|
||||
"github.com/casbin/casbin/v2"
|
||||
)
|
||||
|
||||
type UserService struct {
|
||||
// vfs *models.VfsService
|
||||
vfs *models.VfsDAO
|
||||
enforcer *casbin.Enforcer
|
||||
// errorHandler *ErrorHandler
|
||||
}
|
||||
|
||||
func NewUserService(vfs *models.VfsDAO, enforcer *casbin.Enforcer) *UserService {
|
||||
return &UserService{
|
||||
vfs: vfs,
|
||||
enforcer: enforcer,
|
||||
}
|
||||
}
|
||||
|
||||
func generateToken() string {
|
||||
bytes := make([]byte, 16)
|
||||
if _, err := rand.Read(bytes); err != nil {
|
||||
// fallback to time-based token
|
||||
return fmt.Sprintf("%x", time.Now().UnixNano())
|
||||
}
|
||||
return fmt.Sprintf("%x", bytes)
|
||||
}
|
||||
|
||||
func (s *UserService) CreateUser(username string) (*string, *VFSError) {
|
||||
token := generateToken()
|
||||
// 创建用户
|
||||
err := s.vfs.CreateUser(username, token)
|
||||
if err != nil {
|
||||
return nil, &VFSError{
|
||||
Type: ErrorTypeUserCreationFailed,
|
||||
Error: err,
|
||||
}
|
||||
}
|
||||
|
||||
// 为新用户添加角色
|
||||
_, err = s.enforcer.AddRoleForUser(username, "user")
|
||||
if err != nil {
|
||||
log.Printf("Failed to add role for user %s: %v", username, err)
|
||||
}
|
||||
|
||||
// 保存策略
|
||||
s.enforcer.SavePolicy()
|
||||
|
||||
// 返回带有token的响应
|
||||
return &token, nil
|
||||
}
|
||||
|
||||
func (s *UserService) DeleteUser(username string) *VFSError {
|
||||
// 删除用户
|
||||
err := s.vfs.DeleteUser(username)
|
||||
if err != nil {
|
||||
return &VFSError{
|
||||
Type: ErrorTypeUserDeletionFailed,
|
||||
Error: err,
|
||||
}
|
||||
}
|
||||
|
||||
// 从权限系统中移除用户
|
||||
// 移除用户的所有角色
|
||||
_, err = s.enforcer.DeleteRolesForUser(username)
|
||||
if err != nil {
|
||||
log.Printf("Failed to delete roles for user %s: %v", username, err)
|
||||
}
|
||||
|
||||
// 保存策略
|
||||
s.enforcer.SavePolicy()
|
||||
|
||||
// 成功删除返回204状态
|
||||
return nil
|
||||
}
|
183
internal/vfs/services/vfsdriver/vfs_bookmark.go
Normal file
183
internal/vfs/services/vfsdriver/vfs_bookmark.go
Normal file
@ -0,0 +1,183 @@
|
||||
// internal/handlers/vfs_driver/vfs_bookmark.go
|
||||
|
||||
package vfsdriver
|
||||
|
||||
import (
|
||||
"context"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"net/http"
|
||||
|
||||
api "git.zzyxyz.com/zzy/zzyxyz_go_api/gen/bookmarks_client"
|
||||
"git.zzyxyz.com/zzy/zzyxyz_go_api/internal/vfs/models"
|
||||
vfs_service "git.zzyxyz.com/zzy/zzyxyz_go_api/internal/vfs/services"
|
||||
)
|
||||
|
||||
type VfsBookMarkService struct {
|
||||
client *api.ClientWithResponses
|
||||
token string
|
||||
}
|
||||
|
||||
func NewVfsBookMarkService(serverURL string) (*vfs_service.ProxyEntry, error) {
|
||||
client, err := api.NewClientWithResponses(serverURL)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
ret := vfs_service.ProxyEntry{
|
||||
Name: "bookmark",
|
||||
MatchExt: "bk",
|
||||
Proxy: &VfsBookMarkService{
|
||||
client: client,
|
||||
token: "random_token",
|
||||
},
|
||||
}
|
||||
return &ret, nil
|
||||
}
|
||||
|
||||
// Create implements ServiceProxy.
|
||||
func (v *VfsBookMarkService) Create(servicePath string, node *models.VfsNode, data []byte) ([]byte, error) {
|
||||
ctx := context.Background()
|
||||
|
||||
// 解析传入的数据为 BookmarkRequest
|
||||
var req api.BookmarkRequest
|
||||
if err := json.Unmarshal(data, &req); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// 调用 bookmark 服务创建书签
|
||||
resp, err := v.client.CreateBookmarkWithResponse(ctx, int64(node.ID), req, func(ctx context.Context, req *http.Request) error {
|
||||
req.Header.Set("X-BookMark-Token", v.token)
|
||||
return nil
|
||||
})
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// 处理响应
|
||||
if resp.JSON201 != nil {
|
||||
data, err := json.Marshal(resp.JSON201)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("marshal response error: %w", err)
|
||||
}
|
||||
return data, nil
|
||||
}
|
||||
|
||||
// 处理错误情况
|
||||
if resp.JSON400 != nil {
|
||||
return nil, fmt.Errorf("bad request: %s", resp.JSON400.Message)
|
||||
}
|
||||
|
||||
if resp.JSON500 != nil {
|
||||
return nil, fmt.Errorf("server error: %s", resp.JSON500.Message)
|
||||
}
|
||||
|
||||
return nil, fmt.Errorf("unknown error: %s %s", resp.HTTPResponse.Status, resp.Body)
|
||||
}
|
||||
|
||||
// Delete implements ServiceProxy.
|
||||
func (v *VfsBookMarkService) Delete(servicePath string, node *models.VfsNode) error {
|
||||
ctx := context.Background()
|
||||
|
||||
// 调用 bookmark 服务删除书签
|
||||
resp, err := v.client.DeleteBookmarkWithResponse(ctx, int64(node.ID), func(ctx context.Context, req *http.Request) error {
|
||||
req.Header.Set("X-BookMark-Token", v.token)
|
||||
return nil
|
||||
})
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// 处理响应
|
||||
if resp.StatusCode() == 204 {
|
||||
return nil
|
||||
}
|
||||
|
||||
// 处理错误情况
|
||||
if resp.JSON404 != nil {
|
||||
return fmt.Errorf("not found: %s", resp.JSON404.Message)
|
||||
}
|
||||
|
||||
if resp.JSON500 != nil {
|
||||
return fmt.Errorf("server error: %s", resp.JSON500.Message)
|
||||
}
|
||||
|
||||
return fmt.Errorf("unknown error")
|
||||
}
|
||||
|
||||
// Get implements ServiceProxy.
|
||||
func (v *VfsBookMarkService) Get(servicePath string, node *models.VfsNode) ([]byte, error) {
|
||||
ctx := context.Background()
|
||||
|
||||
// 调用 bookmark 服务获取书签
|
||||
resp, err := v.client.GetBookmarkWithResponse(ctx, int64(node.ID), func(ctx context.Context, req *http.Request) error {
|
||||
req.Header.Set("X-BookMark-Token", v.token)
|
||||
return nil
|
||||
})
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// 处理响应
|
||||
if resp.JSON200 != nil {
|
||||
data, err := json.Marshal(resp.JSON200)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("marshal response error: %w", err)
|
||||
}
|
||||
return data, nil
|
||||
}
|
||||
|
||||
// 处理错误情况
|
||||
if resp.JSON404 != nil {
|
||||
return nil, fmt.Errorf("not found: %s", resp.JSON404.Message)
|
||||
}
|
||||
|
||||
return nil, fmt.Errorf("unknown error")
|
||||
}
|
||||
|
||||
// Update implements ServiceProxy.
|
||||
func (v *VfsBookMarkService) Update(servicePath string, node *models.VfsNode, data []byte) error {
|
||||
ctx := context.Background()
|
||||
|
||||
// 解析传入的数据为 BookmarkRequest
|
||||
var req api.BookmarkRequest
|
||||
if err := json.Unmarshal(data, &req); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// 调用 bookmark 服务更新书签
|
||||
resp, err := v.client.UpdateBookmarkWithResponse(ctx, int64(node.ID), req, func(ctx context.Context, req *http.Request) error {
|
||||
req.Header.Set("X-BookMark-Token", v.token)
|
||||
return nil
|
||||
})
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// 处理响应
|
||||
if resp.JSON200 != nil {
|
||||
return nil
|
||||
}
|
||||
|
||||
// 处理错误情况
|
||||
if resp.JSON400 != nil {
|
||||
return fmt.Errorf("bad request: %s", resp.JSON400.Message)
|
||||
}
|
||||
|
||||
if resp.JSON404 != nil {
|
||||
return fmt.Errorf("not found: %s", resp.JSON404.Message)
|
||||
}
|
||||
|
||||
if resp.JSON500 != nil {
|
||||
return fmt.Errorf("server error: %s", resp.JSON500.Message)
|
||||
}
|
||||
|
||||
return fmt.Errorf("unknown error")
|
||||
}
|
||||
|
||||
// GetName implements ServiceProxy.
|
||||
func (v *VfsBookMarkService) GetName() string {
|
||||
return "bookmark"
|
||||
}
|
||||
|
||||
var _ vfs_service.ServiceProxy = (*VfsBookMarkService)(nil)
|
Reference in New Issue
Block a user