package vfs import ( "context" "fmt" "log" "net/http" api "git.zzyxyz.com/zzy/zzyxyz_go_api/gen/vfs_server" "git.zzyxyz.com/zzy/zzyxyz_go_api/internal/vfs/models" ) // TODO 重命名名称冲突,以及合法名称检测,以及JSONBody and TextBody的检测 // CreateVFSNode implements server.StrictServerInterface. func (v *VfsImpl) CreateVFSNode(ctx context.Context, request api.CreateVFSNodeRequestObject) (api.CreateVFSNodeResponseObject, error) { // 解析路径组件 parentPath, nodeName, nodeType, err := models.ParsePathComponents(request.Params.Path) if err != nil { return api.CreateVFSNode400JSONResponse{ ParameterErrorJSONResponse: api.ParameterErrorJSONResponse{ Errtype: api.ErrorErrtypeParameterError, Message: err.Error(), }, }, nil } // 读取请求体数据 // FIXME: 使用stream可能更好 var content []byte = []byte(*request.Body) // 创建节点 (可能需要传递content数据到vfs层) node, err := v.vfs.CreateNodeByComponents(parentPath, nodeName, nodeType) if err != nil { return api.CreateVFSNode500JSONResponse{ ServerInternalErrorJSONResponse: api.ServerInternalErrorJSONResponse{ Errtype: api.ErrorErrtypeInternalServerError, Message: err.Error(), }, }, nil } // 处理服务类型节点 if nodeType == models.VfsNodeTypeService { // 这里可能需要将content传递给服务处理 if result, err := v.StrictProxy2Service(http.MethodPost, content, node); err != nil { // 回滚操作 delete_err := v.vfs.DeleteVFSNode(node) log.Printf("service node: %s, err %s", node.Name, err.Error()) if delete_err != nil { // FIXME: 需要解决这种原子性 return nil, fmt.Errorf("consistency error: %w", err) } return api.CreateVFSNode500JSONResponse{ ServerInternalErrorJSONResponse: api.ServerInternalErrorJSONResponse{ Errtype: api.ErrorErrtypeServiceProxyError, Message: err.Error(), }, }, nil } else { // 返回二进制数据响应 return api.CreateVFSNode201TextResponse(result), nil } } // 返回JSON响应 return api.CreateVFSNode201JSONResponse{ Name: node.Name, Type: ModelType2ResponseType(node.Type), CreatedAt: node.CreatedAt, UpdatedAt: node.UpdatedAt, }, nil } // DeleteVFSNode implements server.StrictServerInterface. func (v *VfsImpl) DeleteVFSNode(ctx context.Context, request api.DeleteVFSNodeRequestObject) (api.DeleteVFSNodeResponseObject, error) { // 获取节点 node, err := v.vfs.GetNodeByPath(request.Params.Path) if err != nil { return api.DeleteVFSNode404JSONResponse{ PathNotFoundErrorJSONResponse: api.PathNotFoundErrorJSONResponse{ Errtype: api.ErrorErrtypePathNotFound, Message: err.Error(), }, }, nil } // 根据节点类型进行不同处理 switch node.Type { case models.VfsNodeTypeService: // 对于服务类型节点,通过代理删除 _, err := v.StrictProxy2Service(http.MethodDelete, nil, node) if err != nil { return api.DeleteVFSNode500JSONResponse{ ServerInternalErrorJSONResponse: api.ServerInternalErrorJSONResponse{ Errtype: api.ErrorErrtypeServiceProxyError, Message: err.Error(), }, }, nil } case models.VfsNodeTypeDirectory: // 检查目录是否为空 children, err := v.vfs.GetChildren(node.ID) if err != nil { return api.DeleteVFSNode500JSONResponse{ ServerInternalErrorJSONResponse: api.ServerInternalErrorJSONResponse{ Errtype: api.ErrorErrtypeInternalServerError, Message: "Failed to get directory children: " + err.Error(), }, }, nil } if len(children) != 0 { return api.DeleteVFSNode400JSONResponse{ ParameterErrorJSONResponse: api.ParameterErrorJSONResponse{ Errtype: api.ErrorErrtypeConflictError, Message: "Directory is not empty", }, }, nil } case models.VfsNodeTypeFile: // TODO // 文件类型节点可以直接删除 fallthrough default: return api.DeleteVFSNode400JSONResponse{ ParameterErrorJSONResponse: api.ParameterErrorJSONResponse{ Errtype: api.ErrorErrtypeParameterError, Message: "Node type not supported for deletion", }, }, nil } // 执行实际的删除操作 if err := v.vfs.DeleteVFSNode(node); err != nil { return api.DeleteVFSNode500JSONResponse{ ServerInternalErrorJSONResponse: api.ServerInternalErrorJSONResponse{ Errtype: api.ErrorErrtypeInternalServerError, Message: "Failed to delete node: " + err.Error(), }, }, nil } // 成功删除返回204状态 return api.DeleteVFSNode204Response{}, nil } // GetVFSNode implements server.StrictServerInterface. func (v *VfsImpl) GetVFSNode(ctx context.Context, request api.GetVFSNodeRequestObject) (api.GetVFSNodeResponseObject, error) { // 获取节点 node, err := v.vfs.GetNodeByPath(request.Params.Path) if err != nil { return api.GetVFSNode404JSONResponse{ PathNotFoundErrorJSONResponse: api.PathNotFoundErrorJSONResponse{ Errtype: api.ErrorErrtypePathNotFound, Message: err.Error(), }, }, nil } switch node.Type { case models.VfsNodeTypeDirectory: // 处理目录类型 entries, err := v.vfs.GetChildren(node.ID) if err != nil { return api.GetVFSNode500JSONResponse{ ServerInternalErrorJSONResponse: api.ServerInternalErrorJSONResponse{ Errtype: api.ErrorErrtypeInternalServerError, Message: err.Error(), }, }, nil } var responseEntries []api.VFSDirectoryEntry for _, entry := range entries { responseEntries = append(responseEntries, api.VFSDirectoryEntry{ Name: entry.Name, Type: ModelType2ResponseType(entry.Type), }) } return api.GetVFSNode200JSONResponse(responseEntries), nil // case models.VfsNodeTypeFile: // // 处理文件类型,返回二进制数据 // // 这里需要从vfs中获取文件内容 // fileContent, err := v.vfs.GetFileContent(node.ID) // 假设有此方法 // if err != nil { // return api.GetVFSNode500JSONResponse{ // ServerInternalErrorJSONResponse: api.ServerInternalErrorJSONResponse{ // Errtype: api.ErrorErrtypeInternalServerError, // Message: err.Error(), // }, // }, nil // } // return api.GetVFSNode200ApplicationoctetStreamResponse{ // Body: bytes.NewReader(fileContent), // ContentLength: int64(len(fileContent)), // }, nil case models.VfsNodeTypeService: // 处理服务类型 result, err := v.StrictProxy2Service(http.MethodGet, nil, node) if err != nil { return api.GetVFSNode500JSONResponse{ ServerInternalErrorJSONResponse: api.ServerInternalErrorJSONResponse{ Errtype: api.ErrorErrtypeServiceProxyError, Message: err.Error(), }, }, nil } return api.GetVFSNode200TextResponse(result), nil default: return api.GetVFSNode400JSONResponse{ ParameterErrorJSONResponse: api.ParameterErrorJSONResponse{ Errtype: api.ErrorErrtypeParameterError, Message: "Not a valid node type", }, }, nil } } // UpdateVFSNode implements server.StrictServerInterface. func (v *VfsImpl) UpdateVFSNode(ctx context.Context, request api.UpdateVFSNodeRequestObject) (api.UpdateVFSNodeResponseObject, error) { // 获取节点 node, err := v.vfs.GetNodeByPath(request.Params.Path) if err != nil { return api.UpdateVFSNode404JSONResponse{ PathNotFoundErrorJSONResponse: api.PathNotFoundErrorJSONResponse{ Errtype: api.ErrorErrtypePathNotFound, Message: err.Error(), }, }, nil } // 根据操作类型进行不同处理 switch request.Params.Op { case api.Rename: // 检查请求体 if request.JSONBody == nil { return api.UpdateVFSNode400JSONResponse{ ParameterErrorJSONResponse: api.ParameterErrorJSONResponse{ Errtype: api.ErrorErrtypeParameterError, Message: "Request body is required for rename operation", }, }, nil } newName := string(*request.JSONBody) if err := v.vfs.CheckNameValid(newName); err != nil { return api.UpdateVFSNode400JSONResponse{ ParameterErrorJSONResponse: api.ParameterErrorJSONResponse{ Errtype: api.ErrorErrtypeParameterError, Message: err.Error(), }, }, nil } // FIXME: 检查新名称是否合法 // 对于服务类型节点,可能需要保留特定后缀 if node.Type == models.VfsNodeTypeService { // 可以添加对服务节点重命名的特殊处理 // 例如确保保留.service后缀 } // 更新节点名称 node.Name = newName if err := v.vfs.UpdateVFSNode(node); err != nil { return api.UpdateVFSNode500JSONResponse{ ServerInternalErrorJSONResponse: api.ServerInternalErrorJSONResponse{ Errtype: api.ErrorErrtypeInternalServerError, Message: "Failed to rename node: " + err.Error(), }, }, nil } case api.Change: // Change操作仅适用于文件和服务类型节点 if node.Type != models.VfsNodeTypeFile && node.Type != models.VfsNodeTypeService { return api.UpdateVFSNode400JSONResponse{ ParameterErrorJSONResponse: api.ParameterErrorJSONResponse{ Errtype: api.ErrorErrtypeParameterError, Message: "Change operation is only supported for file and service nodes", }, }, nil } // 读取请求体数据 // FIXME: 使用stream可能更好 var content []byte = []byte(*request.TextBody) // 对于服务节点,通过代理发送变更 if node.Type == models.VfsNodeTypeService { _, err := v.StrictProxy2Service(http.MethodPatch, content, node) if err != nil { return api.UpdateVFSNode500JSONResponse{ ServerInternalErrorJSONResponse: api.ServerInternalErrorJSONResponse{ Errtype: api.ErrorErrtypeServiceProxyError, Message: "Failed to proxy change to service: " + err.Error(), }, }, nil } } else { // 对于文件节点,可能需要更新文件内容 // 这里可以根据需要实现文件内容更新逻辑 return api.UpdateVFSNode500JSONResponse{ ServerInternalErrorJSONResponse: api.ServerInternalErrorJSONResponse{ Errtype: api.ErrorErrtypeInternalServerError, Message: "File Opreation Not Supported", }, }, nil } case api.Move: // FIXME: 需要添加权限控制 if request.JSONBody == nil { return api.UpdateVFSNode400JSONResponse{ ParameterErrorJSONResponse: api.ParameterErrorJSONResponse{ Errtype: api.ErrorErrtypeParameterError, Message: "Request body is required for move operation", }, }, nil } targetPath := string(*request.JSONBody) if targetPath == "" { return api.UpdateVFSNode400JSONResponse{ ParameterErrorJSONResponse: api.ParameterErrorJSONResponse{ Errtype: api.ErrorErrtypeParameterError, Message: "Target path cannot be empty", }, }, nil } // 移动节点到新路径 if err := v.vfs.MoveToPath(node, targetPath); err != nil { return api.UpdateVFSNode500JSONResponse{ ServerInternalErrorJSONResponse: api.ServerInternalErrorJSONResponse{ Errtype: api.ErrorErrtypeInternalServerError, Message: "Failed to move node: " + err.Error(), }, }, nil } case api.Copy: fallthrough // if request.Body == nil { // return api.UpdateVFSNode400JSONResponse{ // ParameterErrorJSONResponse: api.ParameterErrorJSONResponse{ // Errtype: api.ErrorErrtypeParameterError, // Message: "Request body is required for copy operation", // }, // }, nil // } // targetPath := string(*request.Body) // if targetPath == "" { // return api.UpdateVFSNode400JSONResponse{ // ParameterErrorJSONResponse: api.ParameterErrorJSONResponse{ // Errtype: api.ErrorErrtypeParameterError, // Message: "Target path cannot be empty", // }, // }, nil // } // // 复制节点到新路径 // if err := v.vfs.CopyToPath(node, targetPath); err != nil { // return api.UpdateVFSNode500JSONResponse{ // ServerInternalErrorJSONResponse: api.ServerInternalErrorJSONResponse{ // Errtype: api.ErrorErrtypeInternalServerError, // Message: "Failed to copy node: " + err.Error(), // }, // }, nil // } default: return api.UpdateVFSNode400JSONResponse{ ParameterErrorJSONResponse: api.ParameterErrorJSONResponse{ Errtype: api.ErrorErrtypeParameterError, Message: "Unsupported operation type", }, }, nil } // 返回更新后的节点信息 return api.UpdateVFSNode200JSONResponse{ Name: node.Name, Type: ModelType2ResponseType(node.Type), CreatedAt: node.CreatedAt, UpdatedAt: node.UpdatedAt, }, nil } func ModelType2ResponseType(nodeType models.VfsNodeType) api.VFSNodeType { var reponseType api.VFSNodeType switch nodeType { case models.VfsNodeTypeFile: reponseType = api.File case models.VfsNodeTypeDirectory: reponseType = api.Directory case models.VfsNodeTypeService: reponseType = api.Service } return reponseType } // CreateUser implements server.StrictServerInterface. func (v *VfsImpl) CreateUser(ctx context.Context, request api.CreateUserRequestObject) (api.CreateUserResponseObject, error) { // 从上下文中获取请求头信息 // 注意:在严格模式下,我们需要从上下文获取请求信息 // 但这里我们无法直接访问请求头,因此需要在中间件中处理或使用其他方式传递 // 由于严格模式接口限制,我们无法直接访问请求头 // 这里假设我们通过其他方式验证了权限(比如中间件) // token := c.GetHeader("X-VFS-Token") // if token != v.config.RegisterToken || token != v.config.AdminToken { // c.JSON(http.StatusForbidden, api.Error{ // Errtype: "AccessDenied", // Message: "Access denied", // }) // return // } // 创建用户 token, err := v.vfs.CreateUser(request.Username) if err != nil { // 检查是否是用户已存在的错误 if err.Error() == "user already exists" { return api.CreateUser400JSONResponse{ ParameterErrorJSONResponse: api.ParameterErrorJSONResponse{ Errtype: api.ErrorErrtypeConflictError, Message: "User already exists", }, }, nil } return api.CreateUser500JSONResponse{ ServerInternalErrorJSONResponse: api.ServerInternalErrorJSONResponse{ Errtype: api.ErrorErrtypeInternalServerError, Message: "Failed to create user: " + err.Error(), }, }, nil } // 为新用户添加角色 _, err = v.enfocer.AddRoleForUser(request.Username, "user") if err != nil { log.Printf("Failed to add role for user %s: %v", request.Username, err) // 注意:这里即使添加角色失败,我们也不会回滚用户创建 // 因为用户创建已经成功,且这是两个独立的系统 // FIXME: unknown } // 保存策略 v.enfocer.SavePolicy() // 返回带有token的响应 return api.CreateUser201Response{ Headers: api.CreateUser201ResponseHeaders{ XVFSToken: token, }, }, nil } // DeleteUser implements server.StrictServerInterface. func (v *VfsImpl) DeleteUser(ctx context.Context, request api.DeleteUserRequestObject) (api.DeleteUserResponseObject, error) { // 删除用户 err := v.vfs.DeleteUser(request.Username) if err != nil { // 检查是否是用户未找到的错误 if err.Error() == "user not found" { return api.DeleteUser404JSONResponse{ Errtype: api.ErrorErrtypeNotFoundError, Message: "User not found", }, nil } return api.DeleteUser500JSONResponse{ ServerInternalErrorJSONResponse: api.ServerInternalErrorJSONResponse{ Errtype: api.ErrorErrtypeInternalServerError, Message: "Failed to delete user: " + err.Error(), }, }, nil } // 从权限系统中移除用户 // 移除用户的所有角色 _, err = v.enfocer.DeleteRolesForUser(request.Username) if err != nil { log.Printf("Failed to delete roles for user %s: %v", request.Username, err) // 注意:这里即使删除角色失败,我们也不会回滚用户删除 // 因为数据库中的用户已经删除,且这是两个独立的系统 // FIXME: unknown } // 保存策略 v.enfocer.SavePolicy() // 成功删除返回204状态 return api.DeleteUser204Response{}, nil } // Make sure we conform to ServerInterface var _ api.StrictServerInterface = (*VfsImpl)(nil)