mirror of https://github.com/Xhofe/alist
fix: check if the req path is relative path (close #2531)
parent
f9788ea7cf
commit
b5bf5f4325
|
@ -2,6 +2,7 @@ package model
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"github.com/alist-org/alist/v3/internal/errs"
|
"github.com/alist-org/alist/v3/internal/errs"
|
||||||
|
"github.com/alist-org/alist/v3/pkg/utils"
|
||||||
"github.com/pkg/errors"
|
"github.com/pkg/errors"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -89,3 +90,7 @@ func (u User) CanWebdavRead() bool {
|
||||||
func (u User) CanWebdavManage() bool {
|
func (u User) CanWebdavManage() bool {
|
||||||
return u.IsAdmin() || (u.Permission>>9)&1 == 1
|
return u.IsAdmin() || (u.Permission>>9)&1 == 1
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (u User) JoinPath(reqPath string) (string, error) {
|
||||||
|
return utils.JoinBasePath(u.BasePath, reqPath)
|
||||||
|
}
|
||||||
|
|
|
@ -6,6 +6,8 @@ import (
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
"runtime"
|
"runtime"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
|
"github.com/alist-org/alist/v3/internal/errs"
|
||||||
)
|
)
|
||||||
|
|
||||||
// StandardizePath convert path like '/' '/root' '/a/b'
|
// StandardizePath convert path like '/' '/root' '/a/b'
|
||||||
|
@ -60,3 +62,10 @@ func EncodePath(path string, all ...bool) string {
|
||||||
}
|
}
|
||||||
return strings.Join(seg, "/")
|
return strings.Join(seg, "/")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func JoinBasePath(basePath, reqPath string) (string, error) {
|
||||||
|
if strings.HasSuffix(reqPath, "..") || strings.Contains(reqPath, "../") {
|
||||||
|
return "", errs.RelativePath
|
||||||
|
}
|
||||||
|
return stdpath.Join(basePath, reqPath), nil
|
||||||
|
}
|
||||||
|
|
|
@ -1,8 +1,6 @@
|
||||||
package handles
|
package handles
|
||||||
|
|
||||||
import (
|
import (
|
||||||
stdpath "path"
|
|
||||||
|
|
||||||
"github.com/alist-org/alist/v3/internal/aria2"
|
"github.com/alist-org/alist/v3/internal/aria2"
|
||||||
"github.com/alist-org/alist/v3/internal/conf"
|
"github.com/alist-org/alist/v3/internal/conf"
|
||||||
"github.com/alist-org/alist/v3/internal/db"
|
"github.com/alist-org/alist/v3/internal/db"
|
||||||
|
@ -58,9 +56,13 @@ func AddAria2(c *gin.Context) {
|
||||||
common.ErrorResp(c, err, 400)
|
common.ErrorResp(c, err, 400)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
req.Path = stdpath.Join(user.BasePath, req.Path)
|
reqPath, err := user.JoinPath(req.Path)
|
||||||
|
if err != nil {
|
||||||
|
common.ErrorResp(c, err, 403)
|
||||||
|
return
|
||||||
|
}
|
||||||
for _, url := range req.Urls {
|
for _, url := range req.Urls {
|
||||||
err := aria2.AddURI(c, url, req.Path)
|
err := aria2.AddURI(c, url, reqPath)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
common.ErrorResp(c, err, 500)
|
common.ErrorResp(c, err, 500)
|
||||||
return
|
return
|
||||||
|
|
|
@ -26,25 +26,29 @@ func FsMkdir(c *gin.Context) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
user := c.MustGet("user").(*model.User)
|
user := c.MustGet("user").(*model.User)
|
||||||
req.Path = stdpath.Join(user.BasePath, req.Path)
|
reqPath, err := user.JoinPath(req.Path)
|
||||||
|
if err != nil {
|
||||||
|
common.ErrorResp(c, err, 403)
|
||||||
|
return
|
||||||
|
}
|
||||||
if !user.CanWrite() {
|
if !user.CanWrite() {
|
||||||
meta, err := db.GetNearestMeta(stdpath.Dir(req.Path))
|
meta, err := db.GetNearestMeta(stdpath.Dir(reqPath))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
if !errors.Is(errors.Cause(err), errs.MetaNotFound) {
|
if !errors.Is(errors.Cause(err), errs.MetaNotFound) {
|
||||||
common.ErrorResp(c, err, 500, true)
|
common.ErrorResp(c, err, 500, true)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if !common.CanWrite(meta, req.Path) {
|
if !common.CanWrite(meta, reqPath) {
|
||||||
common.ErrorResp(c, errs.PermissionDenied, 403)
|
common.ErrorResp(c, errs.PermissionDenied, 403)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if err := fs.MakeDir(c, req.Path); err != nil {
|
if err := fs.MakeDir(c, reqPath); err != nil {
|
||||||
common.ErrorResp(c, err, 500)
|
common.ErrorResp(c, err, 500)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
fs.ClearCache(stdpath.Dir(req.Path))
|
fs.ClearCache(stdpath.Dir(reqPath))
|
||||||
common.SuccessResp(c)
|
common.SuccessResp(c)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -69,17 +73,25 @@ func FsMove(c *gin.Context) {
|
||||||
common.ErrorResp(c, errs.PermissionDenied, 403)
|
common.ErrorResp(c, errs.PermissionDenied, 403)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
req.SrcDir = stdpath.Join(user.BasePath, req.SrcDir)
|
srcDir, err := user.JoinPath(req.SrcDir)
|
||||||
req.DstDir = stdpath.Join(user.BasePath, req.DstDir)
|
if err != nil {
|
||||||
|
common.ErrorResp(c, err, 403)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
dstDir, err := user.JoinPath(req.DstDir)
|
||||||
|
if err != nil {
|
||||||
|
common.ErrorResp(c, err, 403)
|
||||||
|
return
|
||||||
|
}
|
||||||
for _, name := range req.Names {
|
for _, name := range req.Names {
|
||||||
err := fs.Move(c, stdpath.Join(req.SrcDir, name), req.DstDir)
|
err := fs.Move(c, stdpath.Join(srcDir, name), dstDir)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
common.ErrorResp(c, err, 500)
|
common.ErrorResp(c, err, 500)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
fs.ClearCache(req.SrcDir)
|
fs.ClearCache(srcDir)
|
||||||
fs.ClearCache(req.DstDir)
|
fs.ClearCache(dstDir)
|
||||||
common.SuccessResp(c)
|
common.SuccessResp(c)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -98,11 +110,19 @@ func FsCopy(c *gin.Context) {
|
||||||
common.ErrorResp(c, errs.PermissionDenied, 403)
|
common.ErrorResp(c, errs.PermissionDenied, 403)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
req.SrcDir = stdpath.Join(user.BasePath, req.SrcDir)
|
srcDir, err := user.JoinPath(req.SrcDir)
|
||||||
req.DstDir = stdpath.Join(user.BasePath, req.DstDir)
|
if err != nil {
|
||||||
|
common.ErrorResp(c, err, 403)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
dstDir, err := user.JoinPath(req.DstDir)
|
||||||
|
if err != nil {
|
||||||
|
common.ErrorResp(c, err, 403)
|
||||||
|
return
|
||||||
|
}
|
||||||
var addedTask []string
|
var addedTask []string
|
||||||
for _, name := range req.Names {
|
for _, name := range req.Names {
|
||||||
ok, err := fs.Copy(c, stdpath.Join(req.SrcDir, name), req.DstDir)
|
ok, err := fs.Copy(c, stdpath.Join(srcDir, name), dstDir)
|
||||||
if ok {
|
if ok {
|
||||||
addedTask = append(addedTask, name)
|
addedTask = append(addedTask, name)
|
||||||
}
|
}
|
||||||
|
@ -112,7 +132,7 @@ func FsCopy(c *gin.Context) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if len(req.Names) != len(addedTask) {
|
if len(req.Names) != len(addedTask) {
|
||||||
fs.ClearCache(req.DstDir)
|
fs.ClearCache(dstDir)
|
||||||
}
|
}
|
||||||
if len(addedTask) > 0 {
|
if len(addedTask) > 0 {
|
||||||
common.SuccessResp(c, fmt.Sprintf("Added %d tasks", len(addedTask)))
|
common.SuccessResp(c, fmt.Sprintf("Added %d tasks", len(addedTask)))
|
||||||
|
@ -137,12 +157,16 @@ func FsRename(c *gin.Context) {
|
||||||
common.ErrorResp(c, errs.PermissionDenied, 403)
|
common.ErrorResp(c, errs.PermissionDenied, 403)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
req.Path = stdpath.Join(user.BasePath, req.Path)
|
reqPath, err := user.JoinPath(req.Path)
|
||||||
if err := fs.Rename(c, req.Path, req.Name); err != nil {
|
if err != nil {
|
||||||
|
common.ErrorResp(c, err, 403)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if err := fs.Rename(c, reqPath, req.Name); err != nil {
|
||||||
common.ErrorResp(c, err, 500)
|
common.ErrorResp(c, err, 500)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
fs.ClearCache(stdpath.Dir(req.Path))
|
fs.ClearCache(stdpath.Dir(reqPath))
|
||||||
common.SuccessResp(c)
|
common.SuccessResp(c)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -166,9 +190,13 @@ func FsRemove(c *gin.Context) {
|
||||||
common.ErrorResp(c, errs.PermissionDenied, 403)
|
common.ErrorResp(c, errs.PermissionDenied, 403)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
req.Dir = stdpath.Join(user.BasePath, req.Dir)
|
reqDir, err := user.JoinPath(req.Dir)
|
||||||
|
if err != nil {
|
||||||
|
common.ErrorResp(c, err, 403)
|
||||||
|
return
|
||||||
|
}
|
||||||
for _, name := range req.Names {
|
for _, name := range req.Names {
|
||||||
err := fs.Remove(c, stdpath.Join(req.Dir, name))
|
err := fs.Remove(c, stdpath.Join(reqDir, name))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
common.ErrorResp(c, err, 500)
|
common.ErrorResp(c, err, 500)
|
||||||
return
|
return
|
||||||
|
@ -185,8 +213,10 @@ func Link(c *gin.Context) {
|
||||||
common.ErrorResp(c, err, 400)
|
common.ErrorResp(c, err, 400)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
user := c.MustGet("user").(*model.User)
|
//user := c.MustGet("user").(*model.User)
|
||||||
rawPath := stdpath.Join(user.BasePath, req.Path)
|
//rawPath := stdpath.Join(user.BasePath, req.Path)
|
||||||
|
// why need not join base_path? because it's always the full path
|
||||||
|
rawPath := req.Path
|
||||||
storage, err := fs.GetStorage(rawPath)
|
storage, err := fs.GetStorage(rawPath)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
common.ErrorResp(c, err, 500)
|
common.ErrorResp(c, err, 500)
|
||||||
|
|
|
@ -56,8 +56,12 @@ func FsList(c *gin.Context) {
|
||||||
}
|
}
|
||||||
req.Validate()
|
req.Validate()
|
||||||
user := c.MustGet("user").(*model.User)
|
user := c.MustGet("user").(*model.User)
|
||||||
req.Path = stdpath.Join(user.BasePath, req.Path)
|
reqPath, err := user.JoinPath(req.Path)
|
||||||
meta, err := db.GetNearestMeta(req.Path)
|
if err != nil {
|
||||||
|
common.ErrorResp(c, err, 403)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
meta, err := db.GetNearestMeta(reqPath)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
if !errors.Is(errors.Cause(err), errs.MetaNotFound) {
|
if !errors.Is(errors.Cause(err), errs.MetaNotFound) {
|
||||||
common.ErrorResp(c, err, 500, true)
|
common.ErrorResp(c, err, 500, true)
|
||||||
|
@ -65,30 +69,30 @@ func FsList(c *gin.Context) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
c.Set("meta", meta)
|
c.Set("meta", meta)
|
||||||
if !common.CanAccess(user, meta, req.Path, req.Password) {
|
if !common.CanAccess(user, meta, reqPath, req.Password) {
|
||||||
common.ErrorStrResp(c, "password is incorrect", 403)
|
common.ErrorStrResp(c, "password is incorrect", 403)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
if !user.CanWrite() && !common.CanWrite(meta, req.Path) && req.Refresh {
|
if !user.CanWrite() && !common.CanWrite(meta, reqPath) && req.Refresh {
|
||||||
common.ErrorStrResp(c, "Refresh without permission", 403)
|
common.ErrorStrResp(c, "Refresh without permission", 403)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
objs, err := fs.List(c, req.Path, req.Refresh)
|
objs, err := fs.List(c, reqPath, req.Refresh)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
common.ErrorResp(c, err, 500)
|
common.ErrorResp(c, err, 500)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
total, objs := pagination(objs, &req.PageReq)
|
total, objs := pagination(objs, &req.PageReq)
|
||||||
provider := "unknown"
|
provider := "unknown"
|
||||||
storage, err := fs.GetStorage(req.Path)
|
storage, err := fs.GetStorage(reqPath)
|
||||||
if err == nil {
|
if err == nil {
|
||||||
provider = storage.GetStorage().Driver
|
provider = storage.GetStorage().Driver
|
||||||
}
|
}
|
||||||
common.SuccessResp(c, FsListResp{
|
common.SuccessResp(c, FsListResp{
|
||||||
Content: toObjsResp(objs, req.Path, isEncrypt(meta, req.Path)),
|
Content: toObjsResp(objs, reqPath, isEncrypt(meta, reqPath)),
|
||||||
Total: int64(total),
|
Total: int64(total),
|
||||||
Readme: getReadme(meta, req.Path),
|
Readme: getReadme(meta, reqPath),
|
||||||
Write: user.CanWrite() || common.CanWrite(meta, req.Path),
|
Write: user.CanWrite() || common.CanWrite(meta, reqPath),
|
||||||
Provider: provider,
|
Provider: provider,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
@ -100,15 +104,21 @@ func FsDirs(c *gin.Context) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
user := c.MustGet("user").(*model.User)
|
user := c.MustGet("user").(*model.User)
|
||||||
|
var reqPath string
|
||||||
if req.ForceRoot {
|
if req.ForceRoot {
|
||||||
if !user.IsAdmin() {
|
if !user.IsAdmin() {
|
||||||
common.ErrorStrResp(c, "Permission denied", 403)
|
common.ErrorStrResp(c, "Permission denied", 403)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
req.Path = stdpath.Join(user.BasePath, req.Path)
|
tmp, err := user.JoinPath(req.Path)
|
||||||
|
if err != nil {
|
||||||
|
common.ErrorResp(c, err, 403)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
reqPath = tmp
|
||||||
}
|
}
|
||||||
meta, err := db.GetNearestMeta(req.Path)
|
meta, err := db.GetNearestMeta(reqPath)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
if !errors.Is(errors.Cause(err), errs.MetaNotFound) {
|
if !errors.Is(errors.Cause(err), errs.MetaNotFound) {
|
||||||
common.ErrorResp(c, err, 500, true)
|
common.ErrorResp(c, err, 500, true)
|
||||||
|
@ -116,11 +126,11 @@ func FsDirs(c *gin.Context) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
c.Set("meta", meta)
|
c.Set("meta", meta)
|
||||||
if !common.CanAccess(user, meta, req.Path, req.Password) {
|
if !common.CanAccess(user, meta, reqPath, req.Password) {
|
||||||
common.ErrorStrResp(c, "password is incorrect", 403)
|
common.ErrorStrResp(c, "password is incorrect", 403)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
objs, err := fs.List(c, req.Path)
|
objs, err := fs.List(c, reqPath)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
common.ErrorResp(c, err, 500)
|
common.ErrorResp(c, err, 500)
|
||||||
return
|
return
|
||||||
|
@ -218,8 +228,12 @@ func FsGet(c *gin.Context) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
user := c.MustGet("user").(*model.User)
|
user := c.MustGet("user").(*model.User)
|
||||||
req.Path = stdpath.Join(user.BasePath, req.Path)
|
reqPath, err := user.JoinPath(req.Path)
|
||||||
meta, err := db.GetNearestMeta(req.Path)
|
if err != nil {
|
||||||
|
common.ErrorResp(c, err, 403)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
meta, err := db.GetNearestMeta(reqPath)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
if !errors.Is(errors.Cause(err), errs.MetaNotFound) {
|
if !errors.Is(errors.Cause(err), errs.MetaNotFound) {
|
||||||
common.ErrorResp(c, err, 500)
|
common.ErrorResp(c, err, 500)
|
||||||
|
@ -227,18 +241,18 @@ func FsGet(c *gin.Context) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
c.Set("meta", meta)
|
c.Set("meta", meta)
|
||||||
if !common.CanAccess(user, meta, req.Path, req.Password) {
|
if !common.CanAccess(user, meta, reqPath, req.Password) {
|
||||||
common.ErrorStrResp(c, "password is incorrect", 403)
|
common.ErrorStrResp(c, "password is incorrect", 403)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
obj, err := fs.Get(c, req.Path)
|
obj, err := fs.Get(c, reqPath)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
common.ErrorResp(c, err, 500)
|
common.ErrorResp(c, err, 500)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
var rawURL string
|
var rawURL string
|
||||||
|
|
||||||
storage, err := fs.GetStorage(req.Path)
|
storage, err := fs.GetStorage(reqPath)
|
||||||
provider := "unknown"
|
provider := "unknown"
|
||||||
if err == nil {
|
if err == nil {
|
||||||
provider = storage.Config().Name
|
provider = storage.Config().Name
|
||||||
|
@ -252,13 +266,13 @@ func FsGet(c *gin.Context) {
|
||||||
if storage.GetStorage().DownProxyUrl != "" {
|
if storage.GetStorage().DownProxyUrl != "" {
|
||||||
rawURL = fmt.Sprintf("%s%s?sign=%s",
|
rawURL = fmt.Sprintf("%s%s?sign=%s",
|
||||||
strings.Split(storage.GetStorage().DownProxyUrl, "\n")[0],
|
strings.Split(storage.GetStorage().DownProxyUrl, "\n")[0],
|
||||||
utils.EncodePath(req.Path, true),
|
utils.EncodePath(reqPath, true),
|
||||||
sign.Sign(req.Path))
|
sign.Sign(reqPath))
|
||||||
} else {
|
} else {
|
||||||
rawURL = fmt.Sprintf("%s/p%s?sign=%s",
|
rawURL = fmt.Sprintf("%s/p%s?sign=%s",
|
||||||
common.GetApiUrl(c.Request),
|
common.GetApiUrl(c.Request),
|
||||||
utils.EncodePath(req.Path, true),
|
utils.EncodePath(reqPath, true),
|
||||||
sign.Sign(req.Path))
|
sign.Sign(reqPath))
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
// file have raw url
|
// file have raw url
|
||||||
|
@ -266,7 +280,7 @@ func FsGet(c *gin.Context) {
|
||||||
rawURL = u.URL()
|
rawURL = u.URL()
|
||||||
} else {
|
} else {
|
||||||
// if storage is not proxy, use raw url by fs.Link
|
// if storage is not proxy, use raw url by fs.Link
|
||||||
link, _, err := fs.Link(c, req.Path, model.LinkArgs{IP: c.ClientIP(), Header: c.Request.Header})
|
link, _, err := fs.Link(c, reqPath, model.LinkArgs{IP: c.ClientIP(), Header: c.Request.Header})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
common.ErrorResp(c, err, 500)
|
common.ErrorResp(c, err, 500)
|
||||||
return
|
return
|
||||||
|
@ -276,7 +290,7 @@ func FsGet(c *gin.Context) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
var related []model.Obj
|
var related []model.Obj
|
||||||
parentPath := stdpath.Dir(req.Path)
|
parentPath := stdpath.Dir(reqPath)
|
||||||
sameLevelFiles, err := fs.List(c, parentPath)
|
sameLevelFiles, err := fs.List(c, parentPath)
|
||||||
if err == nil {
|
if err == nil {
|
||||||
related = filterRelated(sameLevelFiles, obj)
|
related = filterRelated(sameLevelFiles, obj)
|
||||||
|
@ -288,11 +302,11 @@ func FsGet(c *gin.Context) {
|
||||||
Size: obj.GetSize(),
|
Size: obj.GetSize(),
|
||||||
IsDir: obj.IsDir(),
|
IsDir: obj.IsDir(),
|
||||||
Modified: obj.ModTime(),
|
Modified: obj.ModTime(),
|
||||||
Sign: common.Sign(obj, parentPath, isEncrypt(meta, req.Path)),
|
Sign: common.Sign(obj, parentPath, isEncrypt(meta, reqPath)),
|
||||||
Type: utils.GetFileType(obj.GetName()),
|
Type: utils.GetFileType(obj.GetName()),
|
||||||
},
|
},
|
||||||
RawURL: rawURL,
|
RawURL: rawURL,
|
||||||
Readme: getReadme(meta, req.Path),
|
Readme: getReadme(meta, reqPath),
|
||||||
Provider: provider,
|
Provider: provider,
|
||||||
Related: toObjsResp(related, parentPath, isEncrypt(parentMeta, parentPath)),
|
Related: toObjsResp(related, parentPath, isEncrypt(parentMeta, parentPath)),
|
||||||
})
|
})
|
||||||
|
@ -324,7 +338,12 @@ func FsOther(c *gin.Context) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
user := c.MustGet("user").(*model.User)
|
user := c.MustGet("user").(*model.User)
|
||||||
req.Path = stdpath.Join(user.BasePath, req.Path)
|
var err error
|
||||||
|
req.Path, err = user.JoinPath(req.Path)
|
||||||
|
if err != nil {
|
||||||
|
common.ErrorResp(c, err, 403)
|
||||||
|
return
|
||||||
|
}
|
||||||
meta, err := db.GetNearestMeta(req.Path)
|
meta, err := db.GetNearestMeta(req.Path)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
if !errors.Is(errors.Cause(err), errs.MetaNotFound) {
|
if !errors.Is(errors.Cause(err), errs.MetaNotFound) {
|
||||||
|
|
|
@ -21,8 +21,11 @@ func FsStream(c *gin.Context) {
|
||||||
}
|
}
|
||||||
asTask := c.GetHeader("As-Task") == "true"
|
asTask := c.GetHeader("As-Task") == "true"
|
||||||
user := c.MustGet("user").(*model.User)
|
user := c.MustGet("user").(*model.User)
|
||||||
path = stdpath.Join(user.BasePath, path)
|
path, err = user.JoinPath(path)
|
||||||
|
if err != nil {
|
||||||
|
common.ErrorResp(c, err, 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)
|
||||||
|
@ -61,8 +64,11 @@ func FsForm(c *gin.Context) {
|
||||||
}
|
}
|
||||||
asTask := c.GetHeader("As-Task") == "true"
|
asTask := c.GetHeader("As-Task") == "true"
|
||||||
user := c.MustGet("user").(*model.User)
|
user := c.MustGet("user").(*model.User)
|
||||||
path = stdpath.Join(user.BasePath, path)
|
path, err = user.JoinPath(path)
|
||||||
|
if err != nil {
|
||||||
|
common.ErrorResp(c, err, 403)
|
||||||
|
return
|
||||||
|
}
|
||||||
storage, err := fs.GetStorage(path)
|
storage, err := fs.GetStorage(path)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
common.ErrorResp(c, err, 400)
|
common.ErrorResp(c, err, 400)
|
||||||
|
|
|
@ -22,7 +22,11 @@ func FsUp(c *gin.Context) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
user := c.MustGet("user").(*model.User)
|
user := c.MustGet("user").(*model.User)
|
||||||
path = stdpath.Join(user.BasePath, path)
|
path, err = user.JoinPath(path)
|
||||||
|
if err != nil {
|
||||||
|
common.ErrorResp(c, err, 403)
|
||||||
|
return
|
||||||
|
}
|
||||||
meta, err := db.GetNearestMeta(stdpath.Dir(path))
|
meta, err := db.GetNearestMeta(stdpath.Dir(path))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
if !errors.Is(errors.Cause(err), errs.MetaNotFound) {
|
if !errors.Is(errors.Cause(err), errs.MetaNotFound) {
|
||||||
|
|
|
@ -178,7 +178,10 @@ func (h *Handler) handleOptions(w http.ResponseWriter, r *http.Request) (status
|
||||||
}
|
}
|
||||||
ctx := r.Context()
|
ctx := r.Context()
|
||||||
user := ctx.Value("user").(*model.User)
|
user := ctx.Value("user").(*model.User)
|
||||||
reqPath = path.Join(user.BasePath, reqPath)
|
reqPath, err = user.JoinPath(reqPath)
|
||||||
|
if err != nil {
|
||||||
|
return 403, err
|
||||||
|
}
|
||||||
allow := "OPTIONS, LOCK, PUT, MKCOL"
|
allow := "OPTIONS, LOCK, PUT, MKCOL"
|
||||||
if fi, err := fs.Get(ctx, reqPath); err == nil {
|
if fi, err := fs.Get(ctx, reqPath); err == nil {
|
||||||
if fi.IsDir() {
|
if fi.IsDir() {
|
||||||
|
@ -203,7 +206,10 @@ func (h *Handler) handleGetHeadPost(w http.ResponseWriter, r *http.Request) (sta
|
||||||
// TODO: check locks for read-only access??
|
// TODO: check locks for read-only access??
|
||||||
ctx := r.Context()
|
ctx := r.Context()
|
||||||
user := ctx.Value("user").(*model.User)
|
user := ctx.Value("user").(*model.User)
|
||||||
reqPath = path.Join(user.BasePath, reqPath)
|
reqPath, err = user.JoinPath(reqPath)
|
||||||
|
if err != nil {
|
||||||
|
return 403, err
|
||||||
|
}
|
||||||
fi, err := fs.Get(ctx, reqPath)
|
fi, err := fs.Get(ctx, reqPath)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return http.StatusNotFound, err
|
return http.StatusNotFound, err
|
||||||
|
@ -258,7 +264,10 @@ func (h *Handler) handleDelete(w http.ResponseWriter, r *http.Request) (status i
|
||||||
|
|
||||||
ctx := r.Context()
|
ctx := r.Context()
|
||||||
user := ctx.Value("user").(*model.User)
|
user := ctx.Value("user").(*model.User)
|
||||||
reqPath = path.Join(user.BasePath, reqPath)
|
reqPath, err = user.JoinPath(reqPath)
|
||||||
|
if err != nil {
|
||||||
|
return 403, err
|
||||||
|
}
|
||||||
// TODO: return MultiStatus where appropriate.
|
// TODO: return MultiStatus where appropriate.
|
||||||
|
|
||||||
// "godoc os RemoveAll" says that "If the path does not exist, RemoveAll
|
// "godoc os RemoveAll" says that "If the path does not exist, RemoveAll
|
||||||
|
@ -291,7 +300,10 @@ func (h *Handler) handlePut(w http.ResponseWriter, r *http.Request) (status int,
|
||||||
// comments in http.checkEtag.
|
// comments in http.checkEtag.
|
||||||
ctx := r.Context()
|
ctx := r.Context()
|
||||||
user := ctx.Value("user").(*model.User)
|
user := ctx.Value("user").(*model.User)
|
||||||
reqPath = path.Join(user.BasePath, reqPath)
|
reqPath, err = user.JoinPath(reqPath)
|
||||||
|
if err != nil {
|
||||||
|
return 403, err
|
||||||
|
}
|
||||||
obj := model.Object{
|
obj := model.Object{
|
||||||
Name: path.Base(reqPath),
|
Name: path.Base(reqPath),
|
||||||
Size: r.ContentLength,
|
Size: r.ContentLength,
|
||||||
|
@ -337,7 +349,10 @@ func (h *Handler) handleMkcol(w http.ResponseWriter, r *http.Request) (status in
|
||||||
|
|
||||||
ctx := r.Context()
|
ctx := r.Context()
|
||||||
user := ctx.Value("user").(*model.User)
|
user := ctx.Value("user").(*model.User)
|
||||||
reqPath = path.Join(user.BasePath, reqPath)
|
reqPath, err = user.JoinPath(reqPath)
|
||||||
|
if err != nil {
|
||||||
|
return 403, err
|
||||||
|
}
|
||||||
|
|
||||||
if r.ContentLength > 0 {
|
if r.ContentLength > 0 {
|
||||||
return http.StatusUnsupportedMediaType, nil
|
return http.StatusUnsupportedMediaType, nil
|
||||||
|
@ -384,8 +399,14 @@ func (h *Handler) handleCopyMove(w http.ResponseWriter, r *http.Request) (status
|
||||||
|
|
||||||
ctx := r.Context()
|
ctx := r.Context()
|
||||||
user := ctx.Value("user").(*model.User)
|
user := ctx.Value("user").(*model.User)
|
||||||
src = path.Join(user.BasePath, src)
|
src, err = user.JoinPath(src)
|
||||||
dst = path.Join(user.BasePath, dst)
|
if err != nil {
|
||||||
|
return 403, err
|
||||||
|
}
|
||||||
|
dst, err = user.JoinPath(dst)
|
||||||
|
if err != nil {
|
||||||
|
return 403, err
|
||||||
|
}
|
||||||
|
|
||||||
if r.Method == "COPY" {
|
if r.Method == "COPY" {
|
||||||
// Section 7.5.1 says that a COPY only needs to lock the destination,
|
// Section 7.5.1 says that a COPY only needs to lock the destination,
|
||||||
|
@ -476,7 +497,10 @@ func (h *Handler) handleLock(w http.ResponseWriter, r *http.Request) (retStatus
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
reqPath, status, err := h.stripPrefix(r.URL.Path)
|
reqPath, status, err := h.stripPrefix(r.URL.Path)
|
||||||
reqPath = path.Join(user.BasePath, reqPath)
|
reqPath, err = user.JoinPath(reqPath)
|
||||||
|
if err != nil {
|
||||||
|
return 403, err
|
||||||
|
}
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return status, err
|
return status, err
|
||||||
}
|
}
|
||||||
|
@ -557,7 +581,10 @@ func (h *Handler) handlePropfind(w http.ResponseWriter, r *http.Request) (status
|
||||||
}
|
}
|
||||||
ctx := r.Context()
|
ctx := r.Context()
|
||||||
user := ctx.Value("user").(*model.User)
|
user := ctx.Value("user").(*model.User)
|
||||||
reqPath = path.Join(user.BasePath, reqPath)
|
reqPath, err = user.JoinPath(reqPath)
|
||||||
|
if err != nil {
|
||||||
|
return 403, err
|
||||||
|
}
|
||||||
fi, err := fs.Get(ctx, reqPath)
|
fi, err := fs.Get(ctx, reqPath)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
if errs.IsObjectNotFound(err) {
|
if errs.IsObjectNotFound(err) {
|
||||||
|
@ -633,8 +660,10 @@ func (h *Handler) handleProppatch(w http.ResponseWriter, r *http.Request) (statu
|
||||||
|
|
||||||
ctx := r.Context()
|
ctx := r.Context()
|
||||||
user := ctx.Value("user").(*model.User)
|
user := ctx.Value("user").(*model.User)
|
||||||
reqPath = path.Join(user.BasePath, reqPath)
|
reqPath, err = user.JoinPath(reqPath)
|
||||||
|
if err != nil {
|
||||||
|
return 403, err
|
||||||
|
}
|
||||||
if _, err := fs.Get(ctx, reqPath); err != nil {
|
if _, err := fs.Get(ctx, reqPath); err != nil {
|
||||||
if errs.IsObjectNotFound(err) {
|
if errs.IsObjectNotFound(err) {
|
||||||
return http.StatusNotFound, err
|
return http.StatusNotFound, err
|
||||||
|
|
Loading…
Reference in New Issue