Merged release-3.2 into master
Этот коммит содержится в:
@@ -13,11 +13,24 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
func checkPasswordAndAllCriteria(user *model.User, password string, mfaToken string) *model.AppError {
|
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 {
|
if err := checkUserPassword(user, password); err != nil {
|
||||||
return err
|
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
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
14
api/user.go
14
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 {
|
if user, err = authenticateUser(user, password, mfaToken); err != nil {
|
||||||
c.LogAuditWithUserId(user.Id, "failure")
|
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, 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
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1386,8 +1390,12 @@ func updatePassword(c *Context, w http.ResponseWriter, r *http.Request) {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
if !model.ComparePassword(user.Password, currentPassword) {
|
if err := doubleCheckPassword(user, currentPassword); err != nil {
|
||||||
c.Err = model.NewLocAppError("updatePassword", "api.user.update_password.incorrect.app_error", 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
|
c.Err.StatusCode = http.StatusForbidden
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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) {
|
func TestSessions(t *testing.T) {
|
||||||
th := Setup().InitBasic()
|
th := Setup().InitBasic()
|
||||||
Client := th.BasicClient
|
Client := th.BasicClient
|
||||||
@@ -746,6 +782,26 @@ func TestUserUpdatePassword(t *testing.T) {
|
|||||||
t.Fatal(err)
|
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 := &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)
|
user2 = Client.Must(Client.CreateUser(user2, "")).Data.(*model.User)
|
||||||
LinkUserToTeam(user2, team)
|
LinkUserToTeam(user2, team)
|
||||||
|
|||||||
@@ -1793,7 +1793,7 @@
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
"id": "api.user.login.invalid_credentials",
|
"id": "api.user.login.invalid_credentials",
|
||||||
"translation": "User ID or password incorrect."
|
"translation": "Your login credentials are incorrect."
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"id": "api.user.login.not_provided.app_error",
|
"id": "api.user.login.not_provided.app_error",
|
||||||
|
|||||||
@@ -286,13 +286,13 @@
|
|||||||
"admin.image.previewHeightTitle": "Image Preview Height:",
|
"admin.image.previewHeightTitle": "Image Preview Height:",
|
||||||
"admin.image.previewWidthDescription": "Maximum width of preview image. Updating this value changes how preview images render in future, but does not change images created in the past.",
|
"admin.image.previewWidthDescription": "Maximum width of preview image. Updating this value changes how preview images render in future, but does not change images created in the past.",
|
||||||
"admin.image.previewWidthExample": "Ex \"1024\"",
|
"admin.image.previewWidthExample": "Ex \"1024\"",
|
||||||
"admin.image.previewWidthTitle": "Profile Picture Width:",
|
"admin.image.previewWidthTitle": "Image Preview Width:",
|
||||||
"admin.image.profileHeightDescription": "Height of profile picture.",
|
"admin.image.profileHeightDescription": "Height of profile picture.",
|
||||||
"admin.image.profileHeightExample": "Ex \"0\"",
|
"admin.image.profileHeightExample": "Ex \"0\"",
|
||||||
"admin.image.profileHeightTitle": "Profile Picture Height:",
|
"admin.image.profileHeightTitle": "Profile Picture Height:",
|
||||||
"admin.image.profileWidthDescription": "Width of profile picture.",
|
"admin.image.profileWidthDescription": "Width of profile picture.",
|
||||||
"admin.image.profileWidthExample": "Ex \"1024\"",
|
"admin.image.profileWidthExample": "Ex \"1024\"",
|
||||||
"admin.image.profileWidthTitle": "Image Preview Width:",
|
"admin.image.profileWidthTitle": "Profile Picture Width:",
|
||||||
"admin.image.publicLinkDescription": "32-character salt added to signing of public image links. Randomly generated on install. Click \"Regenerate\" to create new salt.",
|
"admin.image.publicLinkDescription": "32-character salt added to signing of public image links. Randomly generated on install. Click \"Regenerate\" to create new salt.",
|
||||||
"admin.image.publicLinkExample": "Ex \"gxHVDcKUyP2y1eiyW8S8na1UYQAfq6J6\"",
|
"admin.image.publicLinkExample": "Ex \"gxHVDcKUyP2y1eiyW8S8na1UYQAfq6J6\"",
|
||||||
"admin.image.publicLinkTitle": "Public Link Salt:",
|
"admin.image.publicLinkTitle": "Public Link Salt:",
|
||||||
|
|||||||
Ссылка в новой задаче
Block a user