Skip to content

Fixes #64 - Authenticate request with WS repository management API key #81

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 5 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 3 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -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

Expand All @@ -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.*

Expand Down
9 changes: 9 additions & 0 deletions app/controllers/github_hook_controller.rb
Original file line number Diff line number Diff line change
@@ -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
Expand Down Expand Up @@ -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
38 changes: 35 additions & 3 deletions test/functional/github_hook_controller_test.rb
Original file line number Diff line number Diff line change
Expand Up @@ -65,15 +65,21 @@ 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
GithubHook::Updater.any_instance.expects(:system).never
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
Expand All @@ -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
Expand Down Expand Up @@ -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