feat(fs): add `overwrite` option to preventing unintentional overwriting (#7809)

pull/7851/head
Jealous 2025-01-18 23:39:07 +08:00 committed by GitHub
parent bb40e2e2cd
commit 59e02287b2
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
2 changed files with 48 additions and 5 deletions

View File

@ -59,6 +59,7 @@ type MoveCopyReq struct {
SrcDir string `json:"src_dir"` SrcDir string `json:"src_dir"`
DstDir string `json:"dst_dir"` DstDir string `json:"dst_dir"`
Names []string `json:"names"` Names []string `json:"names"`
Overwrite bool `json:"overwrite"`
} }
func FsMove(c *gin.Context) { func FsMove(c *gin.Context) {
@ -86,6 +87,14 @@ func FsMove(c *gin.Context) {
common.ErrorResp(c, err, 403) common.ErrorResp(c, err, 403)
return return
} }
if !req.Overwrite {
for _, name := range req.Names {
if res, _ := fs.Get(c, stdpath.Join(dstDir, name), &fs.GetArgs{NoLog: true}); res != nil {
common.ErrorStrResp(c, "file exists", 403)
return
}
}
}
for i, name := range req.Names { for i, name := range req.Names {
err := fs.Move(c, stdpath.Join(srcDir, name), dstDir, len(req.Names) > i+1) err := fs.Move(c, stdpath.Join(srcDir, name), dstDir, len(req.Names) > i+1)
if err != nil { if err != nil {
@ -121,6 +130,14 @@ func FsCopy(c *gin.Context) {
common.ErrorResp(c, err, 403) common.ErrorResp(c, err, 403)
return return
} }
if !req.Overwrite {
for _, name := range req.Names {
if res, _ := fs.Get(c, stdpath.Join(dstDir, name), &fs.GetArgs{NoLog: true}); res != nil {
common.ErrorStrResp(c, "file exists", 403)
return
}
}
}
var addedTasks []task.TaskExtensionInfo var addedTasks []task.TaskExtensionInfo
for i, name := range req.Names { for i, name := range req.Names {
t, err := fs.Copy(c, stdpath.Join(srcDir, name), dstDir, len(req.Names) > i+1) t, err := fs.Copy(c, stdpath.Join(srcDir, name), dstDir, len(req.Names) > i+1)
@ -140,6 +157,7 @@ func FsCopy(c *gin.Context) {
type RenameReq struct { type RenameReq struct {
Path string `json:"path"` Path string `json:"path"`
Name string `json:"name"` Name string `json:"name"`
Overwrite bool `json:"overwrite"`
} }
func FsRename(c *gin.Context) { func FsRename(c *gin.Context) {
@ -158,6 +176,15 @@ func FsRename(c *gin.Context) {
common.ErrorResp(c, err, 403) common.ErrorResp(c, err, 403)
return return
} }
if !req.Overwrite {
dstPath := stdpath.Join(stdpath.Dir(reqPath), req.Name)
if dstPath != reqPath {
if res, _ := fs.Get(c, dstPath, &fs.GetArgs{NoLog: true}); res != nil {
common.ErrorStrResp(c, "file exists", 403)
return
}
}
}
if err := fs.Rename(c, reqPath, req.Name); err != nil { if err := fs.Rename(c, reqPath, req.Name); err != nil {
common.ErrorResp(c, err, 500) common.ErrorResp(c, err, 500)
return return

View File

@ -34,12 +34,20 @@ func FsStream(c *gin.Context) {
return return
} }
asTask := c.GetHeader("As-Task") == "true" asTask := c.GetHeader("As-Task") == "true"
overwrite := c.GetHeader("Overwrite") != "false"
user := c.MustGet("user").(*model.User) user := c.MustGet("user").(*model.User)
path, err = user.JoinPath(path) path, err = user.JoinPath(path)
if err != nil { if err != nil {
common.ErrorResp(c, err, 403) common.ErrorResp(c, err, 403)
return return
} }
if !overwrite {
if res, _ := fs.Get(c, path, &fs.GetArgs{NoLog: true}); res != nil {
_, _ = io.Copy(io.Discard, c.Request.Body)
common.ErrorStrResp(c, "file exists", 403)
return
}
}
dir, name := stdpath.Split(path) dir, name := stdpath.Split(path)
sizeStr := c.GetHeader("Content-Length") sizeStr := c.GetHeader("Content-Length")
size, err := strconv.ParseInt(sizeStr, 10, 64) size, err := strconv.ParseInt(sizeStr, 10, 64)
@ -85,12 +93,20 @@ func FsForm(c *gin.Context) {
return return
} }
asTask := c.GetHeader("As-Task") == "true" asTask := c.GetHeader("As-Task") == "true"
overwrite := c.GetHeader("Overwrite") != "false"
user := c.MustGet("user").(*model.User) user := c.MustGet("user").(*model.User)
path, err = user.JoinPath(path) path, err = user.JoinPath(path)
if err != nil { if err != nil {
common.ErrorResp(c, err, 403) common.ErrorResp(c, err, 403)
return return
} }
if !overwrite {
if res, _ := fs.Get(c, path, &fs.GetArgs{NoLog: true}); res != nil {
_, _ = io.Copy(io.Discard, c.Request.Body)
common.ErrorStrResp(c, "file exists", 403)
return
}
}
storage, err := fs.GetStorage(path, &fs.GetStoragesArgs{}) storage, err := fs.GetStorage(path, &fs.GetStoragesArgs{})
if err != nil { if err != nil {
common.ErrorResp(c, err, 400) common.ErrorResp(c, err, 400)