diff --git a/README.md b/README.md index ae312c9..719cd7b 100644 --- a/README.md +++ b/README.md @@ -19,6 +19,7 @@ That approach works perfectly fine, but is a bit heavy-handed and cumbersome. Th `gem "redmine_github_hook"` 2. `bundle` 3. Restart your Redmine +4. Enable **Enable WS for repository management** in **Administration** > **Settings** > **Repositories** and generate an API key ### 2. Add the repository to Redmine @@ -32,9 +33,9 @@ Adding a Git repository to a project (note, this should work whether you want to 1. Go to the repository Settings interface on GitHub. 2. Under "Webhooks & Services" add a new "WebHook". The "Payload URL" needs to be of the format: `[redmine_url]/github_hook` (for example `http://redmine.example.com/github_hook`). * By default, GitHub Hook assumes your GitHub repository name is the same as the *project identifier* in your Redmine installation. - * If this is not the case, you can specify the actual Redmine project identifier in the Post-Receive URL by using the format `[redmine_url]/github_hook?project_id=[identifier]` (for example `http://redmine.example.com/github_hook?project_id=my_project`). + * If this is not the case, you can specify the actual Redmine project identifier in the Post-Receive URL by using the format `[redmine_url]/github_hook?key=[api_key]&project_id=[identifier]` (for example `http://redmine.example.com/github_hook?key=my_api_key&project_id=my_project`). * GitHub Hook will then update **all repositories** in the specified project. *Be aware, that this process may take a while if you have many repositories in your project.* - * If you want GitHub Hook to **only update the current repository** you can specify it with an additional parameter in the Post-Receive URL by using the format `[redmine_url]/github_hook?project_id=[identifier]&repository_id=[repository]` (for example `http://redmine.example.com/github_hook?project_id=my_project&repository_id=my_repo`). + * If you want GitHub Hook to **only update the current repository** you can specify it with an additional parameter in the Post-Receive URL by using the format `[redmine_url]/github_hook?key=[api_key]&project_id=[identifier]&repository_id=[repository]` (for example `http://redmine.example.com/github_hook?key=my_api_key&project_id=my_project&repository_id=my_repo`). * In most cases, just having the "push" event trigger the webhook should suffice, but you are free to customize the events as you desire. * *Note: Make sure you're adding a Webhook - which is what Redmine Github Hook expects. GitHub has some builtin Redmine integration; that's not what you're looking for.* diff --git a/app/controllers/github_hook_controller.rb b/app/controllers/github_hook_controller.rb index 620bf35..8e4033c 100644 --- a/app/controllers/github_hook_controller.rb +++ b/app/controllers/github_hook_controller.rb @@ -1,6 +1,7 @@ require "json" class GithubHookController < ApplicationController + before_filter :check_enabled skip_before_filter :verify_authenticity_token, :check_if_login_required def index @@ -41,4 +42,12 @@ def update_repository(logger) updater.logger = logger updater.call end + + def check_enabled + User.current = nil + unless Setting.sys_api_enabled? && (Setting.sys_api_key.empty? || params[:key].to_s == Setting.sys_api_key) + render :text => 'Access denied. Repository management WS is disabled or key is invalid.', :status => 403 + return false + end + end end diff --git a/test/functional/github_hook_controller_test.rb b/test/functional/github_hook_controller_test.rb index 7d5a5e0..ed96925 100644 --- a/test/functional/github_hook_controller_test.rb +++ b/test/functional/github_hook_controller_test.rb @@ -65,6 +65,8 @@ def project end def setup + Setting.sys_api_enabled = '1' + Setting.sys_api_key = 'my_secret_key' Project.stubs(:find_by_identifier).with("github").returns(project) # Make sure we don't run actual commands in test @@ -72,8 +74,12 @@ def setup Repository.expects(:fetch_changesets).never end - def do_post - post :index, :payload => json + def teardown + Setting.clear_cache + end + + def do_post(key: 'my_secret_key') + post :index, :payload => json, :key => key end def test_should_render_response_from_github_hook_when_done @@ -83,6 +89,27 @@ def test_should_render_response_from_github_hook_when_done assert_match "GithubHook: Redmine repository updated", @response.body end + def test_should_render_response_from_github_hook_when_done_with_empty_sys_api_key + GithubHook::Updater.any_instance.expects(:update_repository).returns(true) + with_settings :sys_api_key => '' do + do_post :key => 'wrong_key' + end + assert_response :success + assert_match "GithubHook: Redmine repository updated", @response.body + end + + def test_disabled_ws_should_respond_with_403 + with_settings :sys_api_enabled => '0' do + do_post + assert_response 403 + end + end + + def test_wrong_key_should_respond_with_403 + do_post :key => 'wrong_key' + assert_response 403 + end + def test_should_render_error_message GithubHook::Updater .any_instance @@ -115,7 +142,12 @@ def test_exec_should_log_output_from_git_as_error_when_things_go_sour end def test_should_respond_to_get - get :index + get :index, :key => 'my_secret_key' assert_response :success end + + def test_wrong_key_should_respond_to_get_with_403 + get :index, :key => 'wrong_key' + assert_response 403 + end end