2025-10-10 07:13:36 -07:00

457 lines
17 KiB
Go

package patch
import (
"github.com/perfect-panel/ppanel-server/initialize/migrate"
"github.com/perfect-panel/ppanel-server/internal/model/application"
"github.com/perfect-panel/ppanel-server/internal/model/auth"
"github.com/perfect-panel/ppanel-server/internal/model/log"
"github.com/perfect-panel/ppanel-server/internal/model/server"
"github.com/perfect-panel/ppanel-server/internal/model/system"
"github.com/perfect-panel/ppanel-server/internal/model/user"
"github.com/perfect-panel/ppanel-server/pkg/email"
"github.com/perfect-panel/ppanel-server/pkg/logger"
"github.com/perfect-panel/ppanel-server/pkg/sms"
"gorm.io/gorm"
)
func Migrate01200(db *gorm.DB) error {
var version = "0.1.2(01200)"
return db.Transaction(func(tx *gorm.DB) error {
if exists := db.Migrator().HasColumn(&user.OldUser{}, "email"); !exists {
logger.Debug("Migrate 01200 skipped", logger.Field("reason", "old user table not exists"))
return nil
}
logger.Debug("Migrate 01200 started", logger.Field("step", "1"), logger.Field("action", "migrate old user to user auth methods"))
var users []*user.OldUser
if err := tx.Model(&user.OldUser{}).Find(&users).Error; err != nil {
return err
}
if err := tx.Migrator().AutoMigrate(&user.AuthMethods{}); err != nil {
logger.Errorw("Migrate 01200 failed", logger.Field("step", "1"), logger.Field("action", "create user auth methods table"), logger.Field("error", err.Error()))
return err
}
err := tx.Transaction(func(tx *gorm.DB) error {
for _, oldUser := range users {
if oldUser.Email == "" {
continue
}
// create user auth method
authMethod := &user.AuthMethods{
UserId: oldUser.Id,
AuthType: "email",
AuthIdentifier: oldUser.Email,
Verified: false,
}
if err := tx.Create(authMethod).Error; err != nil {
return err
}
}
return nil
})
if err != nil {
logger.Errorw("Migrate 01200 failed", logger.Field("step", "1"), logger.Field("action", "migrate old user to user auth methods"), logger.Field("error", err.Error()))
return err
}
logger.Debug("Migrate 01200 completed", logger.Field("step", "1"), logger.Field("action", "migrate old user to user auth methods"))
logger.Debug("Migrate 01200 started", logger.Field("step", "2"), logger.Field("action", "exclude sql files"))
// exclude sql files
if err := migrate.ExecuteSQLFile(tx, "database/01200-patch.sql"); err != nil {
logger.Errorw("Migrate 01200 failed", logger.Field("step", "2"), logger.Field("action", "exclude sql files"), logger.Field("file", "database/01200-patch.sql"), logger.Field("error", err.Error()))
return err
}
logger.Debug("Migrate 01200 completed", logger.Field("step", "2"), logger.Field("action", "exclude sql files"))
logger.Debug("Migrate 01200 started", logger.Field("step", "3"), logger.Field("action", "update system config"))
versionConfig := &system.System{
Category: "system",
Key: "Version",
Value: version,
Type: "string",
Desc: "Version of the system, eg: 1.0.0(10000)",
}
// update system config
if err := tx.Model(&system.System{}).Where("`category` = 'system' AND `key` = 'Version'").Save(&versionConfig).Error; err != nil {
logger.Errorw("Migrate 01200 failed", logger.Field("step", "3"), logger.Field("action", "update system config"), logger.Field("error", err.Error()))
return err
}
return nil
})
}
func Migrate01201(db *gorm.DB) error {
version := "0.1.2(01201)"
// exclude sql files
if err := migrate.ExecuteSQLFile(db, "database/01201-patch.sql"); err != nil {
logger.Errorw("Migrate 01201 failed", logger.Field("step", "1"), logger.Field("action", "exclude sql files"), logger.Field("file", "database/01200-patch.sql"), logger.Field("error", err.Error()))
return err
}
// update system config
if err := db.Model(&system.System{}).Where("`category` = 'system' AND `key` = 'Version'").Update("value", version).Error; err != nil {
logger.Errorw("Migrate 01201 failed", logger.Field("step", "2"), logger.Field("action", "update system config"), logger.Field("error", err.Error()))
return err
}
return nil
}
func Migrate01202(db *gorm.DB) error {
version := "0.1.2(01202)"
return db.Transaction(func(tx *gorm.DB) error {
// migrate email config to system config
if err := db.Migrator().AutoMigrate(&auth.Auth{}); err != nil {
logger.Errorw("Migrate01202: AutoMigrate Auth failed", logger.Field("version", version), logger.Field("error", err.Error()))
return err
}
if db.Migrator().HasColumn("oauth_config", "platform") {
if err := db.Migrator().RenameColumn("oauth_config", "platform", "method"); err != nil {
logger.Errorw("Migrate01202: RenameColumn platform to method failed", logger.Field("version", version), logger.Field("error", err.Error()))
}
}
// init email config
if err := initEmailConfig(db); err != nil {
logger.Errorw("Migrate01202: initEmailConfig failed", logger.Field("version", version), logger.Field("error", err.Error()))
return err
}
// init mobile config
if err := initMobileConfig(db); err != nil {
logger.Errorw("Migrate01202: initMobileConfig failed", logger.Field("version", version), logger.Field("error", err.Error()))
return err
}
// drop oauth_config table
err := db.Migrator().DropTable("oauth_config")
if err != nil {
logger.Debug("Migrate01202: DropTable oauth_config failed", logger.Field("version", version), logger.Field("error", err.Error()))
}
// exclude sql files
if err := migrate.ExecuteSQLFile(db, "database/01202-patch.sql"); err != nil {
logger.Errorw("Migrate 01202 failed", logger.Field("action", "exclude sql files"), logger.Field("file", "database/012002-patch.sql"), logger.Field("error", err.Error()))
return err
}
// update system config
if err := db.Model(&system.System{}).Where("`category` = 'system' AND `key` = 'Version'").Update("value", version).Error; err != nil {
logger.Errorw("Migrate 01202 failed", logger.Field("step", "2"), logger.Field("action", "update system config"), logger.Field("error", err.Error()))
return err
}
return nil
})
}
func Migrate01203(db *gorm.DB) error {
version := "0.1.2(01203)"
return db.Transaction(func(tx *gorm.DB) error {
if err := db.AutoMigrate(&user.LoginLog{}, &user.SubscribeLog{}); err != nil {
logger.Errorw("Migrate01203: AutoMigrate LoginLog/SubscribeLog failed", logger.Field("version", version), logger.Field("error", err.Error()))
return err
}
// update version
if err := db.Model(&system.System{}).Where("`category` = 'system' AND `key` = 'Version'").Update("value", version).Error; err != nil {
logger.Errorw("Migrate01203: Update Version failed", logger.Field("version", version), logger.Field("error", err.Error()))
return err
}
return nil
})
}
func Migrate01204(db *gorm.DB) error {
version := "0.1.2(01204)"
return db.Transaction(func(tx *gorm.DB) error {
if err := db.AutoMigrate(&log.MessageLog{}); err != nil {
logger.Errorw("Migrate01204: AutoMigrate MessageLog failed", logger.Field("version", version), logger.Field("error", err.Error()))
return err
}
// Trial configuration
if err := initTrialConfig(tx); err != nil {
logger.Errorw("Migrate01204: initTrialConfig failed", logger.Field("version", version), logger.Field("error", err.Error()))
return err
}
// Add auth method with device
if err := addAuthMethodWithDevice(tx); err != nil {
logger.Errorw("Migrate01204: Add auth method with device failed", logger.Field("version", version), logger.Field("error", err.Error()))
return err
}
// update version
if err := db.Model(&system.System{}).Where("`category` = 'system' AND `key` = 'Version'").Update("value", version).Error; err != nil {
logger.Errorw("Migrate01204: Update Version failed", logger.Field("version", version), logger.Field("error", err.Error()))
return err
}
return nil
})
}
func Migrate01205(db *gorm.DB) error {
version := "0.1.2(01205)"
return db.Transaction(func(tx *gorm.DB) error {
// Add VerifyCode public configuration
configs := []system.System{
{
Category: "verify_code",
Key: "VerifyCodeExpireTime",
Value: "5",
Type: "int",
Desc: "Verify code expire time",
},
{
Category: "verify_code",
Key: "VerifyCodeLimit",
Value: "15",
Type: "int",
Desc: "limits of verify code",
},
{
Category: "verify_code",
Key: "VerifyCodeInterval",
Value: "60",
Type: "int",
Desc: "Interval of verify code",
},
}
if err := tx.Model(&system.System{}).Save(&configs).Error; err != nil {
logger.Errorw("Migrate01205: Save VerifyCode public configuration failed", logger.Field("error", err.Error()))
return err
}
// update version
if err := db.Model(&system.System{}).Where("`category` = 'system' AND `key` = 'Version'").Update("value", version).Error; err != nil {
logger.Errorw("Migrate01205: Update Version failed", logger.Field("version", version), logger.Field("error", err.Error()))
return err
}
return nil
})
}
func Migrate01301(db *gorm.DB) error {
version := "0.1.3(01301)"
return db.Transaction(func(tx *gorm.DB) error {
err := tx.Migrator().AlterColumn(&application.Application{}, "icon")
if err != nil {
logger.Errorw("Migrate01301: AlterColumn failed", logger.Field("error", err.Error()))
return err
}
// update version
if err := db.Model(&system.System{}).Where("`category` = 'system' AND `key` = 'Version'").Update("value", version).Error; err != nil {
logger.Errorw("Migrate01205: Update Version failed", logger.Field("version", version), logger.Field("error", err.Error()))
return err
}
return nil
})
}
func Migrate01602(db *gorm.DB) error {
version := "0.1.6(01602)"
return db.Transaction(func(tx *gorm.DB) error {
if tx.Model(&system.System{}).Where("`category` = 'tos' AND `key` = 'TosContent'").Find(&system.System{}).RowsAffected == 0 {
if err := tx.Save(&system.System{
Category: "tos",
Key: "TosContent",
Value: "Welcome to use Perfect Panel",
Type: "string",
Desc: "Terms of Service",
}).Error; err != nil {
return err
}
}
// update version
if err := tx.Model(&system.System{}).Where("`category` = 'system' AND `key` = 'Version'").Update("value", version).Error; err != nil {
return err
}
return nil
})
}
func Migrate01701(db *gorm.DB) error {
return db.Transaction(func(tx *gorm.DB) error {
version := "0.1.7(01701)"
if err := db.Migrator().AlterColumn(&user.User{}, "Avatar"); err != nil {
return err
}
// update version
if err := tx.Model(&system.System{}).Where("`category` = 'system' AND `key` = 'Version'").Update("value", version).Error; err != nil {
return err
}
return nil
})
}
func Migrate01702(db *gorm.DB) error {
return db.Transaction(func(tx *gorm.DB) error {
version := "0.1.7(01702)"
if tx.Model(&system.System{}).Where("`category` = 'site' AND `key` = 'Keywords'").Find(&system.System{}).RowsAffected == 0 {
if err := tx.Save(&system.System{
Category: "site",
Key: "Keywords",
Value: "Perfect Panel,PPanel",
Type: "string",
Desc: "Keywords",
}).Error; err != nil {
return err
}
}
if tx.Model(&system.System{}).Where("`category` = 'site' AND `key` = 'CustomHTML'").Find(&system.System{}).RowsAffected == 0 {
if err := tx.Save(&system.System{
Category: "site",
Key: "CustomHTML",
Value: "",
Type: "string",
Desc: "Custom HTML",
}).Error; err != nil {
return err
}
}
// update version
if err := tx.Model(&system.System{}).Where("`category` = 'system' AND `key` = 'Version'").Update("value", version).Error; err != nil {
return err
}
return nil
})
}
func Migrate01703(db *gorm.DB) error {
version := "0.1.7(01703)"
return db.Transaction(func(tx *gorm.DB) error {
if tx.Model(&system.System{}).Where("`category` = 'tos' AND `key` = 'PrivacyPolicy'").Find(&system.System{}).RowsAffected == 0 {
if err := tx.Save(&system.System{
Category: "tos",
Key: "PrivacyPolicy",
Value: "",
Type: "string",
Desc: "Privacy Policy",
}).Error; err != nil {
return err
}
}
return tx.Model(&system.System{}).Where("`category` = 'system' AND `key` = 'Version'").Update("value", version).Error
})
}
func Migrate01704(db *gorm.DB) error {
version := "0.1.7(01704)"
// check server table latitude column exists, if not exists, create it
if exists := db.Migrator().HasColumn(&server.Server{}, "latitude"); !exists {
if err := db.Migrator().AddColumn(&server.Server{}, "latitude"); err != nil {
logger.Errorw("Migrate 01704 failed", logger.Field("action", "add latitude column"), logger.Field("error", err.Error()))
return err
}
logger.Infow("Migrate 01704 success", logger.Field("action", "add latitude column"))
}
// check server table longitude column exists, if not exists, create it
if exists := db.Migrator().HasColumn(&server.Server{}, "longitude"); !exists {
if err := db.Migrator().AddColumn(&server.Server{}, "longitude"); err != nil {
logger.Errorw("Migrate 01704 failed", logger.Field("action", "add longitude column"), logger.Field("error", err.Error()))
return err
}
logger.Infow("Migrate 01704 success", logger.Field("action", "add longitude column"))
}
// update system config
if err := db.Model(&system.System{}).Where("`category` = 'system' AND `key` = 'Version'").Update("value", version).Error; err != nil {
logger.Errorw("Migrate 01704 failed", logger.Field("step", "2"), logger.Field("action", "update system config"), logger.Field("error", err.Error()))
return err
}
logger.Infow("Migrate 01704 success", logger.Field("action", "update system config"))
return nil
}
func Migrate01705(db *gorm.DB) error {
version := "0.1.7(01705)"
// check user_device table exists, if not exists, create it
if exists := db.Migrator().HasTable(&user.Device{}); !exists {
if err := db.Migrator().CreateTable(&user.Device{}); err != nil {
logger.Errorw("Migrate 01705 failed", logger.Field("action", "create user_device table"), logger.Field("error", err.Error()))
return err
}
logger.Infow("Migrate 01705 success", logger.Field("action", "create user_device table"))
}
// check user_table exists and imei column exists, if exists, update imei column name to identifier
if exists := db.Migrator().HasColumn(&user.Device{}, "imei"); exists {
if err := db.Migrator().RenameColumn(&user.Device{}, "imei", "identifier"); err != nil {
logger.Errorw("Migrate 01705 failed", logger.Field("action", "rename imei column to identifier"), logger.Field("error", err.Error()))
return err
}
logger.Infow("Migrate 01705 success", logger.Field("action", "rename imei column to identifier"))
}
// update system config
if err := db.Model(&system.System{}).Where("`category` = 'system' AND `key` = 'Version'").Update("value", version).Error; err != nil {
logger.Errorw("Migrate 01705 failed", logger.Field("step", "2"), logger.Field("action", "update system config"), logger.Field("error", err.Error()))
return err
}
return nil
}
func initMobileConfig(db *gorm.DB) error {
cfg := new(auth.AlibabaCloudConfig)
mobileConfig := auth.MobileAuthConfig{
Platform: sms.AlibabaCloud.String(),
PlatformConfig: cfg.Marshal(),
EnableWhitelist: false,
Whitelist: make([]string, 0),
}
authMethod := auth.Auth{
Method: "mobile",
Config: mobileConfig.Marshal(),
}
if err := db.Save(&authMethod).Error; err != nil {
return err
}
return nil
}
func initEmailConfig(db *gorm.DB) error {
enable := true
smtpConfig := new(auth.SMTPConfig)
emailConfig := auth.EmailAuthConfig{
Platform: "smtp",
PlatformConfig: smtpConfig.Marshal(),
EnableVerify: false,
EnableDomainSuffix: false,
DomainSuffixList: "",
VerifyEmailTemplate: email.DefaultEmailVerifyTemplate,
ExpirationEmailTemplate: email.DefaultExpirationEmailTemplate,
MaintenanceEmailTemplate: email.DefaultMaintenanceEmailTemplate,
}
authMethod := auth.Auth{
Method: "email",
Config: emailConfig.Marshal(),
Enabled: &enable,
}
return db.Save(&authMethod).Error
}
func initTrialConfig(tx *gorm.DB) error {
configs := []system.System{
{
Category: "register",
Key: "TrialSubscribe",
Value: "",
Type: "int",
Desc: "Trial subscription",
},
{
Category: "register",
Key: "TrialTime",
Value: "24",
Type: "int",
Desc: "Trial time",
},
{
Category: "register",
Key: "TrialTimeUnit",
Value: "Hour",
Type: "string",
Desc: "Trial time unit",
},
}
return tx.Model(&system.System{}).Save(&configs).Error
}
func addAuthMethodWithDevice(tx *gorm.DB) error {
return tx.Model(&auth.Auth{}).Save(&auth.Auth{
Method: "device",
}).Error
}