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 |