diff --git a/model/meta.go b/model/meta.go index d660a779..fb3f4d3a 100644 --- a/model/meta.go +++ b/model/meta.go @@ -10,6 +10,7 @@ type Meta struct { Path string `json:"path" gorm:"unique" binding:"required"` Password string `json:"password"` Hide string `json:"hide"` + Upload bool `json:"upload"` } func GetMetaByPath(path string) (*Meta, error) { diff --git a/server/common/common.go b/server/common/common.go index c9c21c21..d8400c4d 100644 --- a/server/common/common.go +++ b/server/common/common.go @@ -1,6 +1,7 @@ package common import ( + "errors" "fmt" "github.com/Xhofe/alist/drivers/base" "github.com/Xhofe/alist/model" @@ -29,6 +30,9 @@ func ParsePath(rawPath string) (*model.Account, string, base.Driver, error) { path = rawPath break default: + if path == "/" { + return nil, "", nil, errors.New("can't operate root of multiple accounts") + } paths := strings.Split(rawPath, "/") path = "/" + strings.Join(paths[2:], "/") name = paths[1] diff --git a/server/controllers/file.go b/server/controllers/file.go new file mode 100644 index 00000000..4ade2e5b --- /dev/null +++ b/server/controllers/file.go @@ -0,0 +1,57 @@ +package controllers + +import ( + "errors" + "github.com/Xhofe/alist/conf" + "github.com/Xhofe/alist/model" + "github.com/Xhofe/alist/server/common" + "github.com/Xhofe/alist/utils" + "github.com/gin-gonic/gin" +) + +func UploadFile(c *gin.Context) { + path := c.PostForm("path") + path = utils.ParsePath(path) + token := c.GetHeader("Authorization") + if token != conf.Token { + password := c.PostForm("password") + meta, _ := model.GetMetaByPath(path) + if meta == nil || !meta.Upload { + common.ErrorResp(c, errors.New("not allow upload"), 403) + return + } + if meta.Password != "" && meta.Password != password { + common.ErrorResp(c, errors.New("wrong password"), 403) + return + } + } + file, err := c.FormFile("file") + if err != nil { + common.ErrorResp(c, err, 400) + } + open, err := file.Open() + defer func() { + _ = open.Close() + }() + if err != nil { + return + } + account, path_, driver, err := common.ParsePath(path) + if err != nil { + common.ErrorResp(c, err, 500) + return + } + fileStream := model.FileStream{ + File: open, + Size: uint64(file.Size), + ParentPath: path_, + Name: file.Filename, + MIMEType: c.GetHeader("Content-Type"), + } + err = driver.Upload(&fileStream, account) + if err != nil { + common.ErrorResp(c, err, 500) + return + } + common.SuccessResp(c) +} diff --git a/server/controllers/path.go b/server/controllers/path.go index 0343262f..72a6eae1 100644 --- a/server/controllers/path.go +++ b/server/controllers/path.go @@ -12,8 +12,8 @@ import ( "strings" ) -func Hide(files []model.File, path string) []model.File { - meta, _ := model.GetMetaByPath(path) +func Hide(meta *model.Meta, files []model.File, path string) []model.File { + //meta, _ := model.GetMetaByPath(path) if meta != nil && meta.Hide != "" { tmpFiles := make([]model.File, 0) hideFiles := strings.Split(meta.Hide, ",") @@ -27,29 +27,41 @@ func Hide(files []model.File, path string) []model.File { return files } +type Meta struct { + Driver string `json:"driver"` + Upload bool `json:"upload"` +} + type PathResp struct { - Type string `json:"type"` - Driver string `json:"driver"` - Files []model.File `json:"files"` + Type string `json:"type"` + Meta Meta `json:"meta"` + Files []model.File `json:"files"` } func Path(c *gin.Context) { reqV, _ := c.Get("req") req := reqV.(common.PathReq) + meta, _ := model.GetMetaByPath(req.Path) + upload := false + if meta != nil && meta.Upload { + upload = true + } if model.AccountsCount() > 1 && req.Path == "/" { files, err := model.GetAccountFiles() if err != nil { common.ErrorResp(c, err, 500) return } - files = Hide(files, req.Path) + files = Hide(meta, files, req.Path) c.JSON(200, common.Resp{ Code: 200, Message: "success", Data: PathResp{ - Type: "folder", - Driver: "root", - Files: files, + Type: "folder", + Meta: Meta{ + Driver: "root", + }, + Files: files, }, }) return @@ -84,13 +96,15 @@ func Path(c *gin.Context) { Code: 200, Message: "success", Data: PathResp{ - Type: "file", - Driver: driver.Config().Name, - Files: []model.File{*file}, + Type: "file", + Meta: Meta{ + Driver: driver.Config().Name, + }, + Files: []model.File{*file}, }, }) } else { - files = Hide(files, req.Path) + files = Hide(meta, files, req.Path) if driver.Config().LocalSort { model.SortFiles(files, account) } @@ -98,9 +112,12 @@ func Path(c *gin.Context) { Code: 200, Message: "success", Data: PathResp{ - Type: "folder", - Driver: "root", - Files: files, + Type: "folder", + Meta: Meta{ + Driver: driver.Config().Name, + Upload: upload, + }, + Files: files, }, }) } diff --git a/server/router.go b/server/router.go index 9645cd56..c063c53a 100644 --- a/server/router.go +++ b/server/router.go @@ -23,6 +23,7 @@ func InitApiRouter(r *gin.Engine) { path.POST("/preview", controllers.Preview) //path.POST("/link",middlewares.Auth, controllers.Link) + public.POST("/upload", controllers.UploadFile) public.GET("/settings", controllers.GetSettingsPublic) }