Invalidate password recovery tokens on eMail change (#10302)

Этот коммит содержится в:
Daniel Schalla
2019-02-21 00:48:28 +01:00
коммит произвёл GitHub
родитель ab812207ab
Коммит 26d3362eca
2 изменённых файлов: 70 добавлений и 4 удалений

Просмотреть файл

@@ -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)
}