fix(caldav): no failed login emails for tokens (#1252)

Prevent Vikunja from sending mail notifications for failed login attempts if CalDav token is used.

Before, as the provided password value was tested against the user password regardless of whether it was a CalDav token, it triggered a failed login attempt email every three times.

Reviewed-on: vikunja/api#1252
Reviewed-by: konrad <k@knt.li>
Co-authored-by: Luca Bernstein <luca@lucabernstein.com>
Co-committed-by: Luca Bernstein <luca@lucabernstein.com>
This commit is contained in:
Luca Bernstein 2022-09-27 15:12:37 +00:00 committed by konrad
parent 25609db567
commit 54b7f7127c
1 changed files with 26 additions and 15 deletions

View File

@ -22,6 +22,7 @@ import (
"code.vikunja.io/api/pkg/db" "code.vikunja.io/api/pkg/db"
"code.vikunja.io/api/pkg/log" "code.vikunja.io/api/pkg/log"
"code.vikunja.io/api/pkg/user" "code.vikunja.io/api/pkg/user"
"xorm.io/xorm"
"github.com/labstack/echo/v4" "github.com/labstack/echo/v4"
"golang.org/x/crypto/bcrypt" "golang.org/x/crypto/bcrypt"
@ -35,37 +36,47 @@ func BasicAuth(username, password string, c echo.Context) (bool, error) {
Username: username, Username: username,
Password: password, Password: password,
} }
u, err := user.CheckUserCredentials(s, credentials) var err error
if err != nil && !user.IsErrWrongUsernameOrPassword(err) && !user.IsErrAccountIsNotLocal(err) { u, err := checkUserCaldavTokens(s, credentials)
log.Errorf("Error during basic auth for caldav: %v", err) if user.IsErrUserDoesNotExist(err) {
return false, nil return false, nil
} }
if u == nil {
if err == nil { u, err = user.CheckUserCredentials(s, credentials)
if err != nil {
log.Errorf("Error during basic auth for caldav: %v", err)
return false, nil
}
}
if u != nil && err == nil {
c.Set("userBasicAuth", u) c.Set("userBasicAuth", u)
return true, nil return true, nil
} }
return false, nil
}
tokens, err := user.GetCaldavTokens(u) func checkUserCaldavTokens(s *xorm.Session, login *user.Login) (*user.User, error) {
usr, err := user.GetUserByUsername(s, login.Username)
if err != nil || usr == nil {
log.Warningf("Error while retrieving users from database: %v", err)
return nil, err
}
tokens, err := user.GetCaldavTokens(usr)
if err != nil { if err != nil {
log.Errorf("Error while getting tokens for caldav auth: %v", err) log.Errorf("Error while getting tokens for caldav auth: %v", err)
return false, nil return nil, err
} }
// Looping over all tokens until we find one that matches // Looping over all tokens until we find one that matches
for _, token := range tokens { for _, token := range tokens {
err = bcrypt.CompareHashAndPassword([]byte(token.Token), []byte(password)) err = bcrypt.CompareHashAndPassword([]byte(token.Token), []byte(login.Password))
if err != nil { if err != nil {
if errors.Is(err, bcrypt.ErrMismatchedHashAndPassword) { if errors.Is(err, bcrypt.ErrMismatchedHashAndPassword) {
continue continue
} }
log.Errorf("Error while verifying tokens for caldav auth: %v", err) log.Errorf("Error while verifying tokens for caldav auth: %v", err)
return false, nil return nil, nil
} }
return usr, nil
c.Set("userBasicAuth", u)
return true, nil
} }
return nil, nil
return false, nil
} }