🎨 Improve the code structure

pull/548/head
微凉 2021-12-07 15:56:43 +08:00
parent 6e8d551420
commit 03580fd76c
14 changed files with 220 additions and 176 deletions

View File

@ -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 {

View File

@ -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() {

View File

@ -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)
}

View File

@ -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)
}
}

View File

@ -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)

View File

@ -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())
}

View File

@ -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)
}

View File

@ -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)
}
}

View File

@ -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)
}

View File

@ -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()
}

View File

@ -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()
}

View File

@ -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()
}

View File

@ -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()
}

View File

@ -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)