diff --git a/app/controllers/application.rb b/app/controllers/application.rb index 2daee50de..debe02162 100644 --- a/app/controllers/application.rb +++ b/app/controllers/application.rb @@ -15,6 +15,8 @@ # along with this program; if not, write to the Free Software # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +require 'uri' + class ApplicationController < ActionController::Base before_filter :user_setup, :check_if_login_required, :set_localization filter_parameter_logging :password @@ -77,8 +79,7 @@ class ApplicationController < ActionController::Base def require_login if !User.current.logged? - store_location - redirect_to :controller => "account", :action => "login" + redirect_to :controller => "account", :action => "login", :back_url => request.request_uri return false end true @@ -115,20 +116,16 @@ class ApplicationController < ActionController::Base end end - # store current uri in session. - # return to this location by calling redirect_back_or_default - def store_location - session[:return_to_params] = params - end - - # move to the last store_location call or to the passed default one def redirect_back_or_default(default) - if session[:return_to_params].nil? - redirect_to default - else - redirect_to session[:return_to_params] - session[:return_to_params] = nil + back_url = params[:back_url] + if !back_url.blank? + uri = URI.parse(back_url) + # do not redirect user to another host + if uri.relative? || (uri.host == request.host) + redirect_to(back_url) and return + end end + redirect_to default end def render_403 diff --git a/app/helpers/application_helper.rb b/app/helpers/application_helper.rb index 6e39d093f..7bcec461e 100644 --- a/app/helpers/application_helper.rb +++ b/app/helpers/application_helper.rb @@ -451,7 +451,8 @@ module ApplicationHelper end def back_url_hidden_field_tag - hidden_field_tag 'back_url', (params[:back_url] || request.env['HTTP_REFERER']) + back_url = params[:back_url] || request.env['HTTP_REFERER'] + hidden_field_tag('back_url', back_url) unless back_url.blank? end def check_all_links(form_name) diff --git a/app/views/account/login.rhtml b/app/views/account/login.rhtml index ea1a1cd44..d8c1f313f 100644 --- a/app/views/account/login.rhtml +++ b/app/views/account/login.rhtml @@ -1,5 +1,6 @@
<% form_tag({:action=> "login"}) do %> +<%= back_url_hidden_field_tag %> diff --git a/test/functional/account_controller_test.rb b/test/functional/account_controller_test.rb index 666acf0dd..26218d177 100644 --- a/test/functional/account_controller_test.rb +++ b/test/functional/account_controller_test.rb @@ -44,6 +44,17 @@ class AccountControllerTest < Test::Unit::TestCase assert_nil assigns(:user) end + def test_login_should_redirect_to_back_url_param + # request.uri is "test.host" in test environment + post :login, :username => 'jsmith', :password => 'jsmith', :back_url => 'http://test.host/issues/show/1' + assert_redirected_to '/issues/show/1' + end + + def test_login_should_not_redirect_to_another_host + post :login, :username => 'jsmith', :password => 'jsmith', :back_url => 'http://test.foo/fake' + assert_redirected_to '/my/page' + end + def test_login_with_wrong_password post :login, :username => 'admin', :password => 'bad' assert_response :success