]> source.dussan.org Git - redmine.git/commitdiff
Adds an optional X-Redmine-Switch-User header to let admin users swicth user in API...
authorJean-Philippe Lang <jp_lang@yahoo.fr>
Thu, 11 Oct 2012 17:07:24 +0000 (17:07 +0000)
committerJean-Philippe Lang <jp_lang@yahoo.fr>
Thu, 11 Oct 2012 17:07:24 +0000 (17:07 +0000)
git-svn-id: svn+ssh://rubyforge.org/var/svn/redmine/trunk@10608 e93f8b46-1217-0410-a6f0-8f06a7374b81

app/controllers/application_controller.rb
test/integration/api_test/authentication_test.rb

index e5234a4bc28b882f343e49905e0ad07b4969fd08..6c77796365c86a95d6c1bc70bc5b61d8b04049c8 100644 (file)
@@ -110,6 +110,16 @@ class ApplicationController < ActionController::Base
           user = User.try_to_login(username, password) || User.find_by_api_key(username)
         end
       end
+      # Switch user if requested by an admin user
+      if user && user.admin? && (username = api_switch_user_from_request)
+        su = User.find_by_login(username)
+        if su && su.active?
+          logger.info("  User switched by: #{user.login} (id=#{user.id})") if logger
+          user = su
+        else
+          render_error :message => 'Invalid X-Redmine-Switch-User header', :status => 412
+        end
+      end
     end
     user
   end
@@ -508,6 +518,11 @@ class ApplicationController < ActionController::Base
     end
   end
 
+  # Returns the API 'switch user' value if present
+  def api_switch_user_from_request
+    request.headers["X-Redmine-Switch-User"].to_s.presence
+  end
+
   # Renders a warning flash if obj has unsaved attachments
   def render_attachment_warning_if_needed(obj)
     flash[:warning] = l(:warning_attachments_not_saved, obj.unsaved_attachments.size) if obj.unsaved_attachments.present?
index 10527431a874017d6b50d9b3e28c7896a08277a5..a22c8897b964a28c570a822e1a838fcc234ebf45 100644 (file)
@@ -20,6 +20,14 @@ require File.expand_path('../../../test_helper', __FILE__)
 class ApiTest::AuthenticationTest < ActionController::IntegrationTest
   fixtures :users
 
+  def setup
+    Setting.rest_api_enabled = '1'
+  end
+
+  def teardown
+    Setting.rest_api_enabled = '0'
+  end
+
   def test_api_request_should_not_use_user_session
     log_user('jsmith', 'jsmith')
 
@@ -29,4 +37,37 @@ class ApiTest::AuthenticationTest < ActionController::IntegrationTest
     get '/users/current.json'
     assert_response 401
   end
+
+  def test_api_should_accept_switch_user_header_for_admin_user
+    user = User.find(1)
+    su = User.find(4)
+
+    get '/users/current', {}, {'X-Redmine-API-Key' => user.api_key, 'X-Redmine-Switch-User' => su.login}
+    assert_response :success
+    assert_equal su, assigns(:user)
+    assert_equal su, User.current
+  end
+
+  def test_api_should_respond_with_412_when_trying_to_switch_to_a_invalid_user
+    get '/users/current', {}, {'X-Redmine-API-Key' => User.find(1).api_key, 'X-Redmine-Switch-User' => 'foobar'}
+    assert_response 412
+  end
+
+  def test_api_should_respond_with_412_when_trying_to_switch_to_a_locked_user
+    user = User.find(5)
+    assert user.locked?
+
+    get '/users/current', {}, {'X-Redmine-API-Key' => User.find(1).api_key, 'X-Redmine-Switch-User' => user.login}
+    assert_response 412
+  end
+
+  def test_api_should_not_accept_switch_user_header_for_non_admin_user
+    user = User.find(2)
+    su = User.find(4)
+
+    get '/users/current', {}, {'X-Redmine-API-Key' => user.api_key, 'X-Redmine-Switch-User' => su.login}
+    assert_response :success
+    assert_equal user, assigns(:user)
+    assert_equal user, User.current
+  end
 end