summaryrefslogtreecommitdiffstats
path: root/api
diff options
context:
space:
mode:
authorHarrison Healey <harrisonmhealey@gmail.com>2016-07-12 10:52:43 -0400
committerHarrison Healey <harrisonmhealey@gmail.com>2016-07-12 10:52:43 -0400
commit954e251188621563b3b10218f4072cc358149e84 (patch)
tree0fa41b4ecc7dcd5e9e73062ad6ebc7edd5343da0 /api
parentad343a0f4ad175053f7d0da12a0587bcbb396d1c (diff)
parentc377605906fc7eeb9dcaf75e66732efd3b4fe7fc (diff)
downloadchat-954e251188621563b3b10218f4072cc358149e84.tar.gz
chat-954e251188621563b3b10218f4072cc358149e84.tar.bz2
chat-954e251188621563b3b10218f4072cc358149e84.zip
Merged release-3.2 into master
Diffstat (limited to 'api')
-rw-r--r--api/authentication.go15
-rw-r--r--api/user.go14
-rw-r--r--api/user_test.go56
3 files changed, 81 insertions, 4 deletions
diff --git a/api/authentication.go b/api/authentication.go
index 8170f0a8e..fbfdb2cf4 100644
--- a/api/authentication.go
+++ b/api/authentication.go
@@ -13,11 +13,24 @@ import (
)
func checkPasswordAndAllCriteria(user *model.User, password string, mfaToken string) *model.AppError {
+ if err := checkUserAdditionalAuthenticationCriteria(user, mfaToken); err != nil {
+ return err
+ }
+
if err := checkUserPassword(user, password); err != nil {
return err
}
- if err := checkUserAdditionalAuthenticationCriteria(user, mfaToken); err != nil {
+ return nil
+}
+
+// This to be used for places we check the users password when they are already logged in
+func doubleCheckPassword(user *model.User, password string) *model.AppError {
+ if err := checkUserLoginAttempts(user); err != nil {
+ return err
+ }
+
+ if err := checkUserPassword(user, password); err != nil {
return err
}
diff --git a/api/user.go b/api/user.go
index 3666bfd7a..c64315440 100644
--- a/api/user.go
+++ b/api/user.go
@@ -474,7 +474,11 @@ func login(c *Context, w http.ResponseWriter, r *http.Request) {
if user, err = authenticateUser(user, password, mfaToken); err != nil {
c.LogAuditWithUserId(user.Id, "failure")
//c.Err = model.NewLocAppError("login", "api.user.login.invalid_credentials", nil, err.Error())
- c.Err = model.NewLocAppError("login", "api.user.login.invalid_credentials", nil, "")
+ if err.Id == "api.user.login.not_verified.app_error" {
+ c.Err = err
+ } else {
+ c.Err = model.NewLocAppError("login", "api.user.login.invalid_credentials", nil, "")
+ }
return
}
@@ -1386,8 +1390,12 @@ func updatePassword(c *Context, w http.ResponseWriter, r *http.Request) {
return
}
- if !model.ComparePassword(user.Password, currentPassword) {
- c.Err = model.NewLocAppError("updatePassword", "api.user.update_password.incorrect.app_error", nil, "")
+ if err := doubleCheckPassword(user, currentPassword); err != nil {
+ if err.Id == "api.user.check_user_password.invalid.app_error" {
+ c.Err = model.NewLocAppError("updatePassword", "api.user.update_password.incorrect.app_error", nil, "")
+ } else {
+ c.Err = err
+ }
c.Err.StatusCode = http.StatusForbidden
return
}
diff --git a/api/user_test.go b/api/user_test.go
index 12390135e..5fc0a99dc 100644
--- a/api/user_test.go
+++ b/api/user_test.go
@@ -249,6 +249,42 @@ func TestLoginWithDeviceId(t *testing.T) {
}
}
+func TestPasswordGuessLockout(t *testing.T) {
+ th := Setup().InitBasic()
+ Client := th.BasicClient
+ user := th.BasicUser
+ Client.Must(Client.Logout())
+
+ enableSignInWithEmail := *utils.Cfg.EmailSettings.EnableSignInWithEmail
+ passwordAttempts := utils.Cfg.ServiceSettings.MaximumLoginAttempts
+ defer func() {
+ *utils.Cfg.EmailSettings.EnableSignInWithEmail = enableSignInWithEmail
+ utils.Cfg.ServiceSettings.MaximumLoginAttempts = passwordAttempts
+ }()
+ *utils.Cfg.EmailSettings.EnableSignInWithEmail = true
+ utils.Cfg.ServiceSettings.MaximumLoginAttempts = 2
+
+ // OK to log in
+ if _, err := Client.Login(user.Username, user.Password); err != nil {
+ t.Fatal(err)
+ }
+
+ Client.Must(Client.Logout())
+
+ // Fail twice
+ if _, err := Client.Login(user.Email, "notthepassword"); err == nil {
+ t.Fatal("Shouldn't be able to login with bad password.")
+ }
+ if _, err := Client.Login(user.Email, "notthepassword"); err == nil {
+ t.Fatal("Shouldn't be able to login with bad password.")
+ }
+
+ // Locked out
+ if _, err := Client.Login(user.Email, user.Password); err == nil {
+ t.Fatal("Shouldn't be able to login with password when account is locked out.")
+ }
+}
+
func TestSessions(t *testing.T) {
th := Setup().InitBasic()
Client := th.BasicClient
@@ -746,6 +782,26 @@ func TestUserUpdatePassword(t *testing.T) {
t.Fatal(err)
}
+ // Test lockout
+ passwordAttempts := utils.Cfg.ServiceSettings.MaximumLoginAttempts
+ defer func() {
+ utils.Cfg.ServiceSettings.MaximumLoginAttempts = passwordAttempts
+ }()
+ utils.Cfg.ServiceSettings.MaximumLoginAttempts = 2
+
+ // Fail twice
+ if _, err := Client.UpdateUserPassword(user.Id, "badpwd", "newpwd"); err == nil {
+ t.Fatal("Should have errored")
+ }
+ if _, err := Client.UpdateUserPassword(user.Id, "badpwd", "newpwd"); err == nil {
+ t.Fatal("Should have errored")
+ }
+
+ // Should fail because account is locked out
+ if _, err := Client.UpdateUserPassword(user.Id, "newpwd1", "newpwd2"); err == nil {
+ t.Fatal("Should have errored")
+ }
+
user2 := &model.User{Email: strings.ToLower(model.NewId()) + "success+test@simulator.amazonses.com", Nickname: "Corey Hulen", Password: "passwd1"}
user2 = Client.Must(Client.CreateUser(user2, "")).Data.(*model.User)
LinkUserToTeam(user2, team)