Skip to content
Snippets Groups Projects
Commit 67a566c5 authored by Florent Gluck's avatar Florent Gluck
Browse files

server: updated user locking which wasn't working as it should

parent 87d4adca
No related branches found
No related tags found
No related merge requests found
......@@ -35,7 +35,7 @@ type userRequest struct {
var loginAttempts map[userRequest]int // Number of consecutive wrong logins for the same user
var loginAttemptsMutex *sync.Mutex
var lockedUsers map[string]time.Time // Locked users and timestamps when their accounts were locked
var lockedUsers map[userRequest]time.Time // Locked users and timestamps when their accounts were locked
var lockedUsersMutex *sync.Mutex
var jwtSecretKey string
......@@ -44,7 +44,7 @@ var jwtSecretKey string
func NewAuth(u *users.Users) (*auth, error) {
loginAttempts = make(map[userRequest]int)
loginAttemptsMutex = new(sync.Mutex)
lockedUsers = make(map[string]time.Time)
lockedUsers = make(map[userRequest]time.Time)
lockedUsersMutex = new(sync.Mutex)
// TODO: better to store jwtSecretKey in an env. variable?
......@@ -95,9 +95,12 @@ func (auth *auth) Login(c echo.Context) error {
return echo.NewHTTPError(http.StatusUnauthorized, err.Error())
}
// A user request is the combination of user email and where the request comes from (ip address)
userReq := userRequest{email: user.Email, ip: c.RealIP()}
// Is user locked?
lockedUsersMutex.Lock()
lockedTime, found := lockedUsers[user.Email]
lockedTime, found := lockedUsers[userReq]
if found {
lockedUsersMutex.Unlock()
// If locked time has elapsed, unlock the user.
......@@ -120,7 +123,6 @@ func (auth *auth) Login(c echo.Context) error {
err = bcrypt.CompareHashAndPassword([]byte(user.Pwd), []byte(reqUser.Pwd))
// If err == nil, passwords match!
userReq := userRequest{email: user.Email, ip: c.RealIP()}
if err == nil {
loginAttemptsMutex.Lock()
loginAttempts[userReq] = 0
......@@ -140,7 +142,7 @@ func (auth *auth) Login(c echo.Context) error {
if count > conf.Auth.MaxLoginAttempts {
// Locks user
lockedUsersMutex.Lock()
lockedUsers[user.Email] = time.Now()
lockedUsers[userReq] = time.Now()
lockedUsersMutex.Unlock()
log.Info("User ", user.Email, " is locked: too many wrong password attempts, source ip=", c.RealIP())
return echo.NewHTTPError(http.StatusUnauthorized, "User is locked")
......@@ -208,15 +210,23 @@ func UnlockUser(c echo.Context, emailToUnlock string) error {
lockedUsersMutex.Lock()
defer lockedUsersMutex.Unlock()
_, found := lockedUsers[emailToUnlock]
if found {
// unlock user by removing it from the locked map
delete(lockedUsers, emailToUnlock)
loginAttemptsMutex.Lock()
userReq := userRequest{email: userEmail, ip: c.RealIP()}
loginAttempts[userReq] = 0 // reset the number of attempts
loginAttemptsMutex.Unlock()
log.Info("User ", userEmail, " unlocked user ", emailToUnlock, ", source ip=", c.RealIP())
// Remove all entries matching the user email to unlock
userFound := false
for _userReq := range lockedUsers {
if _userReq.email == emailToUnlock {
delete(lockedUsers, _userReq)
loginAttemptsMutex.Lock()
delete(loginAttempts, _userReq) // reset the number of attempts
loginAttemptsMutex.Unlock()
log.Info("User ", userEmail, " unlocked user {", _userReq.email, ",", _userReq.ip, "}, source ip=", c.RealIP())
userFound = true
}
}
if userFound {
return nil
} else {
return errors.New("User not locked")
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment