feat: fs link api
This commit is contained in:
18
server/common/base.go
Normal file
18
server/common/base.go
Normal file
@ -0,0 +1,18 @@
|
||||
package common
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"github.com/alist-org/alist/v3/internal/conf"
|
||||
"github.com/alist-org/alist/v3/internal/setting"
|
||||
"net/http"
|
||||
"strings"
|
||||
)
|
||||
|
||||
func GetBaseUrl(r *http.Request) string {
|
||||
baseUrl := setting.GetByKey(conf.BaseUrl)
|
||||
if baseUrl == "" {
|
||||
baseUrl = fmt.Sprintf("//%s", r.Host)
|
||||
}
|
||||
strings.TrimSuffix(baseUrl, "/")
|
||||
return baseUrl
|
||||
}
|
@ -2,6 +2,7 @@ package controllers
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"github.com/alist-org/alist/v3/internal/conf"
|
||||
"github.com/alist-org/alist/v3/internal/sign"
|
||||
stdpath "path"
|
||||
"strings"
|
||||
@ -84,7 +85,7 @@ func shouldProxy(account driver.Driver, filename string) bool {
|
||||
if account.Config().MustProxy() || account.GetAccount().WebProxy {
|
||||
return true
|
||||
}
|
||||
proxyTypes := setting.GetByKey("proxy_types")
|
||||
proxyTypes := setting.GetByKey(conf.ProxyTypes)
|
||||
if strings.Contains(proxyTypes, utils.Ext(filename)) {
|
||||
return true
|
||||
}
|
||||
@ -102,11 +103,11 @@ func canProxy(account driver.Driver, filename string) bool {
|
||||
if account.Config().MustProxy() || account.GetAccount().WebProxy {
|
||||
return true
|
||||
}
|
||||
proxyTypes := setting.GetByKey("proxy_types")
|
||||
proxyTypes := setting.GetByKey(conf.ProxyTypes)
|
||||
if strings.Contains(proxyTypes, utils.Ext(filename)) {
|
||||
return true
|
||||
}
|
||||
textTypes := setting.GetByKey("text_types")
|
||||
textTypes := setting.GetByKey(conf.TextTypes)
|
||||
if strings.Contains(textTypes, utils.Ext(filename)) {
|
||||
return true
|
||||
}
|
||||
|
@ -1,60 +0,0 @@
|
||||
package controllers
|
||||
|
||||
import (
|
||||
stdpath "path"
|
||||
|
||||
"github.com/alist-org/alist/v3/internal/db"
|
||||
"github.com/alist-org/alist/v3/internal/errs"
|
||||
"github.com/alist-org/alist/v3/internal/fs"
|
||||
"github.com/alist-org/alist/v3/internal/model"
|
||||
"github.com/alist-org/alist/v3/server/common"
|
||||
"github.com/gin-gonic/gin"
|
||||
"github.com/pkg/errors"
|
||||
)
|
||||
|
||||
type FsGetReq struct {
|
||||
Path string `json:"path" form:"path"`
|
||||
Password string `json:"password" form:"password"`
|
||||
}
|
||||
|
||||
type FsGetResp struct {
|
||||
ObjResp
|
||||
RawURL string `json:"raw_url"`
|
||||
}
|
||||
|
||||
func FsGet(c *gin.Context) {
|
||||
var req FsGetReq
|
||||
if err := c.ShouldBind(&req); err != nil {
|
||||
common.ErrorResp(c, err, 400)
|
||||
return
|
||||
}
|
||||
user := c.MustGet("user").(*model.User)
|
||||
req.Path = stdpath.Join(user.BasePath, req.Path)
|
||||
meta, err := db.GetNearestMeta(req.Path)
|
||||
if err != nil {
|
||||
if !errors.Is(errors.Cause(err), errs.MetaNotFound) {
|
||||
common.ErrorResp(c, err, 500)
|
||||
return
|
||||
}
|
||||
}
|
||||
c.Set("meta", meta)
|
||||
if !canAccess(user, meta, req.Path, req.Password) {
|
||||
common.ErrorStrResp(c, "password is incorrect", 401)
|
||||
return
|
||||
}
|
||||
obj, err := fs.Get(c, req.Path)
|
||||
if err != nil {
|
||||
common.ErrorResp(c, err, 500)
|
||||
return
|
||||
}
|
||||
common.SuccessResp(c, FsGetResp{
|
||||
ObjResp: ObjResp{
|
||||
Name: obj.GetName(),
|
||||
Size: obj.GetSize(),
|
||||
IsDir: obj.IsDir(),
|
||||
Modified: obj.ModTime(),
|
||||
Sign: common.Sign(obj),
|
||||
},
|
||||
// TODO: set raw url
|
||||
})
|
||||
}
|
@ -4,6 +4,7 @@ import (
|
||||
"fmt"
|
||||
"github.com/alist-org/alist/v3/internal/fs"
|
||||
"github.com/alist-org/alist/v3/internal/model"
|
||||
"github.com/alist-org/alist/v3/internal/sign"
|
||||
"github.com/alist-org/alist/v3/server/common"
|
||||
"github.com/gin-gonic/gin"
|
||||
stdpath "path"
|
||||
@ -11,12 +12,12 @@ import (
|
||||
"time"
|
||||
)
|
||||
|
||||
type MkdirReq struct {
|
||||
Path string `json:"path"`
|
||||
type MkdirOrLinkReq struct {
|
||||
Path string `json:"path" form:"path"`
|
||||
}
|
||||
|
||||
func FsMkdir(c *gin.Context) {
|
||||
var req MkdirReq
|
||||
var req MkdirOrLinkReq
|
||||
if err := c.ShouldBind(&req); err != nil {
|
||||
common.ErrorResp(c, err, 400)
|
||||
return
|
||||
@ -162,3 +163,32 @@ func FsPut(c *gin.Context) {
|
||||
}
|
||||
common.SuccessResp(c)
|
||||
}
|
||||
|
||||
// Link return real link, just for proxy program
|
||||
func Link(c *gin.Context) {
|
||||
var req MkdirOrLinkReq
|
||||
if err := c.ShouldBind(&req); err != nil {
|
||||
common.ErrorResp(c, err, 400)
|
||||
return
|
||||
}
|
||||
user := c.MustGet("user").(*model.User)
|
||||
rawPath := stdpath.Join(user.BasePath, req.Path)
|
||||
account, err := fs.GetAccount(rawPath)
|
||||
if err != nil {
|
||||
common.ErrorResp(c, err, 500)
|
||||
return
|
||||
}
|
||||
if account.Config().OnlyLocal {
|
||||
common.SuccessResp(c, model.Link{
|
||||
URL: fmt.Sprintf("%s/p%s?d&sign=%s", common.GetBaseUrl(c.Request), req.Path, sign.Sign(stdpath.Base(rawPath))),
|
||||
})
|
||||
return
|
||||
}
|
||||
link, _, err := fs.Link(c, rawPath, model.LinkArgs{IP: c.ClientIP()})
|
||||
if err != nil {
|
||||
common.ErrorResp(c, err, 500)
|
||||
return
|
||||
}
|
||||
common.SuccessResp(c, link)
|
||||
return
|
||||
}
|
||||
|
@ -8,7 +8,6 @@ import (
|
||||
"github.com/alist-org/alist/v3/internal/errs"
|
||||
"github.com/alist-org/alist/v3/internal/fs"
|
||||
"github.com/alist-org/alist/v3/internal/model"
|
||||
"github.com/alist-org/alist/v3/internal/setting"
|
||||
"github.com/alist-org/alist/v3/pkg/utils"
|
||||
"github.com/alist-org/alist/v3/server/common"
|
||||
"github.com/gin-gonic/gin"
|
||||
@ -61,9 +60,8 @@ func FsList(c *gin.Context) {
|
||||
return
|
||||
}
|
||||
total, objs := pagination(objs, &req.PageReq)
|
||||
baseURL := setting.GetByKey("base_url", c.Request.Host)
|
||||
common.SuccessResp(c, FsListResp{
|
||||
Content: toObjResp(objs, req.Path, baseURL),
|
||||
Content: toObjResp(objs),
|
||||
Total: int64(total),
|
||||
})
|
||||
}
|
||||
@ -99,7 +97,7 @@ func pagination(objs []model.Obj, req *common.PageReq) (int, []model.Obj) {
|
||||
return total, objs[start:end]
|
||||
}
|
||||
|
||||
func toObjResp(objs []model.Obj, path string, baseURL string) []ObjResp {
|
||||
func toObjResp(objs []model.Obj) []ObjResp {
|
||||
var resp []ObjResp
|
||||
for _, obj := range objs {
|
||||
resp = append(resp, ObjResp{
|
||||
@ -112,3 +110,50 @@ func toObjResp(objs []model.Obj, path string, baseURL string) []ObjResp {
|
||||
}
|
||||
return resp
|
||||
}
|
||||
|
||||
type FsGetReq struct {
|
||||
Path string `json:"path" form:"path"`
|
||||
Password string `json:"password" form:"password"`
|
||||
}
|
||||
|
||||
type FsGetResp struct {
|
||||
ObjResp
|
||||
RawURL string `json:"raw_url"`
|
||||
}
|
||||
|
||||
func FsGet(c *gin.Context) {
|
||||
var req FsGetReq
|
||||
if err := c.ShouldBind(&req); err != nil {
|
||||
common.ErrorResp(c, err, 400)
|
||||
return
|
||||
}
|
||||
user := c.MustGet("user").(*model.User)
|
||||
req.Path = stdpath.Join(user.BasePath, req.Path)
|
||||
meta, err := db.GetNearestMeta(req.Path)
|
||||
if err != nil {
|
||||
if !errors.Is(errors.Cause(err), errs.MetaNotFound) {
|
||||
common.ErrorResp(c, err, 500)
|
||||
return
|
||||
}
|
||||
}
|
||||
c.Set("meta", meta)
|
||||
if !canAccess(user, meta, req.Path, req.Password) {
|
||||
common.ErrorStrResp(c, "password is incorrect", 401)
|
||||
return
|
||||
}
|
||||
obj, err := fs.Get(c, req.Path)
|
||||
if err != nil {
|
||||
common.ErrorResp(c, err, 500)
|
||||
return
|
||||
}
|
||||
common.SuccessResp(c, FsGetResp{
|
||||
ObjResp: ObjResp{
|
||||
Name: obj.GetName(),
|
||||
Size: obj.GetSize(),
|
||||
IsDir: obj.IsDir(),
|
||||
Modified: obj.ModTime(),
|
||||
Sign: common.Sign(obj),
|
||||
},
|
||||
// TODO: set raw url
|
||||
})
|
||||
}
|
@ -1,6 +1,7 @@
|
||||
package middlewares
|
||||
|
||||
import (
|
||||
"github.com/alist-org/alist/v3/internal/conf"
|
||||
"github.com/alist-org/alist/v3/internal/db"
|
||||
"github.com/alist-org/alist/v3/internal/model"
|
||||
"github.com/alist-org/alist/v3/internal/setting"
|
||||
@ -12,7 +13,7 @@ import (
|
||||
// if token is empty, set user to guest
|
||||
func Auth(c *gin.Context) {
|
||||
token := c.GetHeader("Authorization")
|
||||
if token == setting.GetByKey("token") {
|
||||
if token == setting.GetByKey(conf.Token) {
|
||||
admin, err := db.GetAdmin()
|
||||
if err != nil {
|
||||
common.ErrorResp(c, err, 500)
|
||||
@ -59,3 +60,13 @@ func AuthAdmin(c *gin.Context) {
|
||||
c.Next()
|
||||
}
|
||||
}
|
||||
|
||||
func AuthWrite(c *gin.Context) {
|
||||
user := c.MustGet("user").(*model.User)
|
||||
if !user.IsAdmin() && user.ReadOnly {
|
||||
common.ErrorStrResp(c, "You have no write access", 403)
|
||||
c.Abort()
|
||||
} else {
|
||||
c.Next()
|
||||
}
|
||||
}
|
||||
|
@ -56,11 +56,20 @@ func Init(r *gin.Engine) {
|
||||
public.GET("/settings", controllers.PublicSettings)
|
||||
public.Any("/list", controllers.FsList)
|
||||
public.Any("/get", controllers.FsGet)
|
||||
|
||||
fs := api.Group("/fs", middlewares.AuthWrite)
|
||||
fs.POST("/mkdir", controllers.FsMkdir)
|
||||
fs.POST("/rename", controllers.FsRename)
|
||||
fs.POST("/move", controllers.FsMove)
|
||||
fs.POST("/copy", controllers.FsCopy)
|
||||
fs.POST("/remove", controllers.FsRemove)
|
||||
fs.POST("/put", controllers.FsPut)
|
||||
fs.POST("/link", controllers.Link)
|
||||
}
|
||||
|
||||
func Cors(r *gin.Engine) {
|
||||
config := cors.DefaultConfig()
|
||||
config.AllowAllOrigins = true
|
||||
config.AllowHeaders = append(config.AllowHeaders, "Authorization", "range")
|
||||
config.AllowHeaders = append(config.AllowHeaders, "Authorization", "range", "File-Path")
|
||||
r.Use(cors.New(config))
|
||||
}
|
||||
|
Reference in New Issue
Block a user