code.gitea.io/gitea@v1.21.7/services/auth/source/db/authenticate.go (about) 1 // Copyright 2021 The Gitea Authors. All rights reserved. 2 // SPDX-License-Identifier: MIT 3 4 package db 5 6 import ( 7 "context" 8 "fmt" 9 10 user_model "code.gitea.io/gitea/models/user" 11 "code.gitea.io/gitea/modules/setting" 12 "code.gitea.io/gitea/modules/util" 13 ) 14 15 // ErrUserPasswordNotSet represents a "ErrUserPasswordNotSet" kind of error. 16 type ErrUserPasswordNotSet struct { 17 UID int64 18 Name string 19 } 20 21 func (err ErrUserPasswordNotSet) Error() string { 22 return fmt.Sprintf("user's password isn't set [uid: %d, name: %s]", err.UID, err.Name) 23 } 24 25 // Unwrap unwraps this error as a ErrInvalidArgument error 26 func (err ErrUserPasswordNotSet) Unwrap() error { 27 return util.ErrInvalidArgument 28 } 29 30 // ErrUserPasswordInvalid represents a "ErrUserPasswordInvalid" kind of error. 31 type ErrUserPasswordInvalid struct { 32 UID int64 33 Name string 34 } 35 36 func (err ErrUserPasswordInvalid) Error() string { 37 return fmt.Sprintf("user's password is invalid [uid: %d, name: %s]", err.UID, err.Name) 38 } 39 40 // Unwrap unwraps this error as a ErrInvalidArgument error 41 func (err ErrUserPasswordInvalid) Unwrap() error { 42 return util.ErrInvalidArgument 43 } 44 45 // Authenticate authenticates the provided user against the DB 46 func Authenticate(ctx context.Context, user *user_model.User, login, password string) (*user_model.User, error) { 47 if user == nil { 48 return nil, user_model.ErrUserNotExist{Name: login} 49 } 50 51 if !user.IsPasswordSet() { 52 return nil, ErrUserPasswordNotSet{UID: user.ID, Name: user.Name} 53 } else if !user.ValidatePassword(password) { 54 return nil, ErrUserPasswordInvalid{UID: user.ID, Name: user.Name} 55 } 56 57 // Update password hash if server password hash algorithm have changed 58 // Or update the password when the salt length doesn't match the current 59 // recommended salt length, this in order to migrate user's salts to a more secure salt. 60 if user.PasswdHashAlgo != setting.PasswordHashAlgo || len(user.Salt) != user_model.SaltByteLength*2 { 61 if err := user.SetPassword(password); err != nil { 62 return nil, err 63 } 64 if err := user_model.UpdateUserCols(ctx, user, "passwd", "passwd_hash_algo", "salt"); err != nil { 65 return nil, err 66 } 67 } 68 69 // WARN: DON'T check user.IsActive, that will be checked on reqSign so that 70 // user could be hinted to resend confirm email. 71 if user.ProhibitLogin { 72 return nil, user_model.ErrUserProhibitLogin{ 73 UID: user.ID, 74 Name: user.Name, 75 } 76 } 77 78 // attempting to login as a non-user account 79 if user.Type != user_model.UserTypeIndividual { 80 return nil, user_model.ErrUserProhibitLogin{ 81 UID: user.ID, 82 Name: user.Name, 83 } 84 } 85 86 return user, nil 87 }