mirror of https://github.com/Xhofe/alist
feat: token and reset
parent
7903ed1f52
commit
5dbf5db4ff
|
@ -1,40 +1,20 @@
|
||||||
package data
|
package data
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"github.com/alist-org/alist/v3/cmd/args"
|
||||||
"github.com/alist-org/alist/v3/internal/conf"
|
"github.com/alist-org/alist/v3/internal/conf"
|
||||||
"github.com/alist-org/alist/v3/internal/db"
|
"github.com/alist-org/alist/v3/internal/db"
|
||||||
"github.com/alist-org/alist/v3/internal/model"
|
"github.com/alist-org/alist/v3/internal/model"
|
||||||
|
"github.com/alist-org/alist/v3/pkg/utils/random"
|
||||||
"github.com/pkg/errors"
|
"github.com/pkg/errors"
|
||||||
log "github.com/sirupsen/logrus"
|
log "github.com/sirupsen/logrus"
|
||||||
"gorm.io/gorm"
|
"gorm.io/gorm"
|
||||||
)
|
)
|
||||||
|
|
||||||
var initialSettingItems = []model.SettingItem{
|
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},
|
|
||||||
}
|
|
||||||
|
|
||||||
func initSettings() {
|
func initSettings() {
|
||||||
|
initialSettings()
|
||||||
// check deprecated
|
// check deprecated
|
||||||
settings, err := db.GetSettingItems()
|
settings, err := db.GetSettingItems()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -77,3 +57,38 @@ func isActive(key string) bool {
|
||||||
}
|
}
|
||||||
return false
|
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},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -12,12 +12,17 @@ import (
|
||||||
var userCache = cache.NewMemCache(cache.WithShards[*model.User](2))
|
var userCache = cache.NewMemCache(cache.WithShards[*model.User](2))
|
||||||
var userG singleflight.Group[*model.User]
|
var userG singleflight.Group[*model.User]
|
||||||
var guest *model.User
|
var guest *model.User
|
||||||
|
var admin *model.User
|
||||||
|
|
||||||
func GetAdmin() (*model.User, error) {
|
func GetAdmin() (*model.User, error) {
|
||||||
|
if admin != nil {
|
||||||
|
return admin, nil
|
||||||
|
}
|
||||||
user := model.User{Role: model.ADMIN}
|
user := model.User{Role: model.ADMIN}
|
||||||
if err := db.Where(user).Take(&user).Error; err != nil {
|
if err := db.Where(user).Take(&user).Error; err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
admin = &user
|
||||||
return &user, nil
|
return &user, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -73,6 +78,9 @@ func UpdateUser(u *model.User) error {
|
||||||
if u.IsGuest() {
|
if u.IsGuest() {
|
||||||
guest = nil
|
guest = nil
|
||||||
}
|
}
|
||||||
|
if u.IsAdmin() {
|
||||||
|
admin = nil
|
||||||
|
}
|
||||||
return errors.WithStack(db.Save(u).Error)
|
return errors.WithStack(db.Save(u).Error)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -5,6 +5,7 @@ const (
|
||||||
STYLE
|
STYLE
|
||||||
PREVIEW
|
PREVIEW
|
||||||
GLOBAL
|
GLOBAL
|
||||||
|
SINGLE
|
||||||
)
|
)
|
||||||
|
|
||||||
const (
|
const (
|
||||||
|
|
|
@ -17,6 +17,10 @@ func String(n int) string {
|
||||||
return string(b)
|
return string(b)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func Token() string {
|
||||||
|
return String(64)
|
||||||
|
}
|
||||||
|
|
||||||
func init() {
|
func init() {
|
||||||
s := rand.NewSource(time.Now().UnixNano())
|
s := rand.NewSource(time.Now().UnixNano())
|
||||||
Rand = rand.New(s)
|
Rand = rand.New(s)
|
||||||
|
|
|
@ -1,13 +1,35 @@
|
||||||
package controllers
|
package controllers
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"github.com/alist-org/alist/v3/internal/conf"
|
||||||
"github.com/alist-org/alist/v3/internal/db"
|
"github.com/alist-org/alist/v3/internal/db"
|
||||||
"github.com/alist-org/alist/v3/internal/model"
|
"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/alist-org/alist/v3/server/common"
|
||||||
"github.com/gin-gonic/gin"
|
"github.com/gin-gonic/gin"
|
||||||
"strconv"
|
"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) {
|
func SaveSettings(c *gin.Context) {
|
||||||
var req []model.SettingItem
|
var req []model.SettingItem
|
||||||
if err := c.ShouldBind(&req); err != nil {
|
if err := c.ShouldBind(&req); err != nil {
|
||||||
|
|
|
@ -3,6 +3,7 @@ package middlewares
|
||||||
import (
|
import (
|
||||||
"github.com/alist-org/alist/v3/internal/db"
|
"github.com/alist-org/alist/v3/internal/db"
|
||||||
"github.com/alist-org/alist/v3/internal/model"
|
"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"
|
common2 "github.com/alist-org/alist/v3/server/common"
|
||||||
"github.com/gin-gonic/gin"
|
"github.com/gin-gonic/gin"
|
||||||
)
|
)
|
||||||
|
@ -11,6 +12,17 @@ import (
|
||||||
// if token is empty, set user to guest
|
// if token is empty, set user to guest
|
||||||
func Auth(c *gin.Context) {
|
func Auth(c *gin.Context) {
|
||||||
token := c.GetHeader("Authorization")
|
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 == "" {
|
if token == "" {
|
||||||
guest, err := db.GetGuest()
|
guest, err := db.GetGuest()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|
|
@ -43,13 +43,15 @@ func Init(r *gin.Engine) {
|
||||||
driver.GET("/items", controllers.GetDriverItems)
|
driver.GET("/items", controllers.GetDriverItems)
|
||||||
|
|
||||||
setting := admin.Group("/setting")
|
setting := admin.Group("/setting")
|
||||||
|
setting.GET("/get", controllers.GetSetting)
|
||||||
setting.GET("/list", controllers.ListSettings)
|
setting.GET("/list", controllers.ListSettings)
|
||||||
setting.POST("/save", controllers.SaveSettings)
|
setting.POST("/save", controllers.SaveSettings)
|
||||||
setting.POST("/delete", controllers.DeleteSetting)
|
setting.POST("/delete", controllers.DeleteSetting)
|
||||||
|
setting.POST("/reset_token", controllers.ResetToken)
|
||||||
|
|
||||||
public := api.Group("/public")
|
public := api.Group("/public")
|
||||||
public.GET("/settings", controllers.PublicSettings)
|
public.GET("/settings", controllers.PublicSettings)
|
||||||
public.GET("/list", controllers.FsList)
|
public.Any("/list", controllers.FsList)
|
||||||
public.GET("/get", controllers.FsGet)
|
public.GET("/get", controllers.FsGet)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue