diff --git a/internal/bootstrap/data/setting.go b/internal/bootstrap/data/setting.go index a5ecab25b9f..a04b57fa453 100644 --- a/internal/bootstrap/data/setting.go +++ b/internal/bootstrap/data/setting.go @@ -1,40 +1,20 @@ package data import ( + "github.com/alist-org/alist/v3/cmd/args" "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/pkg/utils/random" "github.com/pkg/errors" log "github.com/sirupsen/logrus" "gorm.io/gorm" ) -var 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}, - // style settings - {Key: "icon_color", 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}, - // 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}, -} +var initialSettingItems []model.SettingItem func initSettings() { + initialSettings() // check deprecated settings, err := db.GetSettingItems() if err != nil { @@ -77,3 +57,38 @@ func isActive(key string) bool { } return false } + +func initialSettings() { + var token string + if args.Dev { + token = "dev_token" + } else { + token = random.Token() + } + 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}, + // style settings + {Key: "icon_color", 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}, + // 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}, + // single settings + {Key: "token", Value: token, Type: conf.TypeString, Group: model.SINGLE, Flag: model.PRIVATE}, + } +} diff --git a/internal/db/user.go b/internal/db/user.go index 50002c643b5..39ea13087bd 100644 --- a/internal/db/user.go +++ b/internal/db/user.go @@ -12,12 +12,17 @@ import ( var userCache = cache.NewMemCache(cache.WithShards[*model.User](2)) var userG singleflight.Group[*model.User] var guest *model.User +var admin *model.User func GetAdmin() (*model.User, error) { + if admin != nil { + return admin, nil + } user := model.User{Role: model.ADMIN} if err := db.Where(user).Take(&user).Error; err != nil { return nil, err } + admin = &user return &user, nil } @@ -73,6 +78,9 @@ func UpdateUser(u *model.User) error { if u.IsGuest() { guest = nil } + if u.IsAdmin() { + admin = nil + } return errors.WithStack(db.Save(u).Error) } diff --git a/internal/model/setting.go b/internal/model/setting.go index 8e431176a7d..f252a841178 100644 --- a/internal/model/setting.go +++ b/internal/model/setting.go @@ -5,6 +5,7 @@ const ( STYLE PREVIEW GLOBAL + SINGLE ) const ( diff --git a/pkg/utils/random/random.go b/pkg/utils/random/random.go index 1ccc3d762a7..0d1eb034da4 100644 --- a/pkg/utils/random/random.go +++ b/pkg/utils/random/random.go @@ -17,6 +17,10 @@ func String(n int) string { return string(b) } +func Token() string { + return String(64) +} + func init() { s := rand.NewSource(time.Now().UnixNano()) Rand = rand.New(s) diff --git a/server/controllers/setting.go b/server/controllers/setting.go index 705214fbb26..3582ef52329 100644 --- a/server/controllers/setting.go +++ b/server/controllers/setting.go @@ -1,13 +1,35 @@ package controllers 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/pkg/utils/random" "github.com/alist-org/alist/v3/server/common" "github.com/gin-gonic/gin" "strconv" ) +func ResetToken(c *gin.Context) { + token := random.Token() + item := model.SettingItem{Key: "token", Value: token, Type: conf.TypeString, Group: model.SINGLE, Flag: model.PRIVATE} + if err := db.SaveSettingItem(item); err != nil { + common.ErrorResp(c, err, 500) + return + } + common.SuccessResp(c, token) +} + +func GetSetting(c *gin.Context) { + key := c.Query("key") + item, err := db.GetSettingItemByKey(key) + if err != nil { + common.ErrorResp(c, err, 400) + return + } + common.SuccessResp(c, item) +} + func SaveSettings(c *gin.Context) { var req []model.SettingItem if err := c.ShouldBind(&req); err != nil { diff --git a/server/middlewares/auth.go b/server/middlewares/auth.go index 50a93298971..556ed940dcb 100644 --- a/server/middlewares/auth.go +++ b/server/middlewares/auth.go @@ -3,6 +3,7 @@ package middlewares import ( "github.com/alist-org/alist/v3/internal/db" "github.com/alist-org/alist/v3/internal/model" + "github.com/alist-org/alist/v3/internal/setting" common2 "github.com/alist-org/alist/v3/server/common" "github.com/gin-gonic/gin" ) @@ -11,6 +12,17 @@ import ( // if token is empty, set user to guest func Auth(c *gin.Context) { token := c.GetHeader("Authorization") + if token == setting.GetByKey("token") { + admin, err := db.GetAdmin() + if err != nil { + common2.ErrorResp(c, err, 500) + c.Abort() + return + } + c.Set("user", admin) + c.Next() + return + } if token == "" { guest, err := db.GetGuest() if err != nil { diff --git a/server/router.go b/server/router.go index 1849a68197e..f527c646a48 100644 --- a/server/router.go +++ b/server/router.go @@ -43,13 +43,15 @@ func Init(r *gin.Engine) { driver.GET("/items", controllers.GetDriverItems) setting := admin.Group("/setting") + setting.GET("/get", controllers.GetSetting) setting.GET("/list", controllers.ListSettings) setting.POST("/save", controllers.SaveSettings) setting.POST("/delete", controllers.DeleteSetting) + setting.POST("/reset_token", controllers.ResetToken) public := api.Group("/public") public.GET("/settings", controllers.PublicSettings) - public.GET("/list", controllers.FsList) + public.Any("/list", controllers.FsList) public.GET("/get", controllers.FsGet) }