add reuse check on update MFA (#28304)
Этот коммит содержится в:
@@ -85,27 +85,25 @@ func (m *MFA) GenerateSecret(siteURL, userEmail, userID string) (string, []byte,
|
||||
|
||||
// Activate set the mfa as active and store it with the StoreActive function provided
|
||||
func (m *MFA) Activate(userMfaSecret, userID string, token string) error {
|
||||
otpConfig := &dgoogauth.OTPConfig{
|
||||
Secret: userMfaSecret,
|
||||
WindowSize: 3,
|
||||
HotpCounter: 0,
|
||||
}
|
||||
|
||||
trimmedToken := strings.TrimSpace(token)
|
||||
|
||||
ok, err := otpConfig.Authenticate(trimmedToken)
|
||||
usedTs, err := m.store.GetMfaUsedTimestamps(userID)
|
||||
if err != nil {
|
||||
return errors.Wrap(err, "unable to parse the token")
|
||||
return errors.Wrap(err, "unable to retrieve the DisallowReuse slice")
|
||||
}
|
||||
|
||||
if !ok {
|
||||
return InvalidToken
|
||||
otpConfig, err := m.authenticate(userMfaSecret, usedTs, token)
|
||||
if err != nil {
|
||||
return errors.Wrap(err, "unable to authenticate the token")
|
||||
}
|
||||
|
||||
if err := m.store.UpdateMfaActive(userID, true); err != nil {
|
||||
if err = m.store.UpdateMfaActive(userID, true); err != nil {
|
||||
return errors.Wrap(err, "unable to store mfa active")
|
||||
}
|
||||
|
||||
err = m.store.StoreMfaUsedTimestamps(userID, otpConfig.DisallowReuse)
|
||||
if err != nil {
|
||||
return errors.Wrap(err, "unable to store the DisallowReuse slice")
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
@@ -129,21 +127,14 @@ func (m *MFA) ValidateToken(user *model.User, token string) (bool, error) {
|
||||
return false, errors.Wrap(err, "unable to retrieve the DisallowReuse slice")
|
||||
}
|
||||
|
||||
otpConfig := &dgoogauth.OTPConfig{
|
||||
Secret: user.MfaSecret,
|
||||
WindowSize: 3,
|
||||
HotpCounter: 0,
|
||||
DisallowReuse: usedTs,
|
||||
}
|
||||
|
||||
trimmedToken := strings.TrimSpace(token)
|
||||
ok, err := otpConfig.Authenticate(trimmedToken)
|
||||
otpConfig, err := m.authenticate(user.MfaSecret, usedTs, token)
|
||||
if err != nil {
|
||||
if err == InvalidToken {
|
||||
return false, nil
|
||||
}
|
||||
|
||||
return false, errors.Wrap(err, "unable to parse the token")
|
||||
}
|
||||
if !ok {
|
||||
return false, nil
|
||||
}
|
||||
|
||||
err = m.store.StoreMfaUsedTimestamps(user.Id, otpConfig.DisallowReuse)
|
||||
if err != nil {
|
||||
@@ -152,3 +143,24 @@ func (m *MFA) ValidateToken(user *model.User, token string) (bool, error) {
|
||||
|
||||
return true, nil
|
||||
}
|
||||
|
||||
func (*MFA) authenticate(userMfaSecret string, usedTs []int, token string) (*dgoogauth.OTPConfig, error) {
|
||||
trimmedToken := strings.TrimSpace(token)
|
||||
|
||||
otpConfig := &dgoogauth.OTPConfig{
|
||||
Secret: userMfaSecret,
|
||||
WindowSize: 3,
|
||||
HotpCounter: 0,
|
||||
DisallowReuse: usedTs,
|
||||
}
|
||||
|
||||
ok, err := otpConfig.Authenticate(trimmedToken)
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "unable to parse the token")
|
||||
}
|
||||
if !ok {
|
||||
return nil, InvalidToken
|
||||
}
|
||||
|
||||
return otpConfig, nil
|
||||
}
|
||||
|
||||
Ссылка в новой задаче
Block a user