github.com/infraboard/keyauth@v0.8.1/apps/domain/security_ext.go (about)

     1  package domain
     2  
     3  import (
     4  	"encoding/json"
     5  	"fmt"
     6  	"time"
     7  
     8  	"github.com/infraboard/keyauth/apps/user"
     9  	"github.com/infraboard/keyauth/common/password"
    10  	"github.com/infraboard/mcube/exception"
    11  )
    12  
    13  // NewDefaultSecuritySetting todo
    14  func NewDefaultSecuritySetting() *SecuritySetting {
    15  	return &SecuritySetting{
    16  		PasswordSecurity: NewDefaulPasswordSecurity(),
    17  		LoginSecurity:    NewDefaultLoginSecurity(),
    18  	}
    19  }
    20  
    21  // GetPasswordRepeateLimite todo
    22  func (s *SecuritySetting) GetPasswordRepeateLimite() uint {
    23  	if s.PasswordSecurity == nil {
    24  		return 0
    25  	}
    26  	return uint(s.PasswordSecurity.RepeateLimite)
    27  }
    28  
    29  // Patch todo
    30  func (s *SecuritySetting) Patch(data *SecuritySetting) {
    31  	patchData, _ := json.Marshal(data)
    32  	json.Unmarshal(patchData, s)
    33  }
    34  
    35  // NewDefaulPasswordSecurity todo
    36  func NewDefaulPasswordSecurity() *PasswordSecurity {
    37  	return &PasswordSecurity{
    38  		Length:                  8,
    39  		IncludeNumber:           true,
    40  		IncludeLowerLetter:      true,
    41  		IncludeUpperLetter:      false,
    42  		IncludeSymbols:          false,
    43  		RepeateLimite:           1,
    44  		PasswordExpiredDays:     90,
    45  		BeforeExpiredRemindDays: 10,
    46  	}
    47  }
    48  
    49  // Validate 校验对象合法性
    50  func (p *PasswordSecurity) Validate() error {
    51  	return validate.Struct(p)
    52  }
    53  
    54  // IsPasswordExpired todo
    55  func (p *PasswordSecurity) IsPasswordExpired(pass *user.Password) error {
    56  	if p.PasswordExpiredDays == 0 {
    57  		return nil
    58  	}
    59  
    60  	delta := p.expiredDelta(time.Unix(pass.UpdateAt/1000, 0))
    61  	if delta > 0 {
    62  		return exception.NewPasswordExired("password expired %d days", delta)
    63  	}
    64  
    65  	return nil
    66  }
    67  
    68  // SetPasswordNeedReset todo
    69  func (p *PasswordSecurity) SetPasswordNeedReset(pass *user.Password) {
    70  	// 密码用不过期, 不需要重置
    71  	if p.PasswordExpiredDays == 0 {
    72  		return
    73  	}
    74  
    75  	// 计算密码是否过期
    76  	delta := p.expiredDelta(time.Unix(pass.UpdateAt/1000, 0))
    77  	if delta > 0 {
    78  		pass.SetExpired()
    79  		return
    80  	}
    81  
    82  	// 计算是否即将过期, 需要用户重置
    83  	if -delta < int(p.BeforeExpiredRemindDays) {
    84  		pass.SetNeedReset("密码%d天后过期, 请重置密码", -delta)
    85  	}
    86  }
    87  
    88  func (p *PasswordSecurity) expiredDelta(updateAt time.Time) int {
    89  	updateBefore := uint(time.Now().Sub(updateAt).Hours() / 24)
    90  	return int(updateBefore) - int(p.PasswordExpiredDays)
    91  }
    92  
    93  // Check todo
    94  func (p *PasswordSecurity) Check(pass string) error {
    95  	v := password.NewValidater(pass)
    96  
    97  	if ok := v.LengthOK(int(p.Length)); !ok {
    98  		return fmt.Errorf("password length less than %d", p.Length)
    99  	}
   100  	if p.IncludeNumber {
   101  		if ok := v.IncludeNumbers(); !ok {
   102  			return fmt.Errorf("must include numbers")
   103  		}
   104  	}
   105  	if p.IncludeLowerLetter {
   106  		if ok := v.IncludeLowercaseLetters(); !ok {
   107  			return fmt.Errorf("must include lower letter")
   108  		}
   109  	}
   110  	if p.IncludeUpperLetter {
   111  		if ok := v.IncludeUppercaseLetters(); !ok {
   112  			return fmt.Errorf("must include upper letter")
   113  		}
   114  	}
   115  	if p.IncludeSymbols {
   116  		if ok := v.IncludeSymbols(); !ok {
   117  			return fmt.Errorf("must include symbols")
   118  		}
   119  	}
   120  
   121  	return nil
   122  }
   123  
   124  // NewDefaultLoginSecurity todo
   125  func NewDefaultLoginSecurity() *LoginSecurity {
   126  	return &LoginSecurity{
   127  		ExceptionLock: false,
   128  		ExceptionLockConfig: &ExceptionLockConfig{
   129  			OtherPlaceLogin: true,
   130  			NotLoginDays:    30,
   131  		},
   132  		RetryLock: true,
   133  		RetryLockConfig: &RetryLockConfig{
   134  			RetryLimite:  5,
   135  			LockedMinite: 30,
   136  		},
   137  		IpLimite: false,
   138  		IpLimiteConfig: &IPLimiteConfig{
   139  			Ip: []string{},
   140  		},
   141  	}
   142  }
   143  
   144  // LockedMiniteDuration todo
   145  func (c *RetryLockConfig) LockedMiniteDuration() time.Duration {
   146  	return time.Duration(c.LockedMinite) * time.Minute
   147  }
   148  
   149  // GenRandomPasswordConfig todo
   150  func (p *PasswordSecurity) GenRandomPasswordConfig() password.Config {
   151  	return password.Config{
   152  		Length:                  int(p.Length) + 4,
   153  		IncludeSymbols:          true,
   154  		IncludeNumbers:          true,
   155  		IncludeLowercaseLetters: true,
   156  		IncludeUppercaseLetters: true,
   157  	}
   158  }