Patch #29781 » 0001-Handles-the-case-when-an-expired-token-is-in-the-use.patch
| app/controllers/account_controller.rb | ||
|---|---|---|
| 62 | 62 |
(redirect_to(home_url); return) unless Setting.lost_password? |
| 63 | 63 |
if prt = (params[:token] || session[:password_recovery_token]) |
| 64 | 64 |
@token = Token.find_token("recovery", prt.to_s)
|
| 65 |
if @token.nil? || @token.expired?
|
|
| 65 |
if @token.nil? |
|
| 66 | 66 |
redirect_to home_url |
| 67 | 67 |
return |
| 68 |
elsif @token.expired? |
|
| 69 |
# remove expired token from session and let user try again |
|
| 70 |
session[:password_recovery_token] = nil |
|
| 71 |
flash[:error] = l(:error_token_expired) |
|
| 72 |
redirect_to lost_password_url |
|
| 73 |
return |
|
| 68 | 74 |
end |
| 69 | 75 | |
| 70 | 76 |
# redirect to remove the token query parameter from the URL and add it to the session |
| config/locales/de.yml | ||
|---|---|---|
| 264 | 264 |
error_scm_command_failed: "Beim Zugriff auf das Repository ist ein Fehler aufgetreten: %{value}"
|
| 265 | 265 |
error_scm_not_found: Eintrag und/oder Revision existiert nicht im Repository. |
| 266 | 266 |
error_session_expired: Ihre Sitzung ist abgelaufen. Bitte melden Sie sich erneut an. |
| 267 |
error_token_expired: "Dieser Link zum Passwort zurücksetzen ist nicht mehr gültig. Bitte versuchen Sie es erneut." |
|
| 267 | 268 |
error_unable_delete_issue_status: "Der Ticket-Status konnte nicht gelöscht werden." |
| 268 | 269 |
error_unable_to_connect: Fehler beim Verbinden (%{value})
|
| 269 | 270 |
error_workflow_copy_source: Bitte wählen Sie einen Quell-Tracker und eine Quell-Rolle. |
| config/locales/en.yml | ||
|---|---|---|
| 208 | 208 |
error_unable_to_connect: "Unable to connect (%{value})"
|
| 209 | 209 |
error_attachment_too_big: "This file cannot be uploaded because it exceeds the maximum allowed file size (%{max_size})"
|
| 210 | 210 |
error_session_expired: "Your session has expired. Please login again." |
| 211 |
error_token_expired: "This password recovery link has expired, please try again." |
|
| 211 | 212 |
warning_attachments_not_saved: "%{count} file(s) could not be saved."
|
| 212 | 213 |
error_password_expired: "Your password has expired or the administrator requires you to change it." |
| 213 | 214 |
error_invalid_file_encoding: "The file is not a valid %{encoding} encoded file"
|
| test/integration/account_test.rb | ||
|---|---|---|
| 146 | 146 |
assert_equal false, Token.exists?(token.id), "Password recovery token was not deleted" |
| 147 | 147 |
end |
| 148 | 148 | |
| 149 |
def test_lost_password_expired_token |
|
| 150 |
Token.delete_all |
|
| 151 | ||
| 152 |
get "/account/lost_password" |
|
| 153 |
assert_response :success |
|
| 154 |
assert_select 'input[name=mail]' |
|
| 155 | ||
| 156 |
post "/account/lost_password", :params => {
|
|
| 157 |
:mail => 'jSmith@somenet.foo' |
|
| 158 |
} |
|
| 159 |
assert_redirected_to "/login" |
|
| 160 | ||
| 161 |
token = Token.first |
|
| 162 |
assert_equal 'recovery', token.action |
|
| 163 |
assert_equal 'jsmith@somenet.foo', token.user.mail |
|
| 164 |
refute token.expired? |
|
| 165 | ||
| 166 |
get "/account/lost_password", :params => {
|
|
| 167 |
:token => token.value |
|
| 168 |
} |
|
| 169 |
assert_redirected_to '/account/lost_password' |
|
| 170 | ||
| 171 |
follow_redirect! |
|
| 172 |
assert_response :success |
|
| 173 | ||
| 174 |
# suppose the user forgets to continue the process and the token expires. |
|
| 175 |
token.update_column :created_on, 1.week.ago |
|
| 176 |
assert token.expired? |
|
| 177 | ||
| 178 |
assert_select 'input[type=hidden][name=token][value=?]', token.value |
|
| 179 |
assert_select 'input[name=new_password]' |
|
| 180 |
assert_select 'input[name=new_password_confirmation]' |
|
| 181 | ||
| 182 |
post "/account/lost_password", :params => {
|
|
| 183 |
:token => token.value, :new_password => 'newpass123', |
|
| 184 |
:new_password_confirmation => 'newpass123' |
|
| 185 |
} |
|
| 186 | ||
| 187 |
assert_redirected_to "/account/lost_password" |
|
| 188 |
assert_equal 'This password recovery link has expired, please try again.', flash[:error] |
|
| 189 |
follow_redirect! |
|
| 190 |
assert_response :success |
|
| 191 | ||
| 192 |
post "/account/lost_password", :params => {
|
|
| 193 |
:mail => 'jSmith@somenet.foo' |
|
| 194 |
} |
|
| 195 |
assert_redirected_to "/login" |
|
| 196 | ||
| 197 |
# should have a new token now |
|
| 198 |
token = Token.last |
|
| 199 |
assert_equal 'recovery', token.action |
|
| 200 |
assert_equal 'jsmith@somenet.foo', token.user.mail |
|
| 201 |
refute token.expired? |
|
| 202 |
end |
|
| 203 | ||
| 149 | 204 |
def test_user_with_must_change_passwd_should_be_forced_to_change_its_password |
| 150 | 205 |
User.find_by_login('jsmith').update_attribute :must_change_passwd, true
|
| 151 | 206 | |