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 }