1
0

Disable the user account after 10 failed password attempts

This commit is contained in:
kolaente
2021-07-29 18:45:22 +02:00
parent 3572ac4b82
commit 5cfc9bf2f9
7 changed files with 122 additions and 10 deletions

View File

@ -18,12 +18,17 @@ package user
import (
"image"
"strconv"
"xorm.io/xorm"
"code.vikunja.io/api/pkg/modules/keyvalue"
"code.vikunja.io/api/pkg/config"
"code.vikunja.io/api/pkg/log"
"code.vikunja.io/api/pkg/notifications"
"github.com/pquerna/otp"
"github.com/pquerna/otp/totp"
"xorm.io/xorm"
)
// TOTP holds a user's totp setting in the database.
@ -149,3 +154,46 @@ func GetTOTPQrCodeForUser(s *xorm.Session, user *User) (qrcode image.Image, err
}
return key.Image(300, 300)
}
func (u *User) GetFailedTOTPAttemptsKey() string {
return "failed_totp_attempts_" + strconv.FormatInt(u.ID, 10)
}
// HandleFailedTOTPAuth handles informing the user of failed TOTP attempts and blocking the account after 10 attempts
func HandleFailedTOTPAuth(s *xorm.Session, user *User) {
log.Errorf("Invalid TOTP credentials provided for user %d", user.ID)
err := notifications.Notify(user, &InvalidTOTPNotification{User: user})
if err != nil {
log.Errorf("Could not send failed TOTP notification to user %d: %s", user.ID, err)
}
key := user.GetFailedTOTPAttemptsKey()
err = keyvalue.IncrBy(key, 1)
if err != nil {
log.Errorf("Could not increase failed TOTP attempts for user %d: %s", user.ID, err)
}
a, _, err := keyvalue.Get(key)
if err != nil {
log.Errorf("Could get failed TOTP attempts for user %d: %s", user.ID, err)
}
attempts := a.(int64)
if attempts > 10 {
log.Infof("Blocking user account %d after 10 failed TOTP password attempts", user.ID)
err = RequestUserPasswordResetToken(s, user)
if err != nil {
log.Errorf("Could not reset password of user %d after 10 failed TOTP attempts: %s", user.ID, err)
}
err = notifications.Notify(user, &PasswordAccountLockedAfterInvalidTOTOPNotification{
User: user,
})
if err != nil {
log.Errorf("Could send password information mail to user %d after 10 failed TOTP attempts: %s", user.ID, err)
}
err = user.SetStatus(s, StatusDisabled)
if err != nil {
log.Errorf("Could not disable user %d: %s", user.ID, err)
}
}
}