summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--app/controllers/account_controller.rb8
-rw-r--r--config/locales/de.yml1
-rw-r--r--config/locales/en.yml1
-rw-r--r--test/integration/account_test.rb55
4 files changed, 64 insertions, 1 deletions
diff --git a/app/controllers/account_controller.rb b/app/controllers/account_controller.rb
index 7bb644761..f604540a7 100644
--- a/app/controllers/account_controller.rb
+++ b/app/controllers/account_controller.rb
@@ -62,9 +62,15 @@ class AccountController < ApplicationController
(redirect_to(home_url); return) unless Setting.lost_password?
if prt = (params[:token] || session[:password_recovery_token])
@token = Token.find_token("recovery", prt.to_s)
- if @token.nil? || @token.expired?
+ if @token.nil?
redirect_to home_url
return
+ elsif @token.expired?
+ # remove expired token from session and let user try again
+ session[:password_recovery_token] = nil
+ flash[:error] = l(:error_token_expired)
+ redirect_to lost_password_url
+ return
end
# redirect to remove the token query parameter from the URL and add it to the session
diff --git a/config/locales/de.yml b/config/locales/de.yml
index 1b166a033..cc04355d7 100644
--- a/config/locales/de.yml
+++ b/config/locales/de.yml
@@ -264,6 +264,7 @@ de:
error_scm_command_failed: "Beim Zugriff auf das Repository ist ein Fehler aufgetreten: %{value}"
error_scm_not_found: Eintrag und/oder Revision existiert nicht im Repository.
error_session_expired: Ihre Sitzung ist abgelaufen. Bitte melden Sie sich erneut an.
+ error_token_expired: "Dieser Link zum Passwort zurücksetzen ist nicht mehr gültig. Bitte versuchen Sie es erneut."
error_unable_delete_issue_status: "Der Ticket-Status konnte nicht gelöscht werden."
error_unable_to_connect: Fehler beim Verbinden (%{value})
error_workflow_copy_source: Bitte wählen Sie einen Quell-Tracker und eine Quell-Rolle.
diff --git a/config/locales/en.yml b/config/locales/en.yml
index 6e2cd75c5..36d2099c8 100644
--- a/config/locales/en.yml
+++ b/config/locales/en.yml
@@ -208,6 +208,7 @@ en:
error_unable_to_connect: "Unable to connect (%{value})"
error_attachment_too_big: "This file cannot be uploaded because it exceeds the maximum allowed file size (%{max_size})"
error_session_expired: "Your session has expired. Please login again."
+ error_token_expired: "This password recovery link has expired, please try again."
warning_attachments_not_saved: "%{count} file(s) could not be saved."
error_password_expired: "Your password has expired or the administrator requires you to change it."
error_invalid_file_encoding: "The file is not a valid %{encoding} encoded file"
diff --git a/test/integration/account_test.rb b/test/integration/account_test.rb
index a3a1ecb2e..4f0a45156 100644
--- a/test/integration/account_test.rb
+++ b/test/integration/account_test.rb
@@ -146,6 +146,61 @@ class AccountTest < Redmine::IntegrationTest
assert_equal false, Token.exists?(token.id), "Password recovery token was not deleted"
end
+ def test_lost_password_expired_token
+ Token.delete_all
+
+ get "/account/lost_password"
+ assert_response :success
+ assert_select 'input[name=mail]'
+
+ post "/account/lost_password", :params => {
+ :mail => 'jSmith@somenet.foo'
+ }
+ assert_redirected_to "/login"
+
+ token = Token.first
+ assert_equal 'recovery', token.action
+ assert_equal 'jsmith@somenet.foo', token.user.mail
+ refute token.expired?
+
+ get "/account/lost_password", :params => {
+ :token => token.value
+ }
+ assert_redirected_to '/account/lost_password'
+
+ follow_redirect!
+ assert_response :success
+
+ # suppose the user forgets to continue the process and the token expires.
+ token.update_column :created_on, 1.week.ago
+ assert token.expired?
+
+ assert_select 'input[type=hidden][name=token][value=?]', token.value
+ assert_select 'input[name=new_password]'
+ assert_select 'input[name=new_password_confirmation]'
+
+ post "/account/lost_password", :params => {
+ :token => token.value, :new_password => 'newpass123',
+ :new_password_confirmation => 'newpass123'
+ }
+
+ assert_redirected_to "/account/lost_password"
+ assert_equal 'This password recovery link has expired, please try again.', flash[:error]
+ follow_redirect!
+ assert_response :success
+
+ post "/account/lost_password", :params => {
+ :mail => 'jSmith@somenet.foo'
+ }
+ assert_redirected_to "/login"
+
+ # should have a new token now
+ token = Token.last
+ assert_equal 'recovery', token.action
+ assert_equal 'jsmith@somenet.foo', token.user.mail
+ refute token.expired?
+ end
+
def test_user_with_must_change_passwd_should_be_forced_to_change_its_password
User.find_by_login('jsmith').update_attribute :must_change_passwd, true