90 lines
4.6 KiB
Go
90 lines
4.6 KiB
Go
package system
|
|
|
|
import (
|
|
"context"
|
|
"errors"
|
|
"kra/internal/biz/system"
|
|
dataprovider "kra/internal/data/provider"
|
|
"time"
|
|
|
|
"gorm.io/gorm"
|
|
)
|
|
|
|
// DatabaseProvider is the smaller seam used by security settings, which also
|
|
// need to work before the primary database is initialized.
|
|
type DatabaseProvider = dataprovider.Database
|
|
|
|
type SecurityConfigPO struct {
|
|
ID uint `gorm:"primaryKey"`
|
|
CreatedAt time.Time
|
|
UpdatedAt time.Time
|
|
DeletedAt gorm.DeletedAt `gorm:"index"`
|
|
CaptchaOpen int `gorm:"default:0"`
|
|
CaptchaTimeout int `gorm:"default:3600"`
|
|
KeyLong int `gorm:"default:6"`
|
|
ImgWidth int `gorm:"default:240"`
|
|
ImgHeight int `gorm:"default:80"`
|
|
PwdMinLength int `gorm:"default:8"`
|
|
PwdRequireUpper bool `gorm:"default:false"`
|
|
PwdRequireLower bool `gorm:"default:false"`
|
|
PwdRequireDigit bool `gorm:"default:false"`
|
|
PwdRequireSpecial bool `gorm:"default:false"`
|
|
LimitEnable bool `gorm:"default:false"`
|
|
LimitWindow int `gorm:"default:60"`
|
|
LimitCount int `gorm:"default:30"`
|
|
LockEnable bool `gorm:"default:false"`
|
|
LockThreshold int `gorm:"default:5"`
|
|
LockDuration int `gorm:"default:30"`
|
|
PwdExpireEnable bool `gorm:"default:false"`
|
|
PwdExpireDays int `gorm:"default:90"`
|
|
ForceNewUserChangePassword bool `gorm:"default:false"`
|
|
}
|
|
|
|
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}
|
|
}
|
|
|
|
type securityRepo struct{ data DatabaseProvider }
|
|
|
|
func NewSecurityRepo(data DatabaseProvider) system.SecurityRepo { return &securityRepo{data: data} }
|
|
|
|
func securityFromPO(v SecurityConfigPO) *system.SecurityConfig {
|
|
return &system.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 *system.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) (*system.SecurityConfig, error) {
|
|
if !r.data.DatabaseReady() {
|
|
return nil, errors.New("数据库未初始化")
|
|
}
|
|
db := r.data.DB().WithContext(ctx)
|
|
var po SecurityConfigPO
|
|
err := db.First(&po, 1).Error
|
|
if errors.Is(err, gorm.ErrRecordNotFound) {
|
|
po = DefaultSecurityConfig()
|
|
err = db.Create(&po).Error
|
|
}
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
return securityFromPO(po), nil
|
|
}
|
|
|
|
func (r *securityRepo) SaveSecurityConfig(ctx context.Context, v *system.SecurityConfig) error {
|
|
po := securityToPO(v)
|
|
if err := r.data.DB().WithContext(ctx).Save(&po).Error; err != nil {
|
|
return err
|
|
}
|
|
v.ID, v.CreatedAt, v.UpdatedAt = po.ID, po.CreatedAt, po.UpdatedAt
|
|
return nil
|
|
}
|
|
|
|
func (r *securityRepo) BackfillPasswordUpdatedAt(ctx context.Context, at time.Time) error {
|
|
return r.data.DB().WithContext(ctx).Table("sys_users").Where("password_updated_at IS NULL").Update("password_updated_at", at).Error
|
|
}
|