refactor: separate backend domains and storage adapters
This commit is contained in:
+1
-503
@@ -1,509 +1,7 @@
|
||||
package data
|
||||
|
||||
import (
|
||||
"context"
|
||||
"errors"
|
||||
"fmt"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"kra/internal/biz"
|
||||
|
||||
"gorm.io/gorm"
|
||||
"gorm.io/gorm/clause"
|
||||
)
|
||||
|
||||
type dictionaryPO struct {
|
||||
ID uint `gorm:"primaryKey"`
|
||||
CreatedAt time.Time
|
||||
UpdatedAt time.Time
|
||||
DeletedAt gorm.DeletedAt `gorm:"index"`
|
||||
Name string
|
||||
Type string `gorm:"uniqueIndex"`
|
||||
Status bool
|
||||
Desc string
|
||||
ParentID *uint
|
||||
}
|
||||
|
||||
func (dictionaryPO) TableName() string { return "sys_dictionaries" }
|
||||
|
||||
type dictionaryDetailPO struct {
|
||||
ID uint `gorm:"primaryKey"`
|
||||
CreatedAt time.Time
|
||||
UpdatedAt time.Time
|
||||
DeletedAt gorm.DeletedAt `gorm:"index"`
|
||||
Label string
|
||||
Value string
|
||||
Extend string
|
||||
Status bool
|
||||
Sort int
|
||||
DictionaryID uint `gorm:"column:sys_dictionary_id;index"`
|
||||
ParentID *uint
|
||||
Level int
|
||||
Path string
|
||||
}
|
||||
|
||||
func (dictionaryDetailPO) TableName() string { return "sys_dictionary_details" }
|
||||
|
||||
type parameterPO struct {
|
||||
ID uint `gorm:"primaryKey"`
|
||||
CreatedAt time.Time
|
||||
UpdatedAt time.Time
|
||||
DeletedAt gorm.DeletedAt `gorm:"index"`
|
||||
Name string
|
||||
Key string `gorm:"uniqueIndex"`
|
||||
Value string
|
||||
Desc string
|
||||
}
|
||||
|
||||
func (parameterPO) TableName() string { return "sys_params" }
|
||||
|
||||
type apiTokenPO struct {
|
||||
ID uint `gorm:"primaryKey"`
|
||||
CreatedAt time.Time
|
||||
UpdatedAt time.Time
|
||||
DeletedAt gorm.DeletedAt `gorm:"index"`
|
||||
UserID uint
|
||||
AuthorityID uint
|
||||
Token string `gorm:"type:text;uniqueIndex"`
|
||||
Status bool
|
||||
ExpiresAt time.Time
|
||||
Remark string
|
||||
}
|
||||
|
||||
func (apiTokenPO) TableName() string { return "sys_api_tokens" }
|
||||
|
||||
type jwtBlacklistPO struct {
|
||||
ID uint `gorm:"primaryKey"`
|
||||
CreatedAt time.Time
|
||||
UpdatedAt time.Time
|
||||
DeletedAt gorm.DeletedAt `gorm:"index"`
|
||||
JWT string `gorm:"column:jwt;type:text"`
|
||||
}
|
||||
|
||||
func (jwtBlacklistPO) TableName() string { return "jwt_blacklists" }
|
||||
|
||||
type securityConfigPO struct {
|
||||
ID uint `gorm:"primaryKey"`
|
||||
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" }
|
||||
import "kra/internal/biz"
|
||||
|
||||
type settingsRepo struct{ data *Data }
|
||||
|
||||
func NewSettingsRepo(data *Data) biz.SettingsRepo { return &settingsRepo{data: data} }
|
||||
|
||||
func dictionaryFromPO(po dictionaryPO) *biz.Dictionary {
|
||||
return &biz.Dictionary{ID: po.ID, CreatedAt: po.CreatedAt, UpdatedAt: po.UpdatedAt, Name: po.Name, Type: po.Type, Status: po.Status, Desc: po.Desc, ParentID: po.ParentID}
|
||||
}
|
||||
func detailFromPO(po dictionaryDetailPO) *biz.DictionaryDetail {
|
||||
return &biz.DictionaryDetail{ID: po.ID, CreatedAt: po.CreatedAt, UpdatedAt: po.UpdatedAt, Label: po.Label, Value: po.Value, Extend: po.Extend, Status: po.Status, Sort: po.Sort, DictionaryID: po.DictionaryID, ParentID: po.ParentID, Level: po.Level, Path: po.Path}
|
||||
}
|
||||
func parameterFromPO(po parameterPO) *biz.SystemParameter {
|
||||
return &biz.SystemParameter{ID: po.ID, CreatedAt: po.CreatedAt, UpdatedAt: po.UpdatedAt, Name: po.Name, Key: po.Key, Value: po.Value, Desc: po.Desc}
|
||||
}
|
||||
|
||||
func (r *settingsRepo) CreateDictionary(ctx context.Context, v *biz.Dictionary) error {
|
||||
po := dictionaryPO{Name: v.Name, Type: v.Type, Status: v.Status, Desc: v.Desc, ParentID: v.ParentID}
|
||||
if err := r.data.gormDB.WithContext(ctx).Create(&po).Error; err != nil {
|
||||
return err
|
||||
}
|
||||
v.ID = po.ID
|
||||
return nil
|
||||
}
|
||||
func (r *settingsRepo) UpdateDictionary(ctx context.Context, v *biz.Dictionary) error {
|
||||
return r.data.gormDB.WithContext(ctx).Model(&dictionaryPO{}).Where("id = ?", v.ID).Updates(map[string]any{"name": v.Name, "type": v.Type, "status": v.Status, "desc": v.Desc, "parent_id": v.ParentID}).Error
|
||||
}
|
||||
func (r *settingsRepo) DeleteDictionary(ctx context.Context, id uint) error {
|
||||
return r.data.gormDB.WithContext(ctx).Transaction(func(tx *gorm.DB) error {
|
||||
var count int64
|
||||
if err := tx.Model(&dictionaryPO{}).Where("parent_id = ?", id).Count(&count).Error; err != nil {
|
||||
return err
|
||||
}
|
||||
if count > 0 {
|
||||
return errors.New("存在子字典不可删除")
|
||||
}
|
||||
if err := tx.Where("sys_dictionary_id = ?", id).Delete(&dictionaryDetailPO{}).Error; err != nil {
|
||||
return err
|
||||
}
|
||||
return tx.Delete(&dictionaryPO{}, id).Error
|
||||
})
|
||||
}
|
||||
func (r *settingsRepo) FindDictionary(ctx context.Context, id uint, typ string, details bool) (*biz.Dictionary, error) {
|
||||
var po dictionaryPO
|
||||
db := r.data.gormDB.WithContext(ctx)
|
||||
var err error
|
||||
if id != 0 {
|
||||
err = db.First(&po, id).Error
|
||||
} else {
|
||||
err = db.Where("type = ?", typ).First(&po).Error
|
||||
}
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
out := dictionaryFromPO(po)
|
||||
if details {
|
||||
out.Details, _, err = r.ListDictionaryDetails(ctx, 1, 10000, out.ID, "", "")
|
||||
}
|
||||
return out, err
|
||||
}
|
||||
func (r *settingsRepo) ListDictionaries(ctx context.Context, page, size int, name, typ string, details bool) ([]*biz.Dictionary, int64, error) {
|
||||
if page < 1 {
|
||||
page = 1
|
||||
}
|
||||
if size < 1 {
|
||||
size = 10
|
||||
}
|
||||
db := r.data.gormDB.WithContext(ctx).Model(&dictionaryPO{})
|
||||
if name != "" {
|
||||
db = db.Where("name LIKE ?", "%"+name+"%")
|
||||
}
|
||||
if typ != "" {
|
||||
db = db.Where("type LIKE ?", "%"+typ+"%")
|
||||
}
|
||||
var total int64
|
||||
if err := db.Count(&total).Error; err != nil {
|
||||
return nil, 0, err
|
||||
}
|
||||
var pos []dictionaryPO
|
||||
if err := db.Order("id desc").Offset((page - 1) * size).Limit(size).Find(&pos).Error; err != nil {
|
||||
return nil, 0, err
|
||||
}
|
||||
out := make([]*biz.Dictionary, 0, len(pos))
|
||||
for _, po := range pos {
|
||||
v := dictionaryFromPO(po)
|
||||
if details {
|
||||
v.Details, _, _ = r.ListDictionaryDetails(ctx, 1, 10000, v.ID, "", "")
|
||||
}
|
||||
out = append(out, v)
|
||||
}
|
||||
return out, total, nil
|
||||
}
|
||||
|
||||
func (r *settingsRepo) CreateDictionaryDetail(ctx context.Context, v *biz.DictionaryDetail) error {
|
||||
po := dictionaryDetailPO{Label: v.Label, Value: v.Value, Extend: v.Extend, Status: v.Status, Sort: v.Sort, DictionaryID: v.DictionaryID, ParentID: v.ParentID}
|
||||
po.Level = 0
|
||||
po.Path = ""
|
||||
if v.ParentID != nil && *v.ParentID != 0 {
|
||||
var parent dictionaryDetailPO
|
||||
if err := r.data.gormDB.WithContext(ctx).First(&parent, *v.ParentID).Error; err != nil {
|
||||
return err
|
||||
}
|
||||
po.Level = parent.Level + 1
|
||||
po.Path = strings.Trim(strings.Join([]string{parent.Path, fmt.Sprint(parent.ID)}, ","), ",")
|
||||
}
|
||||
if err := r.data.gormDB.WithContext(ctx).Create(&po).Error; err != nil {
|
||||
return err
|
||||
}
|
||||
v.ID = po.ID
|
||||
v.Level = po.Level
|
||||
v.Path = po.Path
|
||||
return nil
|
||||
}
|
||||
func (r *settingsRepo) UpdateDictionaryDetail(ctx context.Context, v *biz.DictionaryDetail) error {
|
||||
var po dictionaryDetailPO
|
||||
if err := r.data.gormDB.WithContext(ctx).First(&po, v.ID).Error; err != nil {
|
||||
return err
|
||||
}
|
||||
level, path := 0, ""
|
||||
if v.ParentID != nil && *v.ParentID != 0 {
|
||||
if *v.ParentID == v.ID {
|
||||
return errors.New("不能将自身设为父级")
|
||||
}
|
||||
var parent dictionaryDetailPO
|
||||
if err := r.data.gormDB.WithContext(ctx).First(&parent, *v.ParentID).Error; err != nil {
|
||||
return err
|
||||
}
|
||||
if strings.Contains(","+parent.Path+",", fmt.Sprintf(",%d,", v.ID)) {
|
||||
return errors.New("不能移动到自己的子级")
|
||||
}
|
||||
level = parent.Level + 1
|
||||
path = strings.Trim(strings.Join([]string{parent.Path, fmt.Sprint(parent.ID)}, ","), ",")
|
||||
}
|
||||
oldPrefix := strings.Trim(strings.Join([]string{po.Path, fmt.Sprint(po.ID)}, ","), ",")
|
||||
newPrefix := strings.Trim(strings.Join([]string{path, fmt.Sprint(po.ID)}, ","), ",")
|
||||
return r.data.gormDB.WithContext(ctx).Transaction(func(tx *gorm.DB) error {
|
||||
if err := tx.Model(&dictionaryDetailPO{}).Where("id = ?", v.ID).Updates(map[string]any{"label": v.Label, "value": v.Value, "extend": v.Extend, "status": v.Status, "sort": v.Sort, "sys_dictionary_id": v.DictionaryID, "parent_id": v.ParentID, "level": level, "path": path}).Error; err != nil {
|
||||
return err
|
||||
}
|
||||
return tx.Model(&dictionaryDetailPO{}).Where("path = ? OR path LIKE ?", oldPrefix, oldPrefix+",%").Update("path", gorm.Expr("REPLACE(path, ?, ?)", oldPrefix, newPrefix)).Error
|
||||
})
|
||||
}
|
||||
func (r *settingsRepo) DeleteDictionaryDetail(ctx context.Context, id uint) error {
|
||||
var count int64
|
||||
if err := r.data.gormDB.WithContext(ctx).Model(&dictionaryDetailPO{}).Where("parent_id = ?", id).Count(&count).Error; err != nil {
|
||||
return err
|
||||
}
|
||||
if count > 0 {
|
||||
return errors.New("存在子级不可删除")
|
||||
}
|
||||
return r.data.gormDB.WithContext(ctx).Delete(&dictionaryDetailPO{}, id).Error
|
||||
}
|
||||
func (r *settingsRepo) FindDictionaryDetail(ctx context.Context, id uint) (*biz.DictionaryDetail, error) {
|
||||
var po dictionaryDetailPO
|
||||
if err := r.data.gormDB.WithContext(ctx).First(&po, id).Error; err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return detailFromPO(po), nil
|
||||
}
|
||||
func (r *settingsRepo) ListDictionaryDetails(ctx context.Context, page, size int, dictionaryID uint, label, value string) ([]*biz.DictionaryDetail, int64, error) {
|
||||
if page < 1 {
|
||||
page = 1
|
||||
}
|
||||
if size < 1 {
|
||||
size = 10
|
||||
}
|
||||
db := r.data.gormDB.WithContext(ctx).Model(&dictionaryDetailPO{})
|
||||
if dictionaryID != 0 {
|
||||
db = db.Where("sys_dictionary_id = ?", dictionaryID)
|
||||
}
|
||||
if label != "" {
|
||||
db = db.Where("label LIKE ?", "%"+label+"%")
|
||||
}
|
||||
if value != "" {
|
||||
db = db.Where("value LIKE ?", "%"+value+"%")
|
||||
}
|
||||
var total int64
|
||||
if err := db.Count(&total).Error; err != nil {
|
||||
return nil, 0, err
|
||||
}
|
||||
var pos []dictionaryDetailPO
|
||||
if err := db.Order("sort,id").Offset((page - 1) * size).Limit(size).Find(&pos).Error; err != nil {
|
||||
return nil, 0, err
|
||||
}
|
||||
out := make([]*biz.DictionaryDetail, 0, len(pos))
|
||||
for _, po := range pos {
|
||||
out = append(out, detailFromPO(po))
|
||||
}
|
||||
return out, total, nil
|
||||
}
|
||||
func (r *settingsRepo) DictionaryDetailTree(ctx context.Context, dictionaryID uint, typ string) ([]*biz.DictionaryDetail, error) {
|
||||
if dictionaryID == 0 {
|
||||
dictionary, err := r.FindDictionary(ctx, 0, typ, false)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
dictionaryID = dictionary.ID
|
||||
}
|
||||
items, _, err := r.ListDictionaryDetails(ctx, 1, 100000, dictionaryID, "", "")
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
byID := map[uint]*biz.DictionaryDetail{}
|
||||
for _, item := range items {
|
||||
item.Children = []*biz.DictionaryDetail{}
|
||||
byID[item.ID] = item
|
||||
}
|
||||
roots := []*biz.DictionaryDetail{}
|
||||
for _, item := range items {
|
||||
if item.ParentID != nil && byID[*item.ParentID] != nil {
|
||||
byID[*item.ParentID].Children = append(byID[*item.ParentID].Children, item)
|
||||
} else {
|
||||
roots = append(roots, item)
|
||||
}
|
||||
}
|
||||
return roots, nil
|
||||
}
|
||||
|
||||
func (r *settingsRepo) CreateParameter(ctx context.Context, v *biz.SystemParameter) error {
|
||||
po := parameterPO{Name: v.Name, Key: v.Key, Value: v.Value, Desc: v.Desc}
|
||||
if err := r.data.gormDB.WithContext(ctx).Create(&po).Error; err != nil {
|
||||
return err
|
||||
}
|
||||
v.ID = po.ID
|
||||
return nil
|
||||
}
|
||||
func (r *settingsRepo) UpdateParameter(ctx context.Context, v *biz.SystemParameter) error {
|
||||
return r.data.gormDB.WithContext(ctx).Model(¶meterPO{}).Where("id = ?", v.ID).Updates(map[string]any{"name": v.Name, "key": v.Key, "value": v.Value, "desc": v.Desc}).Error
|
||||
}
|
||||
func (r *settingsRepo) DeleteParameters(ctx context.Context, ids []uint) error {
|
||||
return r.data.gormDB.WithContext(ctx).Delete(¶meterPO{}, ids).Error
|
||||
}
|
||||
func (r *settingsRepo) FindParameter(ctx context.Context, id uint, key string) (*biz.SystemParameter, error) {
|
||||
var po parameterPO
|
||||
db := r.data.gormDB.WithContext(ctx)
|
||||
var err error
|
||||
if id != 0 {
|
||||
err = db.First(&po, id).Error
|
||||
} else {
|
||||
err = db.Where(map[string]any{"key": key}).First(&po).Error
|
||||
}
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return parameterFromPO(po), nil
|
||||
}
|
||||
func (r *settingsRepo) ListParameters(ctx context.Context, page, size int, q *biz.SystemParameter) ([]*biz.SystemParameter, int64, error) {
|
||||
if page < 1 {
|
||||
page = 1
|
||||
}
|
||||
if size < 1 {
|
||||
size = 10
|
||||
}
|
||||
db := r.data.gormDB.WithContext(ctx).Model(¶meterPO{})
|
||||
if q != nil {
|
||||
if q.Name != "" {
|
||||
db = db.Where("name LIKE ?", "%"+q.Name+"%")
|
||||
}
|
||||
if q.Key != "" {
|
||||
db = db.Where(clause.Like{Column: clause.Column{Name: "key"}, Value: "%" + q.Key + "%"})
|
||||
}
|
||||
}
|
||||
var total int64
|
||||
if err := db.Count(&total).Error; err != nil {
|
||||
return nil, 0, err
|
||||
}
|
||||
var pos []parameterPO
|
||||
if err := db.Order("id desc").Offset((page - 1) * size).Limit(size).Find(&pos).Error; err != nil {
|
||||
return nil, 0, err
|
||||
}
|
||||
out := make([]*biz.SystemParameter, 0, len(pos))
|
||||
for _, po := range pos {
|
||||
out = append(out, parameterFromPO(po))
|
||||
}
|
||||
return out, total, nil
|
||||
}
|
||||
|
||||
func (r *settingsRepo) UserHasAuthority(ctx context.Context, userID, authorityID uint) (*biz.User, bool, error) {
|
||||
var po userPO
|
||||
if err := r.data.gormDB.WithContext(ctx).First(&po, userID).Error; err != nil {
|
||||
return nil, false, err
|
||||
}
|
||||
var count int64
|
||||
err := r.data.gormDB.WithContext(ctx).Model(&userAuthorityPO{}).Where("sys_user_id = ? AND sys_authority_authority_id = ?", userID, authorityID).Count(&count).Error
|
||||
if err != nil {
|
||||
return nil, false, err
|
||||
}
|
||||
user, err := (&systemRepo{data: r.data}).toBizUser(ctx, &po)
|
||||
return user, count > 0 || po.AuthorityID == authorityID, err
|
||||
}
|
||||
func (r *settingsRepo) CreateAPIToken(ctx context.Context, v *biz.APIToken) error {
|
||||
po := apiTokenPO{UserID: v.UserID, AuthorityID: v.AuthorityID, Token: v.Token, Status: v.Status, ExpiresAt: v.ExpiresAt, Remark: v.Remark}
|
||||
if err := r.data.gormDB.WithContext(ctx).Create(&po).Error; err != nil {
|
||||
return err
|
||||
}
|
||||
v.ID = po.ID
|
||||
v.CreatedAt = po.CreatedAt
|
||||
return nil
|
||||
}
|
||||
func (r *settingsRepo) ListAPITokens(ctx context.Context, page, size int, userID uint, status *bool) ([]*biz.APIToken, int64, error) {
|
||||
if page < 1 {
|
||||
page = 1
|
||||
}
|
||||
if size < 1 {
|
||||
size = 10
|
||||
}
|
||||
db := r.data.gormDB.WithContext(ctx).Model(&apiTokenPO{})
|
||||
if userID != 0 {
|
||||
db = db.Where("user_id = ?", userID)
|
||||
}
|
||||
if status != nil {
|
||||
db = db.Where("status = ?", *status)
|
||||
}
|
||||
var total int64
|
||||
if err := db.Count(&total).Error; err != nil {
|
||||
return nil, 0, err
|
||||
}
|
||||
var pos []apiTokenPO
|
||||
if err := db.Order("created_at desc").Offset((page - 1) * size).Limit(size).Find(&pos).Error; err != nil {
|
||||
return nil, 0, err
|
||||
}
|
||||
out := make([]*biz.APIToken, 0, len(pos))
|
||||
for _, po := range pos {
|
||||
v := &biz.APIToken{ID: po.ID, CreatedAt: po.CreatedAt, UpdatedAt: po.UpdatedAt, UserID: po.UserID, AuthorityID: po.AuthorityID, Token: po.Token, Status: po.Status, ExpiresAt: po.ExpiresAt, Remark: po.Remark}
|
||||
var userPO userPO
|
||||
if r.data.gormDB.WithContext(ctx).First(&userPO, po.UserID).Error == nil {
|
||||
v.User, _ = (&systemRepo{data: r.data}).toBizUser(ctx, &userPO)
|
||||
}
|
||||
out = append(out, v)
|
||||
}
|
||||
return out, total, nil
|
||||
}
|
||||
func (r *settingsRepo) DisableAPIToken(ctx context.Context, id uint) (string, error) {
|
||||
var po apiTokenPO
|
||||
if err := r.data.gormDB.WithContext(ctx).First(&po, id).Error; err != nil {
|
||||
return "", err
|
||||
}
|
||||
return po.Token, r.data.gormDB.WithContext(ctx).Model(&po).Update("status", false).Error
|
||||
}
|
||||
func (r *settingsRepo) BlacklistToken(ctx context.Context, token string) error {
|
||||
if token == "" {
|
||||
return errors.New("token is empty")
|
||||
}
|
||||
return r.data.gormDB.WithContext(ctx).Create(&jwtBlacklistPO{JWT: token}).Error
|
||||
}
|
||||
func (r *settingsRepo) IsTokenDisabled(ctx context.Context, token string) (bool, error) {
|
||||
var blacklistCount int64
|
||||
if err := r.data.gormDB.WithContext(ctx).Model(&jwtBlacklistPO{}).Where("jwt = ?", token).Count(&blacklistCount).Error; err != nil {
|
||||
return false, err
|
||||
}
|
||||
if blacklistCount > 0 {
|
||||
return true, nil
|
||||
}
|
||||
var po apiTokenPO
|
||||
result := r.data.gormDB.WithContext(ctx).Where("token = ?", token).Limit(1).Find(&po)
|
||||
if result.Error != nil {
|
||||
return false, result.Error
|
||||
}
|
||||
if result.RowsAffected == 0 {
|
||||
return false, nil
|
||||
}
|
||||
return !po.Status || time.Now().After(po.ExpiresAt), nil
|
||||
}
|
||||
|
||||
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, 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, 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 *settingsRepo) 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 *settingsRepo) SaveSecurityConfig(ctx context.Context, v *biz.SecurityConfig) error {
|
||||
previous, err := r.SecurityConfig(ctx)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
po := securityToPO(v)
|
||||
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
|
||||
}
|
||||
return nil
|
||||
})
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user