mirror of https://github.com/Xhofe/alist
				
				
				
			✨ bootstrap
							parent
							
								
									9644cc98c3
								
							
						
					
					
						commit
						55f683b12d
					
				| 
						 | 
				
			
			@ -0,0 +1,20 @@
 | 
			
		|||
package bootstrap
 | 
			
		||||
 | 
			
		||||
import (
 | 
			
		||||
	"github.com/Xhofe/alist/conf"
 | 
			
		||||
	"github.com/allegro/bigcache/v3"
 | 
			
		||||
	"github.com/eko/gocache/v2/cache"
 | 
			
		||||
	"github.com/eko/gocache/v2/store"
 | 
			
		||||
	log "github.com/sirupsen/logrus"
 | 
			
		||||
	"time"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
// InitCache init cache
 | 
			
		||||
func InitCache() {
 | 
			
		||||
	log.Infof("init cache...")
 | 
			
		||||
	bigCacheConfig := bigcache.DefaultConfig(60 * time.Minute)
 | 
			
		||||
	bigCacheConfig.HardMaxCacheSize = 512
 | 
			
		||||
	bigCacheClient, _ := bigcache.NewBigCache(bigCacheConfig)
 | 
			
		||||
	bigCacheStore := store.NewBigcache(bigCacheClient, nil)
 | 
			
		||||
	conf.Cache = cache.New(bigCacheStore)
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -0,0 +1,32 @@
 | 
			
		|||
package bootstrap
 | 
			
		||||
 | 
			
		||||
import (
 | 
			
		||||
	"encoding/json"
 | 
			
		||||
	"github.com/Xhofe/alist/conf"
 | 
			
		||||
	"github.com/Xhofe/alist/utils"
 | 
			
		||||
	log "github.com/sirupsen/logrus"
 | 
			
		||||
	"io/ioutil"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
// InitConf init config
 | 
			
		||||
func InitConf() {
 | 
			
		||||
	log.Infof("reading config file: %s", conf.ConfigFile)
 | 
			
		||||
	if !utils.Exists(conf.ConfigFile) {
 | 
			
		||||
		log.Infof("config file not exists, creating default config file")
 | 
			
		||||
		conf.Conf = conf.DefaultConfig()
 | 
			
		||||
		if !utils.WriteToJson(conf.ConfigFile, conf.Conf) {
 | 
			
		||||
			log.Fatalf("failed to create default config file")
 | 
			
		||||
		}
 | 
			
		||||
		return
 | 
			
		||||
	}
 | 
			
		||||
	config, err := ioutil.ReadFile(conf.ConfigFile)
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		log.Fatalf("reading config file error:%s", err.Error())
 | 
			
		||||
	}
 | 
			
		||||
	conf.Conf = new(conf.Config)
 | 
			
		||||
	err = json.Unmarshal(config, conf.Conf)
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		log.Fatalf("load config error: %s", err.Error())
 | 
			
		||||
	}
 | 
			
		||||
	log.Debugf("config:%+v", conf.Conf)
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -0,0 +1,14 @@
 | 
			
		|||
package bootstrap
 | 
			
		||||
 | 
			
		||||
import (
 | 
			
		||||
	"github.com/Xhofe/alist/conf"
 | 
			
		||||
	"github.com/robfig/cron/v3"
 | 
			
		||||
	log "github.com/sirupsen/logrus"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
// InitCron init cron
 | 
			
		||||
func InitCron() {
 | 
			
		||||
	log.Infof("init cron...")
 | 
			
		||||
	conf.Cron = cron.New()
 | 
			
		||||
	conf.Cron.Start()
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -0,0 +1,21 @@
 | 
			
		|||
package bootstrap
 | 
			
		||||
 | 
			
		||||
import (
 | 
			
		||||
	"github.com/Xhofe/alist/conf"
 | 
			
		||||
	log "github.com/sirupsen/logrus"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
// initLog init log
 | 
			
		||||
func InitLog() {
 | 
			
		||||
	if conf.Debug {
 | 
			
		||||
		log.SetLevel(log.DebugLevel)
 | 
			
		||||
		log.SetReportCaller(true)
 | 
			
		||||
	}
 | 
			
		||||
	log.SetFormatter(&log.TextFormatter{
 | 
			
		||||
		//DisableColors: true,
 | 
			
		||||
		ForceColors:               true,
 | 
			
		||||
		EnvironmentOverrideColors: true,
 | 
			
		||||
		TimestampFormat:           "2006-01-02 15:04:05",
 | 
			
		||||
		FullTimestamp:             true,
 | 
			
		||||
	})
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -1,8 +1,11 @@
 | 
			
		|||
package model
 | 
			
		||||
package bootstrap
 | 
			
		||||
 | 
			
		||||
import (
 | 
			
		||||
	"fmt"
 | 
			
		||||
	"github.com/Xhofe/alist/conf"
 | 
			
		||||
	"github.com/Xhofe/alist/drivers"
 | 
			
		||||
	"github.com/Xhofe/alist/model"
 | 
			
		||||
	"github.com/Xhofe/alist/utils"
 | 
			
		||||
	log "github.com/sirupsen/logrus"
 | 
			
		||||
	"gorm.io/driver/mysql"
 | 
			
		||||
	"gorm.io/driver/postgres"
 | 
			
		||||
| 
						 | 
				
			
			@ -64,7 +67,7 @@ func InitModel() {
 | 
			
		|||
		log.Fatalf("not supported database type: %s", config.Type)
 | 
			
		||||
	}
 | 
			
		||||
	log.Infof("auto migrate model")
 | 
			
		||||
	err := conf.DB.AutoMigrate(&SettingItem{},&Account{})
 | 
			
		||||
	err := conf.DB.AutoMigrate(&model.SettingItem{}, &model.Account{})
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		log.Fatalf("failed to auto migrate")
 | 
			
		||||
	}
 | 
			
		||||
| 
						 | 
				
			
			@ -73,3 +76,74 @@ func InitModel() {
 | 
			
		|||
	initAccounts()
 | 
			
		||||
	initSettings()
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func initAccounts() {
 | 
			
		||||
	log.Infof("init accounts...")
 | 
			
		||||
	var accounts []model.Account
 | 
			
		||||
	if err := conf.DB.Find(&accounts).Error; err != nil {
 | 
			
		||||
		log.Fatalf("failed sync init accounts")
 | 
			
		||||
	}
 | 
			
		||||
	for _, account := range accounts {
 | 
			
		||||
		model.RegisterAccount(account)
 | 
			
		||||
		driver, ok := drivers.GetDriver(account.Type)
 | 
			
		||||
		if !ok {
 | 
			
		||||
			log.Error("no [%s] driver", driver)
 | 
			
		||||
		} else {
 | 
			
		||||
			err := driver.Save(&account, nil)
 | 
			
		||||
			if err != nil {
 | 
			
		||||
				log.Errorf("init account [%s] error:[%s]", account.Name, err.Error())
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func initSettings() {
 | 
			
		||||
	log.Infof("init settings...")
 | 
			
		||||
	version, err := model.GetSettingByKey("version")
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		log.Debugf("first run")
 | 
			
		||||
		version = &model.SettingItem{
 | 
			
		||||
			Key:         "version",
 | 
			
		||||
			Value:       "0.0.0",
 | 
			
		||||
			Description: "version",
 | 
			
		||||
			Type:        model.CONST,
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
	settingsMap := map[string][]model.SettingItem{
 | 
			
		||||
		"2.0.0": {
 | 
			
		||||
			{
 | 
			
		||||
				Key:         "title",
 | 
			
		||||
				Value:       "Alist",
 | 
			
		||||
				Description: "title",
 | 
			
		||||
				Type:        model.PUBLIC,
 | 
			
		||||
			},
 | 
			
		||||
			{
 | 
			
		||||
				Key:         "password",
 | 
			
		||||
				Value:       "alist",
 | 
			
		||||
				Description: "password",
 | 
			
		||||
				Type:        model.PRIVATE,
 | 
			
		||||
			},
 | 
			
		||||
			{
 | 
			
		||||
				Key:         "version",
 | 
			
		||||
				Value:       "2.0.0",
 | 
			
		||||
				Description: "version",
 | 
			
		||||
				Type:        model.CONST,
 | 
			
		||||
			},
 | 
			
		||||
			{
 | 
			
		||||
				Key:         "logo",
 | 
			
		||||
				Value:       "",
 | 
			
		||||
				Description: "logo",
 | 
			
		||||
				Type:        model.PUBLIC,
 | 
			
		||||
			},
 | 
			
		||||
		},
 | 
			
		||||
	}
 | 
			
		||||
	for k, v := range settingsMap {
 | 
			
		||||
		if utils.VersionCompare(k, version.Value) > 0 {
 | 
			
		||||
			log.Infof("writing [v%s] settings", k)
 | 
			
		||||
			err = model.SaveSettings(v)
 | 
			
		||||
			if err != nil {
 | 
			
		||||
				log.Fatalf("save settings error")
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -3,6 +3,7 @@ package conf
 | 
			
		|||
import (
 | 
			
		||||
	"context"
 | 
			
		||||
	"github.com/eko/gocache/v2/cache"
 | 
			
		||||
	"github.com/robfig/cron/v3"
 | 
			
		||||
	"gorm.io/gorm"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -14,6 +15,7 @@ var (
 | 
			
		|||
	DB *gorm.DB
 | 
			
		||||
	Cache *cache.Cache
 | 
			
		||||
	Ctx = context.TODO()
 | 
			
		||||
	Cron *cron.Cron
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
var (
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -1,11 +1,25 @@
 | 
			
		|||
package drivers
 | 
			
		||||
 | 
			
		||||
import (
 | 
			
		||||
	"fmt"
 | 
			
		||||
	"github.com/Xhofe/alist/conf"
 | 
			
		||||
	"github.com/Xhofe/alist/model"
 | 
			
		||||
	"github.com/go-resty/resty/v2"
 | 
			
		||||
	"github.com/robfig/cron/v3"
 | 
			
		||||
	log "github.com/sirupsen/logrus"
 | 
			
		||||
	"time"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
var aliClient = resty.New()
 | 
			
		||||
 | 
			
		||||
func init() {
 | 
			
		||||
	aliClient.
 | 
			
		||||
		SetRetryCount(3).
 | 
			
		||||
		SetHeader("user-agent", "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/87.0.4280.88 Safari/537.36").
 | 
			
		||||
		SetHeader("content-type", "application/json").
 | 
			
		||||
		SetHeader("origin", "https://aliyundrive.com")
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
type AliDrive struct {
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -43,11 +57,11 @@ type AliFile struct {
 | 
			
		|||
}
 | 
			
		||||
 | 
			
		||||
func (a AliDrive) Path(path string, account *model.Account) (*model.File, []*model.File, error) {
 | 
			
		||||
	_,err := conf.Cache.Get(conf.Ctx,path)
 | 
			
		||||
	_, err := conf.Cache.Get(conf.Ctx, path)
 | 
			
		||||
	if err == nil {
 | 
			
		||||
		// return
 | 
			
		||||
	}
 | 
			
		||||
	
 | 
			
		||||
 | 
			
		||||
	panic("implement me")
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -55,11 +69,61 @@ func (a AliDrive) Link(path string, account *model.Account) (string, error) {
 | 
			
		|||
	panic("implement me")
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
type AliTokenResp struct {
 | 
			
		||||
	AccessToken  string `json:"access_token"`
 | 
			
		||||
	RefreshToken string `json:"refresh_token"`
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func AliRefreshToken(refresh string) (string, string, error) {
 | 
			
		||||
	url := "https://auth.aliyundrive.com/v2/account/token"
 | 
			
		||||
	var resp AliTokenResp
 | 
			
		||||
	var e AliRespError
 | 
			
		||||
	_, err := aliClient.R().
 | 
			
		||||
		//ForceContentType("application/json").
 | 
			
		||||
		SetBody(JsonStr(Json{"refresh_token": refresh, "grant_type": "refresh_token"})).
 | 
			
		||||
		SetResult(&resp).
 | 
			
		||||
		SetError(&e).
 | 
			
		||||
		Post(url)
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		return "", "", err
 | 
			
		||||
	}
 | 
			
		||||
	log.Debugf("%+v,%+v", resp, e)
 | 
			
		||||
	if e.Code != "" {
 | 
			
		||||
		return "", "", fmt.Errorf("failed to refresh token: %s", e.Message)
 | 
			
		||||
	}
 | 
			
		||||
	return resp.RefreshToken, resp.AccessToken, nil
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (a AliDrive) Save(account *model.Account, old *model.Account) error {
 | 
			
		||||
	if old != nil {
 | 
			
		||||
		// TODO clear something
 | 
			
		||||
		conf.Cron.Remove(cron.EntryID(old.CronId))
 | 
			
		||||
	}
 | 
			
		||||
	panic("implement me")
 | 
			
		||||
	refresh, access, err := AliRefreshToken(account.RefreshToken)
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		return err
 | 
			
		||||
	}
 | 
			
		||||
	account.RefreshToken, account.AccessToken = refresh, access
 | 
			
		||||
	cronId, err := conf.Cron.AddFunc("@every 2h", func() {
 | 
			
		||||
		name := account.Name
 | 
			
		||||
		newAccount, ok := model.GetAccount(name)
 | 
			
		||||
		if !ok {
 | 
			
		||||
			return
 | 
			
		||||
		}
 | 
			
		||||
		newAccount.RefreshToken, newAccount.AccessToken, err = AliRefreshToken(newAccount.RefreshToken)
 | 
			
		||||
		if err != nil {
 | 
			
		||||
			newAccount.Status = err.Error()
 | 
			
		||||
		}
 | 
			
		||||
		_ = model.SaveAccount(newAccount)
 | 
			
		||||
	})
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		return err
 | 
			
		||||
	}
 | 
			
		||||
	account.CronId = int(cronId)
 | 
			
		||||
	err = model.SaveAccount(*account)
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		return err
 | 
			
		||||
	}
 | 
			
		||||
	return nil
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
var _ Driver = (*AliDrive)(nil)
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -1,6 +1,9 @@
 | 
			
		|||
package drivers
 | 
			
		||||
 | 
			
		||||
import "github.com/Xhofe/alist/model"
 | 
			
		||||
import (
 | 
			
		||||
	"encoding/json"
 | 
			
		||||
	"github.com/Xhofe/alist/model"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
type Driver interface {
 | 
			
		||||
	Path(path string, account *model.Account) (*model.File, []*model.File, error)
 | 
			
		||||
| 
						 | 
				
			
			@ -26,3 +29,10 @@ func GetDriverNames() []string {
 | 
			
		|||
	}
 | 
			
		||||
	return names
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
type Json map[string]interface{}
 | 
			
		||||
 | 
			
		||||
func JsonStr(j Json) string {
 | 
			
		||||
	data, _ := json.Marshal(j)
 | 
			
		||||
	return string(data)
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										2
									
								
								go.mod
								
								
								
								
							
							
						
						
									
										2
									
								
								go.mod
								
								
								
								
							| 
						 | 
				
			
			@ -25,6 +25,7 @@ require (
 | 
			
		|||
	github.com/go-playground/locales v0.14.0 // indirect
 | 
			
		||||
	github.com/go-playground/universal-translator v0.18.0 // indirect
 | 
			
		||||
	github.com/go-redis/redis/v8 v8.9.0 // indirect
 | 
			
		||||
	github.com/go-resty/resty/v2 v2.6.0 // indirect
 | 
			
		||||
	github.com/go-sql-driver/mysql v1.6.0 // indirect
 | 
			
		||||
	github.com/golang/protobuf v1.4.3 // indirect
 | 
			
		||||
	github.com/jackc/chunkreader/v2 v2.0.1 // indirect
 | 
			
		||||
| 
						 | 
				
			
			@ -46,6 +47,7 @@ require (
 | 
			
		|||
	github.com/prometheus/client_model v0.2.0 // indirect
 | 
			
		||||
	github.com/prometheus/common v0.18.0 // indirect
 | 
			
		||||
	github.com/prometheus/procfs v0.6.0 // indirect
 | 
			
		||||
	github.com/robfig/cron/v3 v3.0.0 // indirect
 | 
			
		||||
	github.com/spf13/cast v1.3.1 // indirect
 | 
			
		||||
	github.com/valyala/bytebufferpool v1.0.0 // indirect
 | 
			
		||||
	github.com/valyala/fasthttp v1.31.0 // indirect
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
							
								
								
									
										6
									
								
								go.sum
								
								
								
								
							
							
						
						
									
										6
									
								
								go.sum
								
								
								
								
							| 
						 | 
				
			
			@ -125,6 +125,8 @@ github.com/go-playground/validator/v10 v10.9.0 h1:NgTtmN58D0m8+UuxtYmGztBJB7VnPg
 | 
			
		|||
github.com/go-playground/validator/v10 v10.9.0/go.mod h1:74x4gJWsvQexRdW8Pn3dXSGrTK4nAUsbPlLADvpJkos=
 | 
			
		||||
github.com/go-redis/redis/v8 v8.9.0 h1:FTTbB7WqlXfVNdVv0SsxA+oVi0bAwit6bMe3IUucq2o=
 | 
			
		||||
github.com/go-redis/redis/v8 v8.9.0/go.mod h1:ik7vb7+gm8Izylxu6kf6wG26/t2VljgCfSQ1DM4O1uU=
 | 
			
		||||
github.com/go-resty/resty/v2 v2.6.0 h1:joIR5PNLM2EFqqESUjCMGXrWmXNHEU9CEiK813oKYS4=
 | 
			
		||||
github.com/go-resty/resty/v2 v2.6.0/go.mod h1:PwvJS6hvaPkjtjNg9ph+VrSD92bi5Zq73w/BIH7cC3Q=
 | 
			
		||||
github.com/go-sql-driver/mysql v1.4.0/go.mod h1:zAC/RDZ24gD3HViQzih4MyKcchzm+sOG5ZlKdlhCg5w=
 | 
			
		||||
github.com/go-sql-driver/mysql v1.6.0 h1:BCTh4TKNUYmOmMUcQ3IipzF5prigylS7XXjEkfCHuOE=
 | 
			
		||||
github.com/go-sql-driver/mysql v1.6.0/go.mod h1:DCzpHaOWr8IXmIStZouvnhqoel9Qv2LBy8hT2VhHyBg=
 | 
			
		||||
| 
						 | 
				
			
			@ -411,6 +413,8 @@ github.com/prometheus/procfs v0.1.3/go.mod h1:lV6e/gmhEcM9IjHGsFOCxxuZ+z1YqCvr4O
 | 
			
		|||
github.com/prometheus/procfs v0.6.0 h1:mxy4L2jP6qMonqmq+aTtOx1ifVWUgG/TAmntgbh3xv4=
 | 
			
		||||
github.com/prometheus/procfs v0.6.0/go.mod h1:cz+aTbrPOrUb4q7XlbU9ygM+/jj0fzG6c1xBZuNvfVA=
 | 
			
		||||
github.com/rcrowley/go-metrics v0.0.0-20181016184325-3113b8401b8a/go.mod h1:bCqnVzQkZxMG4s8nGwiZ5l3QUCyqpo9Y+/ZMZ9VjZe4=
 | 
			
		||||
github.com/robfig/cron/v3 v3.0.0 h1:kQ6Cb7aHOHTSzNVNEhmp8EcWKLb4CbiMW9h9VyIhO4E=
 | 
			
		||||
github.com/robfig/cron/v3 v3.0.0/go.mod h1:eQICP3HwyT7UooqI/z+Ov+PtYAWygg1TEWWzGIFLtro=
 | 
			
		||||
github.com/rogpeppe/fastuuid v0.0.0-20150106093220-6724a57986af/go.mod h1:XWv6SoW27p1b0cqNHllgS5HIMJraePCO15w5zCzIWYg=
 | 
			
		||||
github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4=
 | 
			
		||||
github.com/rogpeppe/go-internal v1.6.1/go.mod h1:xXDCJY+GAPziupqXw64V24skbSoqbTEfhy4qGm1nDQc=
 | 
			
		||||
| 
						 | 
				
			
			@ -546,6 +550,7 @@ golang.org/x/net v0.0.0-20200625001655-4c5254603344/go.mod h1:/O7V0waA8r7cgGh81R
 | 
			
		|||
golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU=
 | 
			
		||||
golang.org/x/net v0.0.0-20201202161906-c7110b5ffcbb/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU=
 | 
			
		||||
golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=
 | 
			
		||||
golang.org/x/net v0.0.0-20210405180319-a5a99cb37ef4/go.mod h1:p54w0d4576C0XHj96bSt6lcn1PtDYWL6XObtHCRCNQM=
 | 
			
		||||
golang.org/x/net v0.0.0-20210510120150-4163338589ed h1:p9UgmWI9wKpfYmgaV/IZKGdXc5qEK45tDwwwDyjS26I=
 | 
			
		||||
golang.org/x/net v0.0.0-20210510120150-4163338589ed/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
 | 
			
		||||
golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
 | 
			
		||||
| 
						 | 
				
			
			@ -593,6 +598,7 @@ golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7w
 | 
			
		|||
golang.org/x/sys v0.0.0-20210112080510-489259a85091/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
 | 
			
		||||
golang.org/x/sys v0.0.0-20210124154548-22da62e12c0c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
 | 
			
		||||
golang.org/x/sys v0.0.0-20210309074719-68d13333faf2/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
 | 
			
		||||
golang.org/x/sys v0.0.0-20210330210617-4fbd30eecc44/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
 | 
			
		||||
golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
 | 
			
		||||
golang.org/x/sys v0.0.0-20210514084401-e8d321eab015/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
 | 
			
		||||
golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
							
								
								
									
										66
									
								
								main.go
								
								
								
								
							
							
						
						
									
										66
									
								
								main.go
								
								
								
								
							| 
						 | 
				
			
			@ -1,81 +1,27 @@
 | 
			
		|||
package main
 | 
			
		||||
 | 
			
		||||
import (
 | 
			
		||||
	"encoding/json"
 | 
			
		||||
	"flag"
 | 
			
		||||
	"fmt"
 | 
			
		||||
	"github.com/Xhofe/alist/bootstrap"
 | 
			
		||||
	"github.com/Xhofe/alist/conf"
 | 
			
		||||
	"github.com/Xhofe/alist/model"
 | 
			
		||||
	"github.com/Xhofe/alist/public"
 | 
			
		||||
	"github.com/Xhofe/alist/server"
 | 
			
		||||
	"github.com/Xhofe/alist/utils"
 | 
			
		||||
	"github.com/allegro/bigcache/v3"
 | 
			
		||||
	"github.com/eko/gocache/v2/cache"
 | 
			
		||||
	"github.com/eko/gocache/v2/store"
 | 
			
		||||
	"github.com/gofiber/fiber/v2"
 | 
			
		||||
	"github.com/gofiber/fiber/v2/middleware/filesystem"
 | 
			
		||||
	log "github.com/sirupsen/logrus"
 | 
			
		||||
	"io/ioutil"
 | 
			
		||||
	"net/http"
 | 
			
		||||
	"time"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
// initLog init log
 | 
			
		||||
func initLog() {
 | 
			
		||||
	if conf.Debug {
 | 
			
		||||
		log.SetLevel(log.DebugLevel)
 | 
			
		||||
		log.SetReportCaller(true)
 | 
			
		||||
	}
 | 
			
		||||
	log.SetFormatter(&log.TextFormatter{
 | 
			
		||||
		//DisableColors: true,
 | 
			
		||||
		ForceColors:               true,
 | 
			
		||||
		EnvironmentOverrideColors: true,
 | 
			
		||||
		TimestampFormat:           "2006-01-02 15:04:05",
 | 
			
		||||
		FullTimestamp:             true,
 | 
			
		||||
	})
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// InitConf init config
 | 
			
		||||
func initConf() {
 | 
			
		||||
	log.Infof("reading config file: %s", conf.ConfigFile)
 | 
			
		||||
	if !utils.Exists(conf.ConfigFile) {
 | 
			
		||||
		log.Infof("config file not exists, creating default config file")
 | 
			
		||||
		conf.Conf = conf.DefaultConfig()
 | 
			
		||||
		if !utils.WriteToJson(conf.ConfigFile, conf.Conf) {
 | 
			
		||||
			log.Fatalf("failed to create default config file")
 | 
			
		||||
		}
 | 
			
		||||
		return
 | 
			
		||||
	}
 | 
			
		||||
	config, err := ioutil.ReadFile(conf.ConfigFile)
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		log.Fatalf("reading config file error:%s", err.Error())
 | 
			
		||||
	}
 | 
			
		||||
	conf.Conf = new(conf.Config)
 | 
			
		||||
	err = json.Unmarshal(config, conf.Conf)
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		log.Fatalf("load config error: %s", err.Error())
 | 
			
		||||
	}
 | 
			
		||||
	log.Debugf("config:%+v", conf.Conf)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func initCache() {
 | 
			
		||||
	log.Infof("init cache...")
 | 
			
		||||
	bigCacheConfig := bigcache.DefaultConfig(60 * time.Minute)
 | 
			
		||||
	bigCacheConfig.HardMaxCacheSize = 512
 | 
			
		||||
	bigCacheClient, _ := bigcache.NewBigCache(bigCacheConfig)
 | 
			
		||||
	bigCacheStore := store.NewBigcache(bigCacheClient, nil)
 | 
			
		||||
	conf.Cache = cache.New(bigCacheStore)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
func init() {
 | 
			
		||||
	flag.StringVar(&conf.ConfigFile, "conf", "config.json", "config file")
 | 
			
		||||
	flag.BoolVar(&conf.Debug,"debug",false,"start with debug mode")
 | 
			
		||||
	flag.Parse()
 | 
			
		||||
	initLog()
 | 
			
		||||
	initConf()
 | 
			
		||||
	model.InitModel()
 | 
			
		||||
	initCache()
 | 
			
		||||
	bootstrap.InitLog()
 | 
			
		||||
	bootstrap.InitConf()
 | 
			
		||||
	bootstrap.InitCron()
 | 
			
		||||
	bootstrap.InitModel()
 | 
			
		||||
	bootstrap.InitCache()
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func main() {
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -2,7 +2,6 @@ package model
 | 
			
		|||
 | 
			
		||||
import (
 | 
			
		||||
	"github.com/Xhofe/alist/conf"
 | 
			
		||||
	log "github.com/sirupsen/logrus"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
type Account struct {
 | 
			
		||||
| 
						 | 
				
			
			@ -22,6 +21,7 @@ type Account struct {
 | 
			
		|||
 | 
			
		||||
var accountsMap = map[string]Account{}
 | 
			
		||||
 | 
			
		||||
// SaveAccount save account to database
 | 
			
		||||
func SaveAccount(account Account) error {
 | 
			
		||||
	if err := conf.DB.Save(account).Error; err != nil {
 | 
			
		||||
		return err
 | 
			
		||||
| 
						 | 
				
			
			@ -80,14 +80,3 @@ func GetAccounts() []*Account {
 | 
			
		|||
	return accounts
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func initAccounts() {
 | 
			
		||||
	log.Infof("init accounts...")
 | 
			
		||||
	var accounts []Account
 | 
			
		||||
	if err := conf.DB.Find(&accounts).Error; err != nil {
 | 
			
		||||
		log.Fatalf("failed sync init accounts")
 | 
			
		||||
	}
 | 
			
		||||
	for _, account := range accounts {
 | 
			
		||||
		RegisterAccount(account)
 | 
			
		||||
	}
 | 
			
		||||
	log.Debugf("accounts:%+v", accountsMap)
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -2,8 +2,6 @@ package model
 | 
			
		|||
 | 
			
		||||
import (
 | 
			
		||||
	"github.com/Xhofe/alist/conf"
 | 
			
		||||
	"github.com/Xhofe/alist/utils"
 | 
			
		||||
	log "github.com/sirupsen/logrus"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
const (
 | 
			
		||||
| 
						 | 
				
			
			@ -39,47 +37,3 @@ func GetSettingByKey(key string) (*SettingItem, error) {
 | 
			
		|||
	return &items, nil
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func initSettings() {
 | 
			
		||||
	log.Infof("init settings...")
 | 
			
		||||
	version, err := GetSettingByKey("version")
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		log.Debugf("first run")
 | 
			
		||||
		version = &SettingItem{
 | 
			
		||||
			Key:         "version",
 | 
			
		||||
			Value:       "0.0.0",
 | 
			
		||||
			Description: "version",
 | 
			
		||||
			Type:        CONST,
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
	settingsMap := map[string][]SettingItem{
 | 
			
		||||
		"2.0.0": {
 | 
			
		||||
			{
 | 
			
		||||
				Key:         "title",
 | 
			
		||||
				Value:       "Alist",
 | 
			
		||||
				Description: "title",
 | 
			
		||||
				Type:        PUBLIC,
 | 
			
		||||
			},
 | 
			
		||||
			{
 | 
			
		||||
				Key:         "password",
 | 
			
		||||
				Value:       "alist",
 | 
			
		||||
				Description: "password",
 | 
			
		||||
				Type:        PRIVATE,
 | 
			
		||||
			},
 | 
			
		||||
			{
 | 
			
		||||
				Key:         "version",
 | 
			
		||||
				Value:       "2.0.0",
 | 
			
		||||
				Description: "version",
 | 
			
		||||
				Type:        CONST,
 | 
			
		||||
			},
 | 
			
		||||
		},
 | 
			
		||||
	}
 | 
			
		||||
	for k, v := range settingsMap {
 | 
			
		||||
		if utils.VersionCompare(k, version.Value) > 0 {
 | 
			
		||||
			log.Infof("writing [v%s] settings",k)
 | 
			
		||||
			err = SaveSettings(v)
 | 
			
		||||
			if err != nil {
 | 
			
		||||
				log.Fatalf("save settings error")
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -0,0 +1,24 @@
 | 
			
		|||
package server
 | 
			
		||||
 | 
			
		||||
import (
 | 
			
		||||
	"fmt"
 | 
			
		||||
	"github.com/Xhofe/alist/model"
 | 
			
		||||
	"github.com/Xhofe/alist/utils"
 | 
			
		||||
	"github.com/gofiber/fiber/v2"
 | 
			
		||||
	"gorm.io/gorm"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
func Auth(ctx *fiber.Ctx) error {
 | 
			
		||||
	token := ctx.Get("token")
 | 
			
		||||
	password, err := model.GetSettingByKey("password")
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		if err == gorm.ErrRecordNotFound {
 | 
			
		||||
			return ErrorResp(ctx, fmt.Errorf("password not set"), 400)
 | 
			
		||||
		}
 | 
			
		||||
		return ErrorResp(ctx, err, 500)
 | 
			
		||||
	}
 | 
			
		||||
	if token != utils.GetMD5Encode(password.Value) {
 | 
			
		||||
		return ErrorResp(ctx, fmt.Errorf("wrong password"), 401)
 | 
			
		||||
	}
 | 
			
		||||
	return ctx.Next()
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -10,11 +10,12 @@ func InitApiRouter(app *fiber.App) {
 | 
			
		|||
	{
 | 
			
		||||
		// TODO check accounts
 | 
			
		||||
		public.Post("/path", Path)
 | 
			
		||||
		public.Get("/settings", GetSettingsPublic)
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	admin := app.Group("/api/admin")
 | 
			
		||||
	{
 | 
			
		||||
		// TODO auth
 | 
			
		||||
		admin.Use(Auth)
 | 
			
		||||
		admin.Get("/settings", GetSettingsByType)
 | 
			
		||||
		admin.Post("/settings", SaveSettings)
 | 
			
		||||
		admin.Post("/account", SaveAccount)
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -36,3 +36,11 @@ func GetSettingsByType(ctx *fiber.Ctx) error {
 | 
			
		|||
	}
 | 
			
		||||
	return SuccessResp(ctx,settings)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func GetSettingsPublic(ctx *fiber.Ctx) error {
 | 
			
		||||
	settings, err := model.GetSettingByType(0)
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		return ErrorResp(ctx, err, 400)
 | 
			
		||||
	}
 | 
			
		||||
	return SuccessResp(ctx,settings)
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -1,7 +0,0 @@
 | 
			
		|||
package test
 | 
			
		||||
 | 
			
		||||
import "testing"
 | 
			
		||||
 | 
			
		||||
func TestName(t *testing.T) {
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -0,0 +1,18 @@
 | 
			
		|||
package utils
 | 
			
		||||
 | 
			
		||||
import (
 | 
			
		||||
	"crypto/md5"
 | 
			
		||||
	"encoding/hex"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
// GetMD5Encode
 | 
			
		||||
func GetMD5Encode(data string) string {
 | 
			
		||||
	h := md5.New()
 | 
			
		||||
	h.Write([]byte(data))
 | 
			
		||||
	return hex.EncodeToString(h.Sum(nil))
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Get16MD5Encode
 | 
			
		||||
func Get16MD5Encode(data string) string {
 | 
			
		||||
	return GetMD5Encode(data)[8:24]
 | 
			
		||||
}
 | 
			
		||||
		Loading…
	
		Reference in New Issue