Commit 96c08aedad9004d39d1bd7978a28d71f50a734a3
1 parent
bd6b0bc9
Exists in
colab
and in
4 other branches
Verify GitLab headers on push webhook
Gitlab sends the 'X-Gitlab-Event' header for all the webhook requests. Verify it so we reduce the chance that robots call the hooks accidentally. Signed off by: Daniel Miranda <danielkza2@gmail.com>
Showing
2 changed files
with
27 additions
and
12 deletions
Show diff stats
app/controllers/repositories_controller.rb
| @@ -97,13 +97,17 @@ class RepositoriesController < ApplicationController | @@ -97,13 +97,17 @@ class RepositoriesController < ApplicationController | ||
| 97 | end | 97 | end |
| 98 | 98 | ||
| 99 | def notify_push | 99 | def notify_push |
| 100 | + gitlab_event = request.headers['X-Gitlab-Event'] | ||
| 101 | + if gitlab_event.nil? || !gitlab_event.end_with?('Push Hook') | ||
| 102 | + return render nothing: true, status: :unprocessable_entity | ||
| 103 | + end | ||
| 100 | set_repository | 104 | set_repository |
| 101 | - @repository.cancel_processing_of_repository if @repository.last_processing_state.end_with? 'ING' | 105 | + @repository.cancel_processing_of_repository unless %w(READY, ERROR).include? @repository.last_processing_state |
| 102 | @repository.process | 106 | @repository.process |
| 103 | - render :nothing => true, :status => :ok | 107 | + render nothing: true, status: :ok |
| 104 | end | 108 | end |
| 105 | 109 | ||
| 106 | -private | 110 | + private |
| 107 | def set_project_id_repository_types_and_configurations | 111 | def set_project_id_repository_types_and_configurations |
| 108 | @project_id = params[:project_id] | 112 | @project_id = params[:project_id] |
| 109 | @repository_types = Repository.repository_types | 113 | @repository_types = Repository.repository_types |
spec/controllers/repositories_controller_spec.rb
| @@ -475,9 +475,14 @@ describe RepositoriesController, :type => :controller do | @@ -475,9 +475,14 @@ describe RepositoriesController, :type => :controller do | ||
| 475 | end | 475 | end |
| 476 | 476 | ||
| 477 | describe 'notify_push' do | 477 | describe 'notify_push' do |
| 478 | - context 'with a valid repository' do | ||
| 479 | - let(:repository) { FactoryGirl.build(:repository) } | 478 | + let(:repository) { FactoryGirl.build(:repository) } |
| 480 | 479 | ||
| 480 | + def post_push | ||
| 481 | + @request.env['HTTP_X_GITLAB_EVENT'] = ['Push Hook', 'Tag Push Hook'].sample | ||
| 482 | + post :notify_push, id: repository.id | ||
| 483 | + end | ||
| 484 | + | ||
| 485 | + context 'with a valid repository' do | ||
| 481 | before :each do | 486 | before :each do |
| 482 | Repository.expects(:find).with(repository.id).returns(repository) | 487 | Repository.expects(:find).with(repository.id).returns(repository) |
| 483 | end | 488 | end |
| @@ -487,7 +492,7 @@ describe RepositoriesController, :type => :controller do | @@ -487,7 +492,7 @@ describe RepositoriesController, :type => :controller do | ||
| 487 | repository.expects(:last_processing_state).returns('INTERPRETING') | 492 | repository.expects(:last_processing_state).returns('INTERPRETING') |
| 488 | repository.expects(:cancel_processing_of_repository).once | 493 | repository.expects(:cancel_processing_of_repository).once |
| 489 | repository.expects(:process).once | 494 | repository.expects(:process).once |
| 490 | - post :notify_push, id: repository.id | 495 | + post_push |
| 491 | end | 496 | end |
| 492 | 497 | ||
| 493 | it { is_expected.to respond_with(:ok) } | 498 | it { is_expected.to respond_with(:ok) } |
| @@ -497,7 +502,7 @@ describe RepositoriesController, :type => :controller do | @@ -497,7 +502,7 @@ describe RepositoriesController, :type => :controller do | ||
| 497 | before do | 502 | before do |
| 498 | repository.expects(:last_processing_state).returns('ERROR') | 503 | repository.expects(:last_processing_state).returns('ERROR') |
| 499 | repository.expects(:process).once | 504 | repository.expects(:process).once |
| 500 | - post :notify_push, id: repository.id | 505 | + post_push |
| 501 | end | 506 | end |
| 502 | 507 | ||
| 503 | it { is_expected.to respond_with(:ok) } | 508 | it { is_expected.to respond_with(:ok) } |
| @@ -507,7 +512,7 @@ describe RepositoriesController, :type => :controller do | @@ -507,7 +512,7 @@ describe RepositoriesController, :type => :controller do | ||
| 507 | before do | 512 | before do |
| 508 | repository.expects(:last_processing_state).returns('READY') | 513 | repository.expects(:last_processing_state).returns('READY') |
| 509 | repository.expects(:process).once | 514 | repository.expects(:process).once |
| 510 | - post :notify_push, id: repository.id | 515 | + post_push |
| 511 | end | 516 | end |
| 512 | 517 | ||
| 513 | it { is_expected.to respond_with(:ok) } | 518 | it { is_expected.to respond_with(:ok) } |
| @@ -515,14 +520,20 @@ describe RepositoriesController, :type => :controller do | @@ -515,14 +520,20 @@ describe RepositoriesController, :type => :controller do | ||
| 515 | end | 520 | end |
| 516 | 521 | ||
| 517 | context 'with an invalid repository' do | 522 | context 'with an invalid repository' do |
| 518 | - let(:repository_id) { 1 } | ||
| 519 | - | ||
| 520 | before :each do | 523 | before :each do |
| 521 | - Repository.expects(:find).with(repository_id).raises(KalibroClient::Errors::RecordNotFound) | ||
| 522 | - post :notify_push, id: repository_id | 524 | + Repository.expects(:find).with(repository.id).raises(KalibroClient::Errors::RecordNotFound) |
| 525 | + post_push | ||
| 523 | end | 526 | end |
| 524 | 527 | ||
| 525 | it { is_expected.to respond_with(:not_found) } | 528 | it { is_expected.to respond_with(:not_found) } |
| 526 | end | 529 | end |
| 530 | + | ||
| 531 | + context 'with an invalid header' do | ||
| 532 | + before :each do | ||
| 533 | + post :notify_push, id: repository.id | ||
| 534 | + end | ||
| 535 | + | ||
| 536 | + it { is_expected.to respond_with(:unprocessable_entity) } | ||
| 537 | + end | ||
| 527 | end | 538 | end |
| 528 | end | 539 | end |