diff --git a/internal/model/user.go b/internal/model/user.go index 0d0461a3..2a9f4d7b 100644 --- a/internal/model/user.go +++ b/internal/model/user.go @@ -91,6 +91,6 @@ func (u User) CanWebdavManage() bool { return u.IsAdmin() || (u.Permission>>9)&1 == 1 } -func (u User) JoinPath(reqPath string) (string, error) { +func (u User) JoinPath(reqPath string) string { return utils.JoinBasePath(u.BasePath, reqPath) } diff --git a/pkg/utils/path.go b/pkg/utils/path.go index 27328fbb..ca03d1cb 100644 --- a/pkg/utils/path.go +++ b/pkg/utils/path.go @@ -67,6 +67,6 @@ func EncodePath(path string, all ...bool) string { return strings.Join(seg, "/") } -func JoinBasePath(basePath, reqPath string) (string, error) { - return stdpath.Join(FixAndCleanPath(basePath), FixAndCleanPath(reqPath)), nil +func JoinBasePath(basePath, reqPath string) string { + return stdpath.Join(FixAndCleanPath(basePath), FixAndCleanPath(reqPath)) } diff --git a/server/handles/aria2.go b/server/handles/aria2.go index f127bf04..78113050 100644 --- a/server/handles/aria2.go +++ b/server/handles/aria2.go @@ -56,11 +56,7 @@ func AddAria2(c *gin.Context) { common.ErrorResp(c, err, 400) return } - reqPath, err := user.JoinPath(req.Path) - if err != nil { - common.ErrorResp(c, err, 403) - return - } + reqPath := user.JoinPath(req.Path) for _, url := range req.Urls { err := aria2.AddURI(c, url, reqPath) if err != nil { diff --git a/server/handles/fsmanage.go b/server/handles/fsmanage.go index 7b95af5b..0a865726 100644 --- a/server/handles/fsmanage.go +++ b/server/handles/fsmanage.go @@ -26,11 +26,7 @@ func FsMkdir(c *gin.Context) { return } user := c.MustGet("user").(*model.User) - reqPath, err := user.JoinPath(req.Path) - if err != nil { - common.ErrorResp(c, err, 403) - return - } + reqPath := user.JoinPath(req.Path) if !user.CanWrite() { meta, err := op.GetNearestMeta(stdpath.Dir(reqPath)) if err != nil { @@ -73,16 +69,9 @@ func FsMove(c *gin.Context) { common.ErrorResp(c, errs.PermissionDenied, 403) return } - srcDir, err := user.JoinPath(req.SrcDir) - if err != nil { - common.ErrorResp(c, err, 403) - return - } - dstDir, err := user.JoinPath(req.DstDir) - if err != nil { - common.ErrorResp(c, err, 403) - return - } + srcDir := user.JoinPath(req.SrcDir) + dstDir := user.JoinPath(req.DstDir) + for _, name := range req.Names { err := fs.Move(c, stdpath.Join(srcDir, name), dstDir) if err != nil { @@ -110,16 +99,9 @@ func FsCopy(c *gin.Context) { common.ErrorResp(c, errs.PermissionDenied, 403) return } - srcDir, err := user.JoinPath(req.SrcDir) - if err != nil { - common.ErrorResp(c, err, 403) - return - } - dstDir, err := user.JoinPath(req.DstDir) - if err != nil { - common.ErrorResp(c, err, 403) - return - } + srcDir := user.JoinPath(req.SrcDir) + dstDir := user.JoinPath(req.DstDir) + var addedTask []string for _, name := range req.Names { ok, err := fs.Copy(c, stdpath.Join(srcDir, name), dstDir) @@ -157,11 +139,8 @@ func FsRename(c *gin.Context) { common.ErrorResp(c, errs.PermissionDenied, 403) return } - reqPath, err := user.JoinPath(req.Path) - if err != nil { - common.ErrorResp(c, err, 403) - return - } + reqPath := user.JoinPath(req.Path) + if err := fs.Rename(c, reqPath, req.Name); err != nil { common.ErrorResp(c, err, 500) return @@ -190,11 +169,8 @@ func FsRemove(c *gin.Context) { common.ErrorResp(c, errs.PermissionDenied, 403) return } - reqDir, err := user.JoinPath(req.Dir) - if err != nil { - common.ErrorResp(c, err, 403) - return - } + reqDir := user.JoinPath(req.Dir) + for _, name := range req.Names { err := fs.Remove(c, stdpath.Join(reqDir, name)) if err != nil { diff --git a/server/handles/fsread.go b/server/handles/fsread.go index 4d4d617a..32e61023 100644 --- a/server/handles/fsread.go +++ b/server/handles/fsread.go @@ -56,11 +56,8 @@ func FsList(c *gin.Context) { } req.Validate() user := c.MustGet("user").(*model.User) - reqPath, err := user.JoinPath(req.Path) - if err != nil { - common.ErrorResp(c, err, 403) - return - } + reqPath := user.JoinPath(req.Path) + meta, err := op.GetNearestMeta(reqPath) if err != nil { if !errors.Is(errors.Cause(err), errs.MetaNotFound) { @@ -111,12 +108,7 @@ func FsDirs(c *gin.Context) { return } } else { - tmp, err := user.JoinPath(req.Path) - if err != nil { - common.ErrorResp(c, err, 403) - return - } - reqPath = tmp + reqPath = user.JoinPath(req.Path) } meta, err := op.GetNearestMeta(reqPath) if err != nil { @@ -228,11 +220,8 @@ func FsGet(c *gin.Context) { return } user := c.MustGet("user").(*model.User) - reqPath, err := user.JoinPath(req.Path) - if err != nil { - common.ErrorResp(c, err, 403) - return - } + reqPath := user.JoinPath(req.Path) + meta, err := op.GetNearestMeta(reqPath) if err != nil { if !errors.Is(errors.Cause(err), errs.MetaNotFound) { @@ -339,11 +328,8 @@ func FsOther(c *gin.Context) { } user := c.MustGet("user").(*model.User) var err error - req.Path, err = user.JoinPath(req.Path) - if err != nil { - common.ErrorResp(c, err, 403) - return - } + req.Path = user.JoinPath(req.Path) + meta, err := op.GetNearestMeta(req.Path) if err != nil { if !errors.Is(errors.Cause(err), errs.MetaNotFound) { diff --git a/server/handles/fsup.go b/server/handles/fsup.go index b32fca50..aa8769f0 100644 --- a/server/handles/fsup.go +++ b/server/handles/fsup.go @@ -21,11 +21,8 @@ func FsStream(c *gin.Context) { } asTask := c.GetHeader("As-Task") == "true" user := c.MustGet("user").(*model.User) - path, err = user.JoinPath(path) - if err != nil { - common.ErrorResp(c, err, 403) - return - } + path = user.JoinPath(path) + dir, name := stdpath.Split(path) sizeStr := c.GetHeader("Content-Length") size, err := strconv.ParseInt(sizeStr, 10, 64) @@ -64,11 +61,8 @@ func FsForm(c *gin.Context) { } asTask := c.GetHeader("As-Task") == "true" user := c.MustGet("user").(*model.User) - path, err = user.JoinPath(path) - if err != nil { - common.ErrorResp(c, err, 403) - return - } + path = user.JoinPath(path) + storage, err := fs.GetStorage(path) if err != nil { common.ErrorResp(c, err, 400) diff --git a/server/handles/search.go b/server/handles/search.go index 8881731b..4269c5a3 100644 --- a/server/handles/search.go +++ b/server/handles/search.go @@ -34,11 +34,8 @@ func Search(c *gin.Context) { return } user := c.MustGet("user").(*model.User) - req.Parent, err = user.JoinPath(req.Parent) - if err != nil { - common.ErrorResp(c, err, 400) - return - } + req.Parent = user.JoinPath(req.Parent) + if err := req.Validate(); err != nil { common.ErrorResp(c, err, 400) return diff --git a/server/middlewares/fsup.go b/server/middlewares/fsup.go index 809e8f29..efdc6b03 100644 --- a/server/middlewares/fsup.go +++ b/server/middlewares/fsup.go @@ -22,11 +22,8 @@ func FsUp(c *gin.Context) { return } user := c.MustGet("user").(*model.User) - path, err = user.JoinPath(path) - if err != nil { - common.ErrorResp(c, err, 403) - return - } + path = user.JoinPath(path) + meta, err := op.GetNearestMeta(stdpath.Dir(path)) if err != nil { if !errors.Is(errors.Cause(err), errs.MetaNotFound) { diff --git a/server/webdav/webdav.go b/server/webdav/webdav.go index 7ab8dbf5..2723c084 100644 --- a/server/webdav/webdav.go +++ b/server/webdav/webdav.go @@ -183,10 +183,8 @@ func (h *Handler) handleOptions(w http.ResponseWriter, r *http.Request) (status } ctx := r.Context() user := ctx.Value("user").(*model.User) - reqPath, err = user.JoinPath(reqPath) - if err != nil { - return 403, err - } + reqPath = user.JoinPath(reqPath) + allow := "OPTIONS, LOCK, PUT, MKCOL" if fi, err := fs.Get(ctx, reqPath); err == nil { if fi.IsDir() { @@ -211,10 +209,8 @@ func (h *Handler) handleGetHeadPost(w http.ResponseWriter, r *http.Request) (sta // TODO: check locks for read-only access?? ctx := r.Context() user := ctx.Value("user").(*model.User) - reqPath, err = user.JoinPath(reqPath) - if err != nil { - return 403, err - } + reqPath = user.JoinPath(reqPath) + fi, err := fs.Get(ctx, reqPath) if err != nil { return http.StatusNotFound, err @@ -269,10 +265,8 @@ func (h *Handler) handleDelete(w http.ResponseWriter, r *http.Request) (status i ctx := r.Context() user := ctx.Value("user").(*model.User) - reqPath, err = user.JoinPath(reqPath) - if err != nil { - return 403, err - } + reqPath = user.JoinPath(reqPath) + // TODO: return MultiStatus where appropriate. // "godoc os RemoveAll" says that "If the path does not exist, RemoveAll @@ -305,10 +299,8 @@ func (h *Handler) handlePut(w http.ResponseWriter, r *http.Request) (status int, // comments in http.checkEtag. ctx := r.Context() user := ctx.Value("user").(*model.User) - reqPath, err = user.JoinPath(reqPath) - if err != nil { - return 403, err - } + reqPath = user.JoinPath(reqPath) + obj := model.Object{ Name: path.Base(reqPath), Size: r.ContentLength, @@ -354,10 +346,7 @@ func (h *Handler) handleMkcol(w http.ResponseWriter, r *http.Request) (status in ctx := r.Context() user := ctx.Value("user").(*model.User) - reqPath, err = user.JoinPath(reqPath) - if err != nil { - return 403, err - } + reqPath = user.JoinPath(reqPath) if r.ContentLength > 0 { return http.StatusUnsupportedMediaType, nil @@ -404,14 +393,9 @@ func (h *Handler) handleCopyMove(w http.ResponseWriter, r *http.Request) (status ctx := r.Context() user := ctx.Value("user").(*model.User) - src, err = user.JoinPath(src) - if err != nil { - return 403, err - } - dst, err = user.JoinPath(dst) - if err != nil { - return 403, err - } + src = user.JoinPath(src) + + dst = user.JoinPath(dst) if r.Method == "COPY" { // Section 7.5.1 says that a COPY only needs to lock the destination, @@ -502,10 +486,8 @@ func (h *Handler) handleLock(w http.ResponseWriter, r *http.Request) (retStatus } } reqPath, status, err := h.stripPrefix(r.URL.Path) - reqPath, err = user.JoinPath(reqPath) - if err != nil { - return 403, err - } + reqPath = user.JoinPath(reqPath) + if err != nil { return status, err } @@ -586,10 +568,8 @@ func (h *Handler) handlePropfind(w http.ResponseWriter, r *http.Request) (status } ctx := r.Context() user := ctx.Value("user").(*model.User) - reqPath, err = user.JoinPath(reqPath) - if err != nil { - return 403, err - } + reqPath = user.JoinPath(reqPath) + fi, err := fs.Get(ctx, reqPath) if err != nil { if errs.IsObjectNotFound(err) { @@ -665,10 +645,8 @@ func (h *Handler) handleProppatch(w http.ResponseWriter, r *http.Request) (statu ctx := r.Context() user := ctx.Value("user").(*model.User) - reqPath, err = user.JoinPath(reqPath) - if err != nil { - return 403, err - } + reqPath = user.JoinPath(reqPath) + if _, err := fs.Get(ctx, reqPath); err != nil { if errs.IsObjectNotFound(err) { return http.StatusNotFound, err