diff --git a/server/check.go b/server/common/check.go similarity index 64% rename from server/check.go rename to server/common/check.go index c230fd93..e8f7bfad 100644 --- a/server/check.go +++ b/server/common/check.go @@ -1,45 +1,17 @@ -package server +package common import ( - "fmt" "github.com/Xhofe/alist/conf" "github.com/Xhofe/alist/model" "github.com/Xhofe/alist/utils" "github.com/gin-gonic/gin" log "github.com/sirupsen/logrus" - "gorm.io/gorm" ) -func Auth(c *gin.Context) { - token := c.GetHeader("Authorization") - password, err := model.GetSettingByKey("password") - if err != nil { - if err == gorm.ErrRecordNotFound { - ErrorResp(c, fmt.Errorf("password not set"), 400) - return - } - ErrorResp(c, err, 500) - return - } - if token != utils.GetMD5Encode(password.Value) { - ErrorResp(c, fmt.Errorf("wrong password"), 401) - return - } - c.Next() -} - func Login(c *gin.Context) { SuccessResp(c) } -func CheckAccount(c *gin.Context) { - if model.AccountsCount() == 0 { - ErrorResp(c, fmt.Errorf("no accounts,please add one first"), 1001) - return - } - c.Next() -} - func CheckParent(path string, password string) bool { meta, err := model.GetMetaByPath(path) if err == nil { diff --git a/server/common.go b/server/common/common.go similarity index 92% rename from server/common.go rename to server/common/common.go index 80ed4d69..c9c21c21 100644 --- a/server/common.go +++ b/server/common/common.go @@ -1,4 +1,4 @@ -package server +package common import ( "fmt" @@ -15,6 +15,11 @@ type Resp struct { Data interface{} `json:"data"` } +type PathReq struct { + Path string `json:"path"` + Password string `json:"password"` +} + func ParsePath(rawPath string) (*model.Account, string, base.Driver, error) { var path, name string switch model.AccountsCount() { diff --git a/server/account.go b/server/controllers/account.go similarity index 68% rename from server/account.go rename to server/controllers/account.go index 0b0216f0..cef514e5 100644 --- a/server/account.go +++ b/server/controllers/account.go @@ -1,9 +1,10 @@ -package server +package controllers import ( "fmt" "github.com/Xhofe/alist/drivers/base" "github.com/Xhofe/alist/model" + "github.com/Xhofe/alist/server/common" "github.com/gin-gonic/gin" log "github.com/sirupsen/logrus" "strconv" @@ -13,52 +14,52 @@ import ( func GetAccounts(c *gin.Context) { accounts, err := model.GetAccounts() if err != nil { - ErrorResp(c, err, 500) + common.ErrorResp(c, err, 500) return } - SuccessResp(c, accounts) + common.SuccessResp(c, accounts) } func CreateAccount(c *gin.Context) { var req model.Account if err := c.ShouldBind(&req); err != nil { - ErrorResp(c, err, 400) + common.ErrorResp(c, err, 400) return } driver, ok := base.GetDriver(req.Type) if !ok { - ErrorResp(c, fmt.Errorf("no [%s] driver", req.Type), 400) + common.ErrorResp(c, fmt.Errorf("no [%s] driver", req.Type), 400) return } now := time.Now() req.UpdatedAt = &now if err := model.CreateAccount(&req); err != nil { - ErrorResp(c, err, 500) + common.ErrorResp(c, err, 500) } else { log.Debugf("new account: %+v", req) err = driver.Save(&req, nil) if err != nil { - ErrorResp(c, err, 500) + common.ErrorResp(c, err, 500) return } - SuccessResp(c) + common.SuccessResp(c) } } func SaveAccount(c *gin.Context) { var req model.Account if err := c.ShouldBind(&req); err != nil { - ErrorResp(c, err, 400) + common.ErrorResp(c, err, 400) return } driver, ok := base.GetDriver(req.Type) if !ok { - ErrorResp(c, fmt.Errorf("no [%s] driver", req.Type), 400) + common.ErrorResp(c, fmt.Errorf("no [%s] driver", req.Type), 400) return } old, err := model.GetAccountById(req.ID) if err != nil { - ErrorResp(c, err, 400) + common.ErrorResp(c, err, 400) return } now := time.Now() @@ -67,15 +68,15 @@ func SaveAccount(c *gin.Context) { model.DeleteAccountFromMap(old.Name) } if err := model.SaveAccount(&req); err != nil { - ErrorResp(c, err, 500) + common.ErrorResp(c, err, 500) } else { log.Debugf("save account: %+v", req) err = driver.Save(&req, old) if err != nil { - ErrorResp(c, err, 500) + common.ErrorResp(c, err, 500) return } - SuccessResp(c) + common.SuccessResp(c) } } @@ -83,12 +84,12 @@ func DeleteAccount(c *gin.Context) { idStr := c.Query("id") id, err := strconv.Atoi(idStr) if err != nil { - ErrorResp(c, err, 400) + common.ErrorResp(c, err, 400) return } if err := model.DeleteAccount(uint(id)); err != nil { - ErrorResp(c, err, 500) + common.ErrorResp(c, err, 500) return } - SuccessResp(c) + common.SuccessResp(c) } diff --git a/server/cache.go b/server/controllers/cache.go similarity index 59% rename from server/cache.go rename to server/controllers/cache.go index cdff36c7..e1e5d1d3 100644 --- a/server/cache.go +++ b/server/controllers/cache.go @@ -1,15 +1,16 @@ -package server +package controllers import ( "github.com/Xhofe/alist/conf" + "github.com/Xhofe/alist/server/common" "github.com/gin-gonic/gin" ) func ClearCache(c *gin.Context) { err := conf.Cache.Clear(conf.Ctx) if err != nil { - ErrorResp(c, err, 500) + common.ErrorResp(c, err, 500) } else { - SuccessResp(c) + common.SuccessResp(c) } } diff --git a/server/down.go b/server/controllers/down.go similarity index 69% rename from server/down.go rename to server/controllers/down.go index b3250db7..1050bb5b 100644 --- a/server/down.go +++ b/server/controllers/down.go @@ -1,8 +1,9 @@ -package server +package controllers import ( "fmt" "github.com/Xhofe/alist/conf" + "github.com/Xhofe/alist/server/common" "github.com/Xhofe/alist/utils" "github.com/gin-gonic/gin" "github.com/go-resty/resty/v2" @@ -17,55 +18,40 @@ func Down(c *gin.Context) { rawPath := c.Param("path") rawPath = utils.ParsePath(rawPath) log.Debugf("down: %s", rawPath) - pw := c.Query("pw") - if !CheckDownLink(utils.Dir(rawPath), pw, utils.Base(rawPath)) { - ErrorResp(c, fmt.Errorf("wrong password"), 401) - return - } - account, path, driver, err := ParsePath(rawPath) + account, path, driver, err := common.ParsePath(rawPath) if err != nil { - ErrorResp(c, err, 500) + common.ErrorResp(c, err, 500) return } - if account.Type == "GoogleDrive" { + if driver.Config().OnlyProxy { Proxy(c) return } link, err := driver.Link(path, account) if err != nil { - ErrorResp(c, err, 500) - return - } - if account.Type == "Native" { - c.File(link) - return - } else { - c.Redirect(302, link) + common.ErrorResp(c, err, 500) return } + c.Redirect(302, link) + return } func Proxy(c *gin.Context) { rawPath := c.Param("path") rawPath = utils.ParsePath(rawPath) log.Debugf("proxy: %s", rawPath) - pw := c.Query("pw") - if !CheckDownLink(utils.Dir(rawPath), pw, utils.Base(rawPath)) { - ErrorResp(c, fmt.Errorf("wrong password"), 401) - return - } - account, path, driver, err := ParsePath(rawPath) + account, path, driver, err := common.ParsePath(rawPath) if err != nil { - ErrorResp(c, err, 500) + common.ErrorResp(c, err, 500) return } if !account.Proxy && utils.GetFileType(filepath.Ext(rawPath)) != conf.TEXT { - ErrorResp(c, fmt.Errorf("[%s] not allowed proxy", account.Name), 403) + common.ErrorResp(c, fmt.Errorf("[%s] not allowed proxy", account.Name), 403) return } link, err := driver.Link(path, account) if err != nil { - ErrorResp(c, err, 500) + common.ErrorResp(c, err, 500) return } if account.Type == "Native" { @@ -81,7 +67,7 @@ func Proxy(c *gin.Context) { w := c.Writer target, err := url.Parse(link) if err != nil { - ErrorResp(c, err, 500) + common.ErrorResp(c, err, 500) return } protocol := "http://" @@ -106,7 +92,7 @@ func init() { func Text(c *gin.Context, link string) { res, err := client.R().Get(link) if err != nil { - ErrorResp(c, err, 500) + common.ErrorResp(c, err, 500) return } text := res.String() @@ -115,7 +101,7 @@ func Text(c *gin.Context, link string) { if t != utils.UTF8 { body, err := utils.GbkToUtf8(res.Body()) if err != nil { - ErrorResp(c, err, 500) + common.ErrorResp(c, err, 500) return } text = string(body) diff --git a/server/driver.go b/server/controllers/driver.go similarity index 52% rename from server/driver.go rename to server/controllers/driver.go index b7a40c46..c01697c2 100644 --- a/server/driver.go +++ b/server/controllers/driver.go @@ -1,10 +1,11 @@ -package server +package controllers import ( "github.com/Xhofe/alist/drivers/base" + "github.com/Xhofe/alist/server/common" "github.com/gin-gonic/gin" ) func GetDrivers(c *gin.Context) { - SuccessResp(c, base.GetDrivers()) + common.SuccessResp(c, base.GetDrivers()) } \ No newline at end of file diff --git a/server/meta.go b/server/controllers/meta.go similarity index 68% rename from server/meta.go rename to server/controllers/meta.go index 0cb3f940..d14e8e9d 100644 --- a/server/meta.go +++ b/server/controllers/meta.go @@ -1,7 +1,8 @@ -package server +package controllers import ( "github.com/Xhofe/alist/model" + "github.com/Xhofe/alist/server/common" "github.com/Xhofe/alist/utils" "github.com/gin-gonic/gin" "strconv" @@ -10,37 +11,37 @@ import ( func GetMetas(c *gin.Context) { metas,err := model.GetMetas() if err != nil { - ErrorResp(c,err,500) + common.ErrorResp(c,err,500) return } - SuccessResp(c, metas) + common.SuccessResp(c, metas) } func CreateMeta(c *gin.Context) { var req model.Meta if err := c.ShouldBind(&req); err != nil { - ErrorResp(c, err, 400) + common.ErrorResp(c, err, 400) return } req.Path = utils.ParsePath(req.Path) if err := model.CreateMeta(req); err != nil { - ErrorResp(c, err, 500) + common.ErrorResp(c, err, 500) } else { - SuccessResp(c) + common.SuccessResp(c) } } func SaveMeta(c *gin.Context) { var req model.Meta if err := c.ShouldBind(&req); err != nil { - ErrorResp(c, err, 400) + common.ErrorResp(c, err, 400) return } req.Path = utils.ParsePath(req.Path) if err := model.SaveMeta(req); err != nil { - ErrorResp(c, err, 500) + common.ErrorResp(c, err, 500) } else { - SuccessResp(c) + common.SuccessResp(c) } } @@ -48,13 +49,13 @@ func DeleteMeta(c *gin.Context) { idStr := c.Query("id") id, err := strconv.Atoi(idStr) if err != nil { - ErrorResp(c, err, 400) + common.ErrorResp(c, err, 400) return } //path = utils.ParsePath(path) if err := model.DeleteMeta(uint(id)); err != nil { - ErrorResp(c, err, 500) + common.ErrorResp(c, err, 500) return } - SuccessResp(c) + common.SuccessResp(c) } diff --git a/server/path.go b/server/controllers/path.go similarity index 53% rename from server/path.go rename to server/controllers/path.go index d0977747..aec524f5 100644 --- a/server/path.go +++ b/server/controllers/path.go @@ -1,74 +1,52 @@ -package server +package controllers import ( "fmt" - "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" log "github.com/sirupsen/logrus" "strings" ) -type PathReq struct { - Path string `json:"path"` - Password string `json:"password"` -} - func Path(c *gin.Context) { - var req PathReq - if err := c.ShouldBind(&req); err != nil { - ErrorResp(c, err, 400) - return - } - req.Path = utils.ParsePath(req.Path) - log.Debugf("path: %s", req.Path) - meta, err := model.GetMetaByPath(req.Path) - if err == nil { - if meta.Password != "" && meta.Password != req.Password { - ErrorResp(c, fmt.Errorf("wrong password"), 401) - return - } - // TODO hide or ignore? - } else if conf.CheckParent { - if !CheckParent(utils.Dir(req.Path), req.Password) { - ErrorResp(c, fmt.Errorf("wrong password"), 401) - return - } - } + reqV,_ := c.Get("req") + req := reqV.(common.PathReq) if model.AccountsCount() > 1 && req.Path == "/" { files, err := model.GetAccountFiles() if err != nil { - ErrorResp(c, err, 500) + common.ErrorResp(c, err, 500) return } - c.JSON(200, Resp{ + c.JSON(200, common.Resp{ Code: 200, Message: "folder", Data: files, }) return } - account, path, driver, err := ParsePath(req.Path) + account, path, driver, err := common.ParsePath(req.Path) if err != nil { - ErrorResp(c, err, 500) + common.ErrorResp(c, err, 500) return } file, files, err := driver.Path(path, account) if err != nil { - ErrorResp(c, err, 500) + common.ErrorResp(c, err, 500) return } if file != nil { - if account.Type == "Native" { + if driver.Config().OnlyProxy { file.Url = fmt.Sprintf("//%s/d%s", c.Request.Host, req.Path) } - c.JSON(200, Resp{ + c.JSON(200, common.Resp{ Code: 200, Message: "file", Data: []*model.File{file}, }) } else { + meta, _ := model.GetMetaByPath(req.Path) if meta != nil && meta.Hide != "" { tmpFiles := make([]model.File, 0) hideFiles := strings.Split(meta.Hide, ",") @@ -79,7 +57,7 @@ func Path(c *gin.Context) { } files = tmpFiles } - c.JSON(200, Resp{ + c.JSON(200, common.Resp{ Code: 200, Message: "folder", Data: files, @@ -88,31 +66,28 @@ func Path(c *gin.Context) { } func Link(c *gin.Context) { - var req PathReq - if err := c.ShouldBind(&req); err != nil { - ErrorResp(c, err, 400) - return - } + reqV,_ := c.Get("req") + req := reqV.(common.PathReq) rawPath := req.Path rawPath = utils.ParsePath(rawPath) log.Debugf("link: %s", rawPath) - account, path, driver, err := ParsePath(rawPath) + account, path, driver, err := common.ParsePath(rawPath) if err != nil { - ErrorResp(c, err, 500) + common.ErrorResp(c, err, 500) return } link, err := driver.Link(path, account) if err != nil { - ErrorResp(c, err, 500) + common.ErrorResp(c, err, 500) return } - if account.Type == "Native" { - SuccessResp(c, gin.H{ + if driver.Config().OnlyProxy { + common.SuccessResp(c, gin.H{ "url": fmt.Sprintf("//%s/d%s", c.Request.Host, req.Path), }) return } else { - SuccessResp(c, gin.H{ + common.SuccessResp(c, gin.H{ "url": link, }) return @@ -120,23 +95,20 @@ func Link(c *gin.Context) { } func Preview(c *gin.Context) { - var req PathReq - if err := c.ShouldBind(&req); err != nil { - ErrorResp(c, err, 400) - return - } + reqV,_ := c.Get("req") + req := reqV.(common.PathReq) rawPath := req.Path rawPath = utils.ParsePath(rawPath) log.Debugf("preview: %s", rawPath) - account, path, driver, err := ParsePath(rawPath) + account, path, driver, err := common.ParsePath(rawPath) if err != nil { - ErrorResp(c, err, 500) + common.ErrorResp(c, err, 500) return } data, err := driver.Preview(path, account) if err != nil { - ErrorResp(c, err, 500) + common.ErrorResp(c, err, 500) } else { - SuccessResp(c, data) + common.SuccessResp(c, data) } } diff --git a/server/setting.go b/server/controllers/setting.go similarity index 64% rename from server/setting.go rename to server/controllers/setting.go index e4dba7f6..875ea5f7 100644 --- a/server/setting.go +++ b/server/controllers/setting.go @@ -1,38 +1,39 @@ -package server +package controllers import ( "github.com/Xhofe/alist/model" + "github.com/Xhofe/alist/server/common" "github.com/gin-gonic/gin" ) func SaveSettings(c *gin.Context) { var req []model.SettingItem if err := c.ShouldBind(&req); err != nil { - ErrorResp(c, err, 400) + common.ErrorResp(c, err, 400) return } if err := model.SaveSettings(req); err != nil { - ErrorResp(c, err, 500) + common.ErrorResp(c, err, 500) } else { model.LoadSettings() - SuccessResp(c) + common.SuccessResp(c) } } func GetSettings(c *gin.Context) { settings, err := model.GetSettings() if err != nil { - ErrorResp(c, err, 400) + common.ErrorResp(c, err, 400) return } - SuccessResp(c, settings) + common.SuccessResp(c, settings) } func GetSettingsPublic(c *gin.Context) { settings, err := model.GetSettingsPublic() if err != nil { - ErrorResp(c, err, 400) + common.ErrorResp(c, err, 400) return } - SuccessResp(c, settings) + common.SuccessResp(c, settings) } diff --git a/server/middlewares/account.go b/server/middlewares/account.go new file mode 100644 index 00000000..9a821b4b --- /dev/null +++ b/server/middlewares/account.go @@ -0,0 +1,16 @@ +package middlewares + +import ( + "fmt" + "github.com/Xhofe/alist/model" + "github.com/Xhofe/alist/server/common" + "github.com/gin-gonic/gin" +) + +func CheckAccount(c *gin.Context) { + if model.AccountsCount() == 0 { + common.ErrorResp(c, fmt.Errorf("no accounts,please add one first"), 1001) + return + } + c.Next() +} \ No newline at end of file diff --git a/server/middlewares/auth.go b/server/middlewares/auth.go new file mode 100644 index 00000000..1eec9764 --- /dev/null +++ b/server/middlewares/auth.go @@ -0,0 +1,28 @@ +package middlewares + +import ( + "fmt" + "github.com/Xhofe/alist/model" + "github.com/Xhofe/alist/server/common" + "github.com/Xhofe/alist/utils" + "github.com/gin-gonic/gin" + "gorm.io/gorm" +) + +func Auth(c *gin.Context) { + token := c.GetHeader("Authorization") + password, err := model.GetSettingByKey("password") + if err != nil { + if err == gorm.ErrRecordNotFound { + common.ErrorResp(c, fmt.Errorf("password not set"), 400) + return + } + common.ErrorResp(c, err, 500) + return + } + if token != utils.GetMD5Encode(password.Value) { + common.ErrorResp(c, fmt.Errorf("wrong password"), 401) + return + } + c.Next() +} \ No newline at end of file diff --git a/server/middlewares/down.go b/server/middlewares/down.go new file mode 100644 index 00000000..2176017b --- /dev/null +++ b/server/middlewares/down.go @@ -0,0 +1,20 @@ +package middlewares + +import ( + "fmt" + "github.com/Xhofe/alist/server/common" + "github.com/Xhofe/alist/utils" + "github.com/gin-gonic/gin" +) + +func DownCheck(c *gin.Context) { + rawPath := c.Param("path") + rawPath = utils.ParsePath(rawPath) + pw := c.Query("pw") + if !common.CheckDownLink(utils.Dir(rawPath), pw, utils.Base(rawPath)) { + common.ErrorResp(c, fmt.Errorf("wrong password"), 401) + c.Abort() + return + } + c.Next() +} \ No newline at end of file diff --git a/server/middlewares/path.go b/server/middlewares/path.go new file mode 100644 index 00000000..f6d24b72 --- /dev/null +++ b/server/middlewares/path.go @@ -0,0 +1,35 @@ +package middlewares + +import ( + "fmt" + "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 PathCheck(c *gin.Context) { + var req common.PathReq + if err := c.ShouldBind(&req); err != nil { + common.ErrorResp(c, err, 400) + return + } + req.Path = utils.ParsePath(req.Path) + c.Set("req",req) + meta, err := model.GetMetaByPath(req.Path) + if err == nil { + if meta.Password != "" && meta.Password != req.Password { + common.ErrorResp(c, fmt.Errorf("wrong password"), 401) + c.Abort() + return + } + } else if conf.CheckParent { + if !common.CheckParent(utils.Dir(req.Path), req.Password) { + common.ErrorResp(c, fmt.Errorf("wrong password"), 401) + c.Abort() + return + } + } + c.Next() +} \ No newline at end of file diff --git a/server/router.go b/server/router.go index d363cb4d..64973ac0 100644 --- a/server/router.go +++ b/server/router.go @@ -1,6 +1,9 @@ package server import ( + "github.com/Xhofe/alist/server/common" + "github.com/Xhofe/alist/server/controllers" + "github.com/Xhofe/alist/server/middlewares" "github.com/gin-contrib/cors" "github.com/gin-gonic/gin" ) @@ -9,35 +12,37 @@ func InitApiRouter(r *gin.Engine) { // TODO from settings Cors(r) - r.GET("/d/*path", Down) - r.GET("/p/*path", Proxy) + r.GET("/d/*path", middlewares.DownCheck, controllers.Down) + r.GET("/p/*path", middlewares.DownCheck, controllers.Proxy) api := r.Group("/api") public := api.Group("/public") { - public.POST("/path", CheckAccount, Path) - public.POST("/preview", CheckAccount, Preview) - public.GET("/settings", GetSettingsPublic) - public.POST("/link", CheckAccount, Link) + path := public.Group("", middlewares.PathCheck, middlewares.CheckAccount) + path.POST("/path", controllers.Path) + path.POST("/preview", controllers.Preview) + path.POST("/link", controllers.Link) + + public.GET("/settings", controllers.GetSettingsPublic) } admin := api.Group("/admin") { - admin.Use(Auth) - admin.GET("/login", Login) - admin.GET("/settings", GetSettings) - admin.POST("/settings", SaveSettings) - admin.POST("/account/create", CreateAccount) - admin.POST("/account/save", SaveAccount) - admin.GET("/accounts", GetAccounts) - admin.DELETE("/account", DeleteAccount) - admin.GET("/drivers", GetDrivers) - admin.GET("/clear_cache", ClearCache) + admin.Use(middlewares.Auth) + admin.GET("/login", common.Login) + admin.GET("/settings", controllers.GetSettings) + admin.POST("/settings", controllers.SaveSettings) + admin.POST("/account/create", controllers.CreateAccount) + admin.POST("/account/save", controllers.SaveAccount) + admin.GET("/accounts", controllers.GetAccounts) + admin.DELETE("/account", controllers.DeleteAccount) + admin.GET("/drivers", controllers.GetDrivers) + admin.GET("/clear_cache", controllers.ClearCache) - admin.GET("/metas", GetMetas) - admin.POST("/meta/create", CreateMeta) - admin.POST("/meta/save", SaveMeta) - admin.DELETE("/meta", DeleteMeta) + admin.GET("/metas", controllers.GetMetas) + admin.POST("/meta/create", controllers.CreateMeta) + admin.POST("/meta/save", controllers.SaveMeta) + admin.DELETE("/meta", controllers.DeleteMeta) } Static(r) WebDav(r)