package data import ( "context" "errors" "time" "kra/internal/biz" "gorm.io/gorm" ) type securityRepo struct{ data *Data } func NewSecurityRepo(data *Data) biz.SecurityRepo { return &securityRepo{data: data} } type securityConfigPO struct { ID uint `gorm:"primaryKey"` CreatedAt time.Time UpdatedAt time.Time DeletedAt gorm.DeletedAt `gorm:"index"` CaptchaOpen int CaptchaTimeout int KeyLong int ImgWidth int ImgHeight int PwdMinLength int PwdRequireUpper bool PwdRequireLower bool PwdRequireDigit bool PwdRequireSpecial bool LimitEnable bool LimitWindow int LimitCount int LockEnable bool LockThreshold int LockDuration int PwdExpireEnable bool PwdExpireDays int ForceNewUserChangePassword bool } func (securityConfigPO) TableName() string { return "sys_security_config" } func defaultSecurityConfig() securityConfigPO { return securityConfigPO{ID: 1, CaptchaTimeout: 3600, KeyLong: 6, ImgWidth: 240, ImgHeight: 80, PwdMinLength: 8, LimitWindow: 60, LimitCount: 30, LockThreshold: 5, LockDuration: 30, PwdExpireDays: 90} } func securityFromPO(v securityConfigPO) *biz.SecurityConfig { return &biz.SecurityConfig{ID: v.ID, CreatedAt: v.CreatedAt, UpdatedAt: v.UpdatedAt, CaptchaOpen: v.CaptchaOpen, CaptchaTimeout: v.CaptchaTimeout, KeyLong: v.KeyLong, ImgWidth: v.ImgWidth, ImgHeight: v.ImgHeight, PwdMinLength: v.PwdMinLength, PwdRequireUpper: v.PwdRequireUpper, PwdRequireLower: v.PwdRequireLower, PwdRequireDigit: v.PwdRequireDigit, PwdRequireSpecial: v.PwdRequireSpecial, LimitEnable: v.LimitEnable, LimitWindow: v.LimitWindow, LimitCount: v.LimitCount, LockEnable: v.LockEnable, LockThreshold: v.LockThreshold, LockDuration: v.LockDuration, PwdExpireEnable: v.PwdExpireEnable, PwdExpireDays: v.PwdExpireDays, ForceNewUserChangePassword: v.ForceNewUserChangePassword} } func securityToPO(v *biz.SecurityConfig) securityConfigPO { return securityConfigPO{ID: 1, CreatedAt: v.CreatedAt, UpdatedAt: v.UpdatedAt, CaptchaOpen: v.CaptchaOpen, CaptchaTimeout: v.CaptchaTimeout, KeyLong: v.KeyLong, ImgWidth: v.ImgWidth, ImgHeight: v.ImgHeight, PwdMinLength: v.PwdMinLength, PwdRequireUpper: v.PwdRequireUpper, PwdRequireLower: v.PwdRequireLower, PwdRequireDigit: v.PwdRequireDigit, PwdRequireSpecial: v.PwdRequireSpecial, LimitEnable: v.LimitEnable, LimitWindow: v.LimitWindow, LimitCount: v.LimitCount, LockEnable: v.LockEnable, LockThreshold: v.LockThreshold, LockDuration: v.LockDuration, PwdExpireEnable: v.PwdExpireEnable, PwdExpireDays: v.PwdExpireDays, ForceNewUserChangePassword: v.ForceNewUserChangePassword} } func (r *securityRepo) SecurityConfig(ctx context.Context) (*biz.SecurityConfig, error) { var po securityConfigPO err := r.data.gormDB.WithContext(ctx).First(&po, 1).Error if errors.Is(err, gorm.ErrRecordNotFound) { po = defaultSecurityConfig() err = r.data.gormDB.WithContext(ctx).Create(&po).Error } if err != nil { return nil, err } return securityFromPO(po), nil } func (r *securityRepo) SaveSecurityConfig(ctx context.Context, v *biz.SecurityConfig) error { previous, err := r.SecurityConfig(ctx) if err != nil { return err } po := securityToPO(v) po.CreatedAt, po.UpdatedAt = previous.CreatedAt, previous.UpdatedAt return r.data.gormDB.WithContext(ctx).Transaction(func(tx *gorm.DB) error { if err := tx.Save(&po).Error; err != nil { return err } if v.PwdExpireEnable && !previous.PwdExpireEnable { return tx.Model(&userPO{}).Where("password_updated_at IS NULL").Update("password_updated_at", time.Now()).Error } v.ID, v.CreatedAt, v.UpdatedAt = po.ID, po.CreatedAt, po.UpdatedAt return nil }) }