Skip to content

Commit

Permalink
feat: fs link api
Browse files Browse the repository at this point in the history
  • Loading branch information
xhofe committed Jun 29, 2022
1 parent f275f83 commit 4054892
Show file tree
Hide file tree
Showing 11 changed files with 174 additions and 96 deletions.
40 changes: 20 additions & 20 deletions internal/bootstrap/data/setting.go
Original file line number Diff line number Diff line change
Expand Up @@ -67,29 +67,29 @@ func initialSettings() {
}
initialSettingItems = []model.SettingItem{
// site settings
{Key: "version", Value: conf.Version, Type: conf.TypeString, Group: model.SITE, Flag: model.READONLY},
{Key: "base_url", Value: "", Type: conf.TypeString, Group: model.SITE},
{Key: "site_title", Value: "AList", Type: conf.TypeString, Group: model.SITE},
{Key: "site_logo", Value: "https://cdn.jsdelivr.net/gh/alist-org/logo@main/logo.svg", Type: conf.TypeString, Group: model.SITE},
{Key: "favicon", Value: "https://cdn.jsdelivr.net/gh/alist-org/logo@main/logo.svg", Type: conf.TypeString, Group: model.SITE},
{Key: "announcement", Value: "https://github.com/alist-org/alist", Type: conf.TypeString, Group: model.SITE},
{Key: conf.VERSION, Value: conf.Version, Type: conf.TypeString, Group: model.SITE, Flag: model.READONLY},
{Key: conf.BaseUrl, Value: "", Type: conf.TypeString, Group: model.SITE},
{Key: conf.SiteTitle, Value: "AList", Type: conf.TypeString, Group: model.SITE},
{Key: conf.SiteLogo, Value: "https://cdn.jsdelivr.net/gh/alist-org/logo@main/logo.svg", Type: conf.TypeString, Group: model.SITE},
{Key: conf.Favicon, Value: "https://cdn.jsdelivr.net/gh/alist-org/logo@main/logo.svg", Type: conf.TypeString, Group: model.SITE},
{Key: conf.Announcement, Value: "https://github.com/alist-org/alist", Type: conf.TypeString, Group: model.SITE},
// style settings
{Key: "icon_color", Value: "#1890ff", Type: conf.TypeString, Group: model.STYLE},
{Key: conf.IconColor, Value: "#1890ff", Type: conf.TypeString, Group: model.STYLE},
// preview settings
{Key: "text_types", Value: "txt,htm,html,xml,java,properties,sql,js,md,json,conf,ini,vue,php,py,bat,gitignore,yml,go,sh,c,cpp,h,hpp,tsx,vtt,srt,ass,rs,lrc", Type: conf.TypeText, Group: model.PREVIEW, Flag: model.PRIVATE},
{Key: "audio_types", Value: "mp3,flac,ogg,m4a,wav,opus", Type: conf.TypeText, Group: model.PREVIEW, Flag: model.PRIVATE},
{Key: "video_types", Value: "mp4,mkv,avi,mov,rmvb,webm,flv", Type: conf.TypeText, Group: model.PREVIEW, Flag: model.PRIVATE},
{Key: "proxy_types", Value: "m3u8", Type: conf.TypeText, Group: model.PREVIEW, Flag: model.PRIVATE},
{Key: "pdf_viewer_url", Value: "https://alist-org.github.io/pdf.js/web/viewer.html?file=$url", Type: conf.TypeString, Group: model.PREVIEW},
{Key: "audio_autoplay", Value: "true", Type: conf.TypeBool, Group: model.PREVIEW},
{Key: "video_autoplay", Value: "true", Type: conf.TypeBool, Group: model.PREVIEW},
{Key: conf.TextTypes, Value: "txt,htm,html,xml,java,properties,sql,js,md,json,conf,ini,vue,php,py,bat,gitignore,yml,go,sh,c,cpp,h,hpp,tsx,vtt,srt,ass,rs,lrc", Type: conf.TypeText, Group: model.PREVIEW, Flag: model.PRIVATE},
{Key: conf.AudioTypes, Value: "mp3,flac,ogg,m4a,wav,opus", Type: conf.TypeText, Group: model.PREVIEW, Flag: model.PRIVATE},
{Key: conf.VideoTypes, Value: "mp4,mkv,avi,mov,rmvb,webm,flv", Type: conf.TypeText, Group: model.PREVIEW, Flag: model.PRIVATE},
{Key: conf.ProxyTypes, Value: "m3u8", Type: conf.TypeText, Group: model.PREVIEW, Flag: model.PRIVATE},
{Key: conf.PdfViewerUrl, Value: "https://alist-org.github.io/pdf.js/web/viewer.html?file=$url", Type: conf.TypeString, Group: model.PREVIEW},
{Key: conf.AudioAutoplay, Value: "true", Type: conf.TypeBool, Group: model.PREVIEW},
{Key: conf.VideoAutoplay, Value: "true", Type: conf.TypeBool, Group: model.PREVIEW},
// global settings
{Key: "hide_files", Value: "/\\/README.md/i", Type: conf.TypeText, Group: model.GLOBAL},
{Key: "global_readme", Value: "This is global readme", Type: conf.TypeText, Group: model.GLOBAL},
{Key: "customize_head", Type: conf.TypeText, Group: model.GLOBAL, Flag: model.PRIVATE},
{Key: "customize_body", Type: conf.TypeText, Group: model.GLOBAL, Flag: model.PRIVATE},
{Key: "link_expiration", Value: "0", Type: conf.TypeNumber, Group: model.GLOBAL, Flag: model.PRIVATE},
{Key: conf.HideFiles, Value: "/\\/README.md/i", Type: conf.TypeText, Group: model.GLOBAL},
{Key: conf.GlobalReadme, Value: "This is global readme", Type: conf.TypeText, Group: model.GLOBAL},
{Key: conf.CustomizeHead, Type: conf.TypeText, Group: model.GLOBAL, Flag: model.PRIVATE},
{Key: conf.CustomizeBody, Type: conf.TypeText, Group: model.GLOBAL, Flag: model.PRIVATE},
{Key: conf.LinkExpiration, Value: "0", Type: conf.TypeNumber, Group: model.GLOBAL, Flag: model.PRIVATE},
// single settings
{Key: "token", Value: token, Type: conf.TypeString, Group: model.SINGLE, Flag: model.PRIVATE},
{Key: conf.Token, Value: token, Type: conf.TypeString, Group: model.SINGLE, Flag: model.PRIVATE},
}
}
23 changes: 23 additions & 0 deletions internal/conf/const.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,3 +7,26 @@ const (
TypeText = "text"
TypeNumber = "number"
)

const (
VERSION = "version"
BaseUrl = "base_url"
SiteTitle = "site_title"
SiteLogo = "site_logo"
Favicon = "favicon"
Announcement = "announcement"
IconColor = "icon_color"
TextTypes = "text_types"
AudioTypes = "audio_types"
VideoTypes = "video_types"
ProxyTypes = "proxy_types"
PdfViewerUrl = "pdf_viewer_url"
AudioAutoplay = "audio_autoplay"
VideoAutoplay = "video_autoplay"
HideFiles = "hide_files"
GlobalReadme = "global_readme"
CustomizeHead = "customize_head"
CustomizeBody = "customize_body"
LinkExpiration = "link_expiration"
Token = "token"
)
4 changes: 2 additions & 2 deletions internal/model/link.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,8 @@ type LinkArgs struct {
}

type Link struct {
URL string
Header http.Header // needed header
URL string `json:"url"`
Header http.Header `json:"header"` // needed header
Data io.ReadCloser // return file reader directly
Status int // status maybe 200 or 206, etc
FilePath *string // local file, return the filepath
Expand Down
5 changes: 3 additions & 2 deletions internal/sign/sign.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package sign

import (
"github.com/alist-org/alist/v3/internal/conf"
"github.com/alist-org/alist/v3/internal/setting"
"github.com/alist-org/alist/v3/pkg/sign"
"sync"
Expand All @@ -11,7 +12,7 @@ var once sync.Once
var instance sign.Sign

func Sign(data string) string {
expire := setting.GetIntSetting("link_expiration", 0)
expire := setting.GetIntSetting(conf.LinkExpiration, 0)
if expire == 0 {
return NotExpired(data)
} else {
Expand All @@ -35,5 +36,5 @@ func Verify(data string, sign string) error {
}

func Instance() {
instance = sign.NewHMACSign([]byte(setting.GetByKey("token")))
instance = sign.NewHMACSign([]byte(setting.GetByKey(conf.Token)))
}
18 changes: 18 additions & 0 deletions server/common/base.go
Original file line number Diff line number Diff line change
@@ -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
}
7 changes: 4 additions & 3 deletions server/controllers/down.go
Original file line number Diff line number Diff line change
Expand Up @@ -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"
Expand Down Expand Up @@ -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
}
Expand All @@ -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
}
Expand Down
60 changes: 0 additions & 60 deletions server/controllers/fsget.go

This file was deleted.

36 changes: 33 additions & 3 deletions server/controllers/fsmanage.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,19 +4,20 @@ 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"
"strconv"
"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
Expand Down Expand Up @@ -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
}
53 changes: 49 additions & 4 deletions server/controllers/fslist.go → server/controllers/fsread.go
Original file line number Diff line number Diff line change
Expand Up @@ -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"
Expand Down Expand Up @@ -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),
})
}
Expand Down Expand Up @@ -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{
Expand All @@ -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
})
}
13 changes: 12 additions & 1 deletion server/middlewares/auth.go
Original file line number Diff line number Diff line change
@@ -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"
Expand All @@ -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)
Expand Down Expand Up @@ -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()
}
}
Loading

0 comments on commit 4054892

Please sign in to comment.