fix(server): add initer
This commit is contained in:
parent
becfa688aa
commit
b54275771e
3 changed files with 85 additions and 64 deletions
|
@ -6,6 +6,7 @@ import (
|
|||
"crypto/sha1"
|
||||
"errors"
|
||||
"fmt"
|
||||
"io"
|
||||
"os"
|
||||
"path"
|
||||
|
||||
|
@ -31,23 +32,37 @@ import (
|
|||
"github.com/ihexxa/quickshare/src/worker/localworker"
|
||||
)
|
||||
|
||||
func initDeps(cfg gocfg.ICfg) *depidx.Deps {
|
||||
ider := simpleidgen.New()
|
||||
logger := initLogger(cfg)
|
||||
jwtEncDec := initJWT(cfg, logger)
|
||||
workers := initWorkerPool(cfg, logger)
|
||||
filesystem, err := initFs(cfg, ider, logger)
|
||||
if err != nil {
|
||||
logger.Fatalf("failed to init DB: %s", err)
|
||||
type Initer struct {
|
||||
cfg gocfg.ICfg
|
||||
input io.Reader
|
||||
output io.Writer
|
||||
}
|
||||
quickshareDb, err := initDb(cfg, filesystem)
|
||||
if err != nil {
|
||||
logger.Fatalf("failed to init DB: %s", err)
|
||||
}
|
||||
rateLimiter := initRateLimiter(cfg, quickshareDb)
|
||||
fileIndex := initSearchIndex(cfg, filesystem, logger)
|
||||
|
||||
deps := depidx.NewDeps(cfg)
|
||||
func NewIniter(cfg gocfg.ICfg) *Initer {
|
||||
return &Initer{
|
||||
cfg: cfg,
|
||||
input: os.Stdin,
|
||||
output: os.Stdout,
|
||||
}
|
||||
}
|
||||
|
||||
func (it *Initer) InitDeps() *depidx.Deps {
|
||||
ider := simpleidgen.New()
|
||||
logger := it.initLogger()
|
||||
jwtEncDec := it.initJWT(logger)
|
||||
workers := it.initWorkerPool(logger)
|
||||
filesystem, err := it.initFs(ider, logger)
|
||||
if err != nil {
|
||||
logger.Fatalf("failed to init DB: %s", err)
|
||||
}
|
||||
quickshareDb, err := it.initDb(filesystem)
|
||||
if err != nil {
|
||||
logger.Fatalf("failed to init DB: %s", err)
|
||||
}
|
||||
rateLimiter := it.initRateLimiter(quickshareDb)
|
||||
fileIndex := it.initSearchIndex(filesystem, logger)
|
||||
|
||||
deps := depidx.NewDeps(it.cfg)
|
||||
deps.SetDB(quickshareDb)
|
||||
deps.SetFS(filesystem)
|
||||
deps.SetToken(jwtEncDec)
|
||||
|
@ -60,12 +75,12 @@ func initDeps(cfg gocfg.ICfg) *depidx.Deps {
|
|||
return deps
|
||||
}
|
||||
|
||||
func initLogger(cfg gocfg.ICfg) *zap.SugaredLogger {
|
||||
func (it *Initer) initLogger() *zap.SugaredLogger {
|
||||
fileWriter := zapcore.AddSync(&lumberjack.Logger{
|
||||
Filename: path.Join(cfg.GrabString("Fs.Root"), "quickshare.log"),
|
||||
MaxSize: cfg.IntOr("Log.MaxSize", 50), // megabytes
|
||||
MaxBackups: cfg.IntOr("Log.MaxBackups", 2),
|
||||
MaxAge: cfg.IntOr("Log.MaxAge", 31), // days
|
||||
Filename: path.Join(it.cfg.GrabString("Fs.Root"), "quickshare.log"),
|
||||
MaxSize: it.cfg.IntOr("Log.MaxSize", 50), // megabytes
|
||||
MaxBackups: it.cfg.IntOr("Log.MaxBackups", 2),
|
||||
MaxAge: it.cfg.IntOr("Log.MaxAge", 31), // days
|
||||
})
|
||||
stdoutWriter := zapcore.AddSync(os.Stdout)
|
||||
|
||||
|
@ -79,13 +94,13 @@ func initLogger(cfg gocfg.ICfg) *zap.SugaredLogger {
|
|||
return zap.New(core).Sugar()
|
||||
}
|
||||
|
||||
func initJWT(cfg gocfg.ICfg, logger *zap.SugaredLogger) cryptoutil.ITokenEncDec {
|
||||
secret, ok := cfg.String("ENV.TOKENSECRET")
|
||||
func (it *Initer) initJWT(logger *zap.SugaredLogger) cryptoutil.ITokenEncDec {
|
||||
secret, ok := it.cfg.String("ENV.TOKENSECRET")
|
||||
if !ok {
|
||||
b := make([]byte, 32)
|
||||
_, err := rand.Read(b)
|
||||
if err != nil {
|
||||
panic(fmt.Sprintf("make rand token error: %s", err))
|
||||
logger.Fatalf("make rand token error: %s", err)
|
||||
}
|
||||
secret = string(b)
|
||||
logger.Info("warning: TOKENSECRET is not set, a random token is generated")
|
||||
|
@ -94,24 +109,24 @@ func initJWT(cfg gocfg.ICfg, logger *zap.SugaredLogger) cryptoutil.ITokenEncDec
|
|||
return jwt.NewJWTEncDec(secret)
|
||||
}
|
||||
|
||||
func initRateLimiter(cfg gocfg.ICfg, quickshareDb db.IDBQuickshare) iolimiter.ILimiter {
|
||||
limiterCap := cfg.IntOr("Users.LimiterCapacity", 10000)
|
||||
limiterCyc := cfg.IntOr("Users.LimiterCyc", 1000)
|
||||
func (it *Initer) initRateLimiter(quickshareDb db.IDBQuickshare) iolimiter.ILimiter {
|
||||
limiterCap := it.cfg.IntOr("Users.LimiterCapacity", 10000)
|
||||
limiterCyc := it.cfg.IntOr("Users.LimiterCyc", 1000)
|
||||
return iolimiter.NewIOLimiter(limiterCap, limiterCyc, quickshareDb)
|
||||
}
|
||||
|
||||
func initWorkerPool(cfg gocfg.ICfg, logger *zap.SugaredLogger) worker.IWorkerPool {
|
||||
queueSize := cfg.GrabInt("Workers.QueueSize")
|
||||
sleepCyc := cfg.GrabInt("Workers.SleepCyc")
|
||||
workerCount := cfg.GrabInt("Workers.WorkerCount")
|
||||
func (it *Initer) initWorkerPool(logger *zap.SugaredLogger) worker.IWorkerPool {
|
||||
queueSize := it.cfg.GrabInt("Workers.QueueSize")
|
||||
sleepCyc := it.cfg.GrabInt("Workers.SleepCyc")
|
||||
workerCount := it.cfg.GrabInt("Workers.WorkerCount")
|
||||
|
||||
workers := localworker.NewWorkerPool(queueSize, sleepCyc, workerCount, logger)
|
||||
workers.Start()
|
||||
return workers
|
||||
}
|
||||
|
||||
func initSearchIndex(cfg gocfg.ICfg, filesystem fs.ISimpleFS, logger *zap.SugaredLogger) fileindex.IFileIndex {
|
||||
searchResultLimit := cfg.GrabInt("Server.SearchResultLimit")
|
||||
func (it *Initer) initSearchIndex(filesystem fs.ISimpleFS, logger *zap.SugaredLogger) fileindex.IFileIndex {
|
||||
searchResultLimit := it.cfg.GrabInt("Server.SearchResultLimit")
|
||||
fileIndex := fileindex.NewFileTreeIndex(filesystem, "/", searchResultLimit)
|
||||
|
||||
indexInited := false
|
||||
|
@ -137,11 +152,11 @@ func initSearchIndex(cfg gocfg.ICfg, filesystem fs.ISimpleFS, logger *zap.Sugare
|
|||
return fileIndex
|
||||
}
|
||||
|
||||
func initFs(cfg gocfg.ICfg, idGenerator idgen.IIDGen, logger *zap.SugaredLogger) (fs.ISimpleFS, error) {
|
||||
rootPath := cfg.GrabString("Fs.Root")
|
||||
opensLimit := cfg.GrabInt("Fs.OpensLimit")
|
||||
openTTL := cfg.GrabInt("Fs.OpenTTL")
|
||||
readerTTL := cfg.GrabInt("Server.WriteTimeout") / 1000 // millisecond -> second
|
||||
func (it *Initer) initFs(idGenerator idgen.IIDGen, logger *zap.SugaredLogger) (fs.ISimpleFS, error) {
|
||||
rootPath := it.cfg.GrabString("Fs.Root")
|
||||
opensLimit := it.cfg.GrabInt("Fs.OpensLimit")
|
||||
openTTL := it.cfg.GrabInt("Fs.OpenTTL")
|
||||
readerTTL := it.cfg.GrabInt("Server.WriteTimeout") / 1000 // millisecond -> second
|
||||
|
||||
info, err := os.Stat(rootPath)
|
||||
if err != nil {
|
||||
|
@ -160,8 +175,8 @@ func initFs(cfg gocfg.ICfg, idGenerator idgen.IIDGen, logger *zap.SugaredLogger)
|
|||
return local.NewLocalFS(rootPath, 0660, opensLimit, openTTL, readerTTL, idGenerator), nil
|
||||
}
|
||||
|
||||
func initDb(cfg gocfg.ICfg, filesystem fs.ISimpleFS) (db.IDBQuickshare, error) {
|
||||
dbPath := cfg.GrabString("Db.DbPath")
|
||||
func (it *Initer) initDb(filesystem fs.ISimpleFS) (db.IDBQuickshare, error) {
|
||||
dbPath := it.cfg.GrabString("Db.DbPath")
|
||||
dbDir := path.Dir(dbPath)
|
||||
|
||||
sqliteDB, err := sqlite.NewSQLite(path.Join(filesystem.Root(), dbPath))
|
||||
|
@ -192,19 +207,23 @@ func initDb(cfg gocfg.ICfg, filesystem fs.ISimpleFS) (db.IDBQuickshare, error) {
|
|||
return nil, fmt.Errorf("failed to create path for db: %w", err)
|
||||
}
|
||||
|
||||
adminName, ok = cfg.String("ENV.DEFAULTADMIN")
|
||||
adminName, ok = it.cfg.String("ENV.DEFAULTADMIN")
|
||||
if !ok || adminName == "" {
|
||||
fmt.Println("Please input admin name: ")
|
||||
fmt.Scanf("%s", &adminName)
|
||||
fmt.Fprintln(it.output, "Please input admin name: ")
|
||||
fmt.Fscanf(it.input, "%s", &adminName)
|
||||
}
|
||||
|
||||
adminPwd, _ := cfg.String("ENV.DEFAULTADMINPWD")
|
||||
adminPwd, _ := it.cfg.String("ENV.DEFAULTADMINPWD")
|
||||
if adminPwd == "" {
|
||||
adminPwd, err = generatePwd()
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("generate password error: %w", err)
|
||||
}
|
||||
fmt.Printf("password is generated: %s, please update it immediately after login\n", adminPwd)
|
||||
fmt.Fprintf(
|
||||
it.output,
|
||||
"password is generated: %s, please update it immediately after login\n",
|
||||
adminPwd,
|
||||
)
|
||||
}
|
||||
|
||||
pwdHash, err = bcrypt.GenerateFromPassword([]byte(adminPwd), 10)
|
||||
|
@ -212,22 +231,24 @@ func initDb(cfg gocfg.ICfg, filesystem fs.ISimpleFS) (db.IDBQuickshare, error) {
|
|||
return nil, fmt.Errorf("hashing password error: %w", err)
|
||||
}
|
||||
|
||||
cfg.SetString("ENV.DEFAULTADMIN", adminName)
|
||||
cfg.SetString("ENV.DEFAULTADMINPWD", string(pwdHash))
|
||||
it.cfg.SetString("ENV.DEFAULTADMIN", adminName)
|
||||
it.cfg.SetString("ENV.DEFAULTADMINPWD", adminPwd)
|
||||
it.cfg.SetString("ENV.DEFAULTADMINPWDHASH", string(pwdHash))
|
||||
|
||||
siteCfg := &db.SiteConfig{
|
||||
ClientCfg: &db.ClientConfig{
|
||||
SiteName: cfg.StringOr("Site.ClientCfg.SiteName", "Quickshare"),
|
||||
SiteDesc: cfg.StringOr("Site.ClientCfg.SiteDesc", "Quick and simple file sharing"),
|
||||
SiteName: it.cfg.StringOr("Site.ClientCfg.SiteName", "Quickshare"),
|
||||
SiteDesc: it.cfg.StringOr("Site.ClientCfg.SiteDesc", "Quick and simple file sharing"),
|
||||
Bg: &db.BgConfig{
|
||||
Url: cfg.StringOr("Site.ClientCfg.Bg.Url", ""),
|
||||
Repeat: cfg.StringOr("Site.ClientCfg.Bg.Repeat", "repeat"),
|
||||
Position: cfg.StringOr("Site.ClientCfg.Bg.Position", "center"),
|
||||
Align: cfg.StringOr("Site.ClientCfg.Bg.Align", "fixed"),
|
||||
BgColor: cfg.StringOr("Site.ClientCfg.Bg.BgColor", ""),
|
||||
Url: it.cfg.StringOr("Site.ClientCfg.Bg.Url", ""),
|
||||
Repeat: it.cfg.StringOr("Site.ClientCfg.Bg.Repeat", "repeat"),
|
||||
Position: it.cfg.StringOr("Site.ClientCfg.Bg.Position", "center"),
|
||||
Align: it.cfg.StringOr("Site.ClientCfg.Bg.Align", "fixed"),
|
||||
BgColor: it.cfg.StringOr("Site.ClientCfg.Bg.BgColor", ""),
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
err = dbQuickshare.Init(context.TODO(), adminName, string(pwdHash), siteCfg)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to init tables: %w %s", err, dbPath)
|
||||
|
|
|
@ -7,7 +7,6 @@ import (
|
|||
|
||||
"github.com/gin-contrib/static"
|
||||
"github.com/gin-gonic/gin"
|
||||
"github.com/ihexxa/gocfg"
|
||||
|
||||
"github.com/ihexxa/quickshare/src/depidx"
|
||||
"github.com/ihexxa/quickshare/src/handlers/fileshdr"
|
||||
|
@ -16,26 +15,26 @@ import (
|
|||
qsstatic "github.com/ihexxa/quickshare/static"
|
||||
)
|
||||
|
||||
func initHandlers(cfg gocfg.ICfg, deps *depidx.Deps) (*gin.Engine, error) {
|
||||
func (it *Initer) InitHandlers(deps *depidx.Deps) (*gin.Engine, error) {
|
||||
router := gin.Default()
|
||||
|
||||
// handlers
|
||||
userHdrs, err := multiusers.NewMultiUsersSvc(cfg, deps)
|
||||
userHdrs, err := multiusers.NewMultiUsersSvc(it.cfg, deps)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("new users svc error: %w", err)
|
||||
}
|
||||
|
||||
adminName := cfg.GrabString("ENV.DEFAULTADMIN")
|
||||
adminName := it.cfg.GrabString("ENV.DEFAULTADMIN")
|
||||
_, err = userHdrs.Init(context.TODO(), adminName)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to init user handlers: %w", err)
|
||||
}
|
||||
|
||||
fileHdrs, err := fileshdr.NewFileHandlers(cfg, deps)
|
||||
fileHdrs, err := fileshdr.NewFileHandlers(it.cfg, deps)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("new files service error: %w", err)
|
||||
}
|
||||
settingsSvc, err := settings.NewSettingsSvc(cfg, deps)
|
||||
settingsSvc, err := settings.NewSettingsSvc(it.cfg, deps)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("new setting service error: %w", err)
|
||||
}
|
||||
|
@ -44,11 +43,11 @@ func initHandlers(cfg gocfg.ICfg, deps *depidx.Deps) (*gin.Engine, error) {
|
|||
router.Use(userHdrs.AuthN())
|
||||
router.Use(userHdrs.APIAccessControl())
|
||||
|
||||
publicPath, ok := cfg.String("Server.PublicPath")
|
||||
publicPath, ok := it.cfg.String("Server.PublicPath")
|
||||
if !ok || publicPath == "" {
|
||||
return nil, errors.New("publicPath not found or empty")
|
||||
}
|
||||
if cfg.BoolOr("Server.Debug", false) {
|
||||
if it.cfg.BoolOr("Server.Debug", false) {
|
||||
router.Use(static.Serve("/", static.LocalFile(publicPath, false)))
|
||||
} else {
|
||||
embedFs, err := qsstatic.NewEmbedStaticFS()
|
||||
|
|
|
@ -31,8 +31,9 @@ func NewServer(cfg gocfg.ICfg) (*Server, error) {
|
|||
gin.SetMode(gin.ReleaseMode)
|
||||
}
|
||||
|
||||
deps := initDeps(cfg)
|
||||
router, err := initHandlers(cfg, deps)
|
||||
initer := NewIniter(cfg)
|
||||
deps := initer.InitDeps()
|
||||
router, err := initer.InitHandlers(deps)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("init handlers error: %w", err)
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue