Add login via email (#740)

Add login via email

Co-authored-by: kolaente <k@knt.li>
Reviewed-on: https://kolaente.dev/vikunja/api/pulls/740
Co-Authored-By: konrad <konrad@kola-entertainments.de>
Co-Committed-By: konrad <konrad@kola-entertainments.de>
This commit is contained in:
konrad 2020-12-18 13:54:49 +00:00
parent 8d739b2cf9
commit 0bd2632d29
2 changed files with 26 additions and 5 deletions

View file

@ -176,22 +176,38 @@ func getUser(user *User, withEmail bool) (userOut *User, err error) {
return userOut, err return userOut, err
} }
func getUserByUsernameOrEmail(usernameOrEmail string) (u *User, err error) {
u = &User{}
exists, err := x.
Where("username = ? OR email = ?", usernameOrEmail, usernameOrEmail).
Get(u)
if err != nil {
return nil, err
}
if !exists {
return nil, ErrUserDoesNotExist{}
}
u.Email = ""
return
}
// CheckUserCredentials checks user credentials // CheckUserCredentials checks user credentials
func CheckUserCredentials(u *Login) (*User, error) { func CheckUserCredentials(u *Login) (*User, error) {
// Check if we have any credentials // Check if we have any credentials
if u.Password == "" || u.Username == "" { if u.Password == "" || u.Username == "" {
return &User{}, ErrNoUsernamePassword{} return nil, ErrNoUsernamePassword{}
} }
// Check if the user exists // Check if the user exists
user, err := GetUserByUsername(u.Username) user, err := getUserByUsernameOrEmail(u.Username)
if err != nil { if err != nil {
// hashing the password takes a long time, so we hash something to not make it clear if the username was wrong // hashing the password takes a long time, so we hash something to not make it clear if the username was wrong
_, _ = bcrypt.GenerateFromPassword([]byte(u.Username), 14) _, _ = bcrypt.GenerateFromPassword([]byte(u.Username), 14)
return &User{}, ErrWrongUsernameOrPassword{} return nil, ErrWrongUsernameOrPassword{}
} }
// User is invalid if it needs to verify its email address // The user is invalid if they need to verify their email address
if !user.IsActive { if !user.IsActive {
return &User{}, ErrEmailNotConfirmed{UserID: user.ID} return &User{}, ErrEmailNotConfirmed{UserID: user.ID}
} }
@ -199,7 +215,7 @@ func CheckUserCredentials(u *Login) (*User, error) {
// Check the users password // Check the users password
err = CheckUserPassword(user, u.Password) err = CheckUserPassword(user, u.Password)
if err != nil { if err != nil {
return &User{}, err return nil, err
} }
return user, nil return user, nil

View file

@ -201,6 +201,11 @@ func TestCheckUserCredentials(t *testing.T) {
assert.Error(t, err) assert.Error(t, err)
assert.True(t, IsErrNoUsernamePassword(err)) assert.True(t, IsErrNoUsernamePassword(err))
}) })
t.Run("email", func(t *testing.T) {
db.LoadAndAssertFixtures(t)
_, err := CheckUserCredentials(&Login{Username: "user1@example.com", Password: "1234"})
assert.NoError(t, err)
})
} }
func TestUpdateUser(t *testing.T) { func TestUpdateUser(t *testing.T) {