Files
FileRelay/internal/bootstrap/init.go

112 lines
3.0 KiB
Go

package bootstrap
import (
"FileRelay/internal/config"
"FileRelay/internal/model"
"FileRelay/internal/storage"
"context"
"crypto/rand"
"fmt"
"log"
"math/big"
"github.com/glebarez/sqlite"
"golang.org/x/crypto/bcrypt"
"gorm.io/gorm"
)
var DB *gorm.DB
func InitDB() {
var err error
dbPath := config.GlobalConfig.Database.Path
if dbPath == "" {
dbPath = "file_relay.db"
}
DB, err = gorm.Open(sqlite.Open(dbPath), &gorm.Config{})
if err != nil {
log.Fatalf("Failed to connect to database: %v", err)
}
// 自动迁移
err = DB.AutoMigrate(
&model.FileBatch{},
&model.FileItem{},
&model.APIToken{},
)
if err != nil {
log.Fatalf("Failed to migrate database: %v", err)
}
fmt.Println("Database initialized and migrated.")
// 初始化存储
if err := ReloadStorage(); err != nil {
log.Fatalf("Failed to initialize storage: %v", err)
}
// 初始化管理员 (如果不存在)
initAdmin()
}
func ReloadStorage() error {
storageType := config.GlobalConfig.Storage.Type
switch storageType {
case "local":
storage.GlobalStorage = storage.NewLocalStorage(config.GlobalConfig.Storage.Local.Path)
case "webdav":
cfg := config.GlobalConfig.Storage.WebDAV
storage.GlobalStorage = storage.NewWebDAVStorage(cfg.URL, cfg.Username, cfg.Password, cfg.Root)
case "s3":
cfg := config.GlobalConfig.Storage.S3
s3Storage, err := storage.NewS3Storage(context.Background(), cfg.Endpoint, cfg.Region, cfg.AccessKey, cfg.SecretKey, cfg.Bucket, cfg.UseSSL)
if err != nil {
return err
}
storage.GlobalStorage = s3Storage
default:
return fmt.Errorf("unsupported storage type: %s", storageType)
}
fmt.Printf("Storage initialized with type: %s\n", storageType)
return nil
}
func initAdmin() {
passwordHash := config.GlobalConfig.Security.AdminPasswordHash
if passwordHash == "" {
// 生成随机密码
password := generateRandomPassword(12)
hash, err := bcrypt.GenerateFromPassword([]byte(password), bcrypt.DefaultCost)
if err != nil {
log.Fatalf("Failed to generate password hash: %v", err)
}
passwordHash = string(hash)
fmt.Printf("**************************************************\n")
fmt.Printf("NO ADMIN PASSWORD CONFIGURED. GENERATED RANDOM PASSWORD:\n")
fmt.Printf("Password: %s\n", password)
fmt.Printf("Please save this password or configure admin_password_hash in config.yaml\n")
fmt.Printf("**************************************************\n")
// 将生成的哈希保存回配置文件
config.GlobalConfig.Security.AdminPasswordHash = passwordHash
if err := config.SaveConfig(); err != nil {
fmt.Printf("Warning: Failed to save generated password hash to config: %v\n", err)
}
}
fmt.Println("Admin authentication initialized via config.")
}
func generateRandomPassword(length int) string {
const charset = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*"
b := make([]byte, length)
for i := range b {
num, err := rand.Int(rand.Reader, big.NewInt(int64(len(charset))))
if err != nil {
return "admin123" // 退路
}
b[i] = charset[num.Int64()]
}
return string(b)
}