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
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?
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')
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