Invalidate password recovery tokens on eMail change (#10302)
Этот коммит содержится в:
коммит произвёл
GitHub
родитель
ab812207ab
Коммит
26d3362eca
36
app/user.go
36
app/user.go
@@ -1161,11 +1161,25 @@ func (a *App) ResetPasswordFromToken(userSuppliedTokenString, newPassword string
|
||||
return model.NewAppError("resetPassword", "api.user.reset_password.link_expired.app_error", nil, "", http.StatusBadRequest)
|
||||
}
|
||||
|
||||
user, err := a.GetUser(token.Extra)
|
||||
tokenData := struct {
|
||||
UserId string
|
||||
Email string
|
||||
}{}
|
||||
|
||||
err2 := json.Unmarshal([]byte(token.Extra), &tokenData)
|
||||
if err2 != nil {
|
||||
return model.NewAppError("resetPassword", "api.user.reset_password.token_parse.error", nil, "", http.StatusInternalServerError)
|
||||
}
|
||||
|
||||
user, err := a.GetUser(tokenData.UserId)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if user.Email != tokenData.Email {
|
||||
return model.NewAppError("resetPassword", "api.user.reset_password.link_expired.app_error", nil, "", http.StatusBadRequest)
|
||||
}
|
||||
|
||||
if user.IsSSOUser() {
|
||||
return model.NewAppError("ResetPasswordFromCode", "api.user.reset_password.sso.app_error", nil, "userId="+user.Id, http.StatusBadRequest)
|
||||
}
|
||||
@@ -1193,7 +1207,7 @@ func (a *App) SendPasswordReset(email string, siteURL string) (bool, *model.AppE
|
||||
return false, model.NewAppError("SendPasswordReset", "api.user.send_password_reset.sso.app_error", nil, "userId="+user.Id, http.StatusBadRequest)
|
||||
}
|
||||
|
||||
token, err := a.CreatePasswordRecoveryToken(user.Id)
|
||||
token, err := a.CreatePasswordRecoveryToken(user.Id, user.Email)
|
||||
if err != nil {
|
||||
return false, err
|
||||
}
|
||||
@@ -1201,8 +1215,22 @@ func (a *App) SendPasswordReset(email string, siteURL string) (bool, *model.AppE
|
||||
return a.SendPasswordResetEmail(user.Email, token, user.Locale, siteURL)
|
||||
}
|
||||
|
||||
func (a *App) CreatePasswordRecoveryToken(userId string) (*model.Token, *model.AppError) {
|
||||
token := model.NewToken(TOKEN_TYPE_PASSWORD_RECOVERY, userId)
|
||||
func (a *App) CreatePasswordRecoveryToken(userId, email string) (*model.Token, *model.AppError) {
|
||||
|
||||
tokenExtra := struct {
|
||||
UserId string
|
||||
Email string
|
||||
}{
|
||||
userId,
|
||||
email,
|
||||
}
|
||||
jsonData, err := json.Marshal(tokenExtra)
|
||||
|
||||
if err != nil {
|
||||
return nil, model.NewAppError("CreatePasswordRecoveryToken", "api.user.create_password_token.error", nil, "", http.StatusInternalServerError)
|
||||
}
|
||||
|
||||
token := model.NewToken(TOKEN_TYPE_PASSWORD_RECOVERY, string(jsonData))
|
||||
|
||||
if result := <-a.Srv.Store.Token().Save(token); result.Err != nil {
|
||||
return nil, result.Err
|
||||
|
||||
@@ -622,3 +622,41 @@ func TestPermanentDeleteUser(t *testing.T) {
|
||||
t.Fatal("GetFileInfo after DeleteUser is nil")
|
||||
}
|
||||
}
|
||||
|
||||
func TestPasswordRecovery(t *testing.T) {
|
||||
th := Setup(t).InitBasic()
|
||||
defer th.TearDown()
|
||||
|
||||
token, err := th.App.CreatePasswordRecoveryToken(th.BasicUser.Id, th.BasicUser.Email)
|
||||
assert.Nil(t, err)
|
||||
|
||||
tokenData := struct {
|
||||
UserId string
|
||||
Email string
|
||||
}{}
|
||||
|
||||
err2 := json.Unmarshal([]byte(token.Extra), &tokenData)
|
||||
assert.Nil(t, err2)
|
||||
assert.Equal(t, th.BasicUser.Id, tokenData.UserId)
|
||||
assert.Equal(t, th.BasicUser.Email, tokenData.Email)
|
||||
|
||||
// Password token with same eMail as during creation
|
||||
err = th.App.ResetPasswordFromToken(token.Token, "abcdefgh")
|
||||
assert.Nil(t, err)
|
||||
|
||||
// Password token with modified eMail after creation
|
||||
token, err = th.App.CreatePasswordRecoveryToken(th.BasicUser.Id, th.BasicUser.Email)
|
||||
assert.Nil(t, err)
|
||||
|
||||
th.App.UpdateConfig(func (c *model.Config){
|
||||
*c.EmailSettings.RequireEmailVerification = false
|
||||
})
|
||||
|
||||
th.BasicUser.Email = th.MakeEmail()
|
||||
_, err = th.App.UpdateUser(th.BasicUser, false)
|
||||
assert.Nil(t, err)
|
||||
|
||||
err = th.App.ResetPasswordFromToken(token.Token, "abcdefgh")
|
||||
assert.NotNil(t, err)
|
||||
}
|
||||
|
||||
|
||||
Ссылка в новой задаче
Block a user