diff --git a/app/controllers/application_controller.rb b/app/controllers/application_controller.rb index 7c84b99..803eb5f 100644 --- a/app/controllers/application_controller.rb +++ b/app/controllers/application_controller.rb @@ -71,10 +71,10 @@ class ApplicationController < ActionController::Base elsif params[:format] == 'atom' && params[:key] && accept_key_auth_actions.include?(params[:action]) # RSS key authentication does not start a session User.find_by_rss_key(params[:key]) - elsif Setting.rest_api_enabled? && ['xml', 'json'].include?(params[:format]) - if params[:key].present? && accept_key_auth_actions.include?(params[:action]) + elsif Setting.rest_api_enabled? && api_request? + if (key = api_key_from_request) && accept_key_auth_actions.include?(params[:action]) # Use API key - User.find_by_api_key(params[:key]) + User.find_by_api_key(key) else # HTTP Basic, either username/password or API key/random authenticate_with_http_basic do |username, password| @@ -402,6 +402,15 @@ class ApplicationController < ActionController::Base def api_request? %w(xml json).include? params[:format] end + + # Returns the API key present in the request + def api_key_from_request + if params[:key].present? + params[:key] + elsif request.headers["X-Redmine-API-Key"].present? + request.headers["X-Redmine-API-Key"] + end + end # Renders a warning flash if obj has unsaved attachments def render_attachment_warning_if_needed(obj) diff --git a/test/test_helper.rb b/test/test_helper.rb index 5468152..be87c63 100644 --- a/test/test_helper.rb +++ b/test/test_helper.rb @@ -361,6 +361,20 @@ class ActiveSupport::TestCase end end + context "should allow key based auth using X-Redmine-API-Key header for #{http_method} #{url}" do + setup do + @user = User.generate_with_protected!(:admin => true) + @token = Token.generate!(:user => @user, :action => 'api') + send(http_method, url, parameters, {'X-Redmine-API-Key' => @token.value.to_s}) + end + + should_respond_with success_code + should_respond_with_content_type_based_on_url(url) + should_be_a_valid_response_string_based_on_url(url) + should "login as the user" do + assert_equal @user, User.current + end + end end # Uses should_respond_with_content_type based on what's in the url: