diff options
author | Stan Hu <stanhu@gmail.com> | 2017-12-05 23:23:59 -0800 |
---|---|---|
committer | Stan Hu <stanhu@gmail.com> | 2017-12-12 15:07:24 -0800 |
commit | bc2d32aca0be46250bd02c9312d1064df024b621 (patch) | |
tree | 606015ccb2deb339f10db6830c052f210718a384 | |
parent | f6966cfa63fab7e3c8847d69101c6c6a444fb85f (diff) | |
download | gitlab-ce-bc2d32aca0be46250bd02c9312d1064df024b621.tar.gz |
Create a play_pipeline_schedule policy and use it
4 files changed, 40 insertions, 7 deletions
diff --git a/app/controllers/projects/pipeline_schedules_controller.rb b/app/controllers/projects/pipeline_schedules_controller.rb index 38edb38f9fc..a4e865cb9da 100644 --- a/app/controllers/projects/pipeline_schedules_controller.rb +++ b/app/controllers/projects/pipeline_schedules_controller.rb @@ -1,7 +1,7 @@ class Projects::PipelineSchedulesController < Projects::ApplicationController before_action :schedule, except: [:index, :new, :create] - before_action :authorize_create_pipeline!, only: [:play] + before_action :authorize_play_pipeline_schedule!, only: [:play] before_action :authorize_read_pipeline_schedule! before_action :authorize_create_pipeline_schedule!, only: [:new, :create] before_action :authorize_update_pipeline_schedule!, except: [:index, :new, :create, :play] @@ -84,6 +84,10 @@ class Projects::PipelineSchedulesController < Projects::ApplicationController variables_attributes: [:id, :key, :value, :_destroy] ) end + def authorize_play_pipeline_schedule! + return access_denied! unless can?(current_user, :play_pipeline_schedule, schedule) + end + def authorize_update_pipeline_schedule! return access_denied! unless can?(current_user, :update_pipeline_schedule, schedule) end diff --git a/app/policies/ci/pipeline_schedule_policy.rb b/app/policies/ci/pipeline_schedule_policy.rb index 6b7598e1821..8e7e129f135 100644 --- a/app/policies/ci/pipeline_schedule_policy.rb +++ b/app/policies/ci/pipeline_schedule_policy.rb @@ -2,13 +2,31 @@ module Ci class PipelineSchedulePolicy < PipelinePolicy alias_method :pipeline_schedule, :subject + condition(:protected_ref) do + access = ::Gitlab::UserAccess.new(@user, project: @subject.project) + + if @subject.project.repository.branch_exists?(@subject.ref) + access.can_update_branch?(@subject.ref) + elsif @subject.project.repository.tag_exists?(@subject.ref) + access.can_create_tag?(@subject.ref) + else + true + end + end + condition(:owner_of_schedule) do can?(:developer_access) && pipeline_schedule.owned_by?(@user) end + rule { can?(:developer_access) }.policy do + enable :play_pipeline_schedule + end + rule { can?(:master_access) | owner_of_schedule }.policy do enable :update_pipeline_schedule enable :admin_pipeline_schedule end + + rule { protected_ref }.prevent :play_pipeline_schedule end end diff --git a/app/views/projects/pipeline_schedules/_pipeline_schedule.html.haml b/app/views/projects/pipeline_schedules/_pipeline_schedule.html.haml index 57f0ffba9ff..12d7e81c39e 100644 --- a/app/views/projects/pipeline_schedules/_pipeline_schedule.html.haml +++ b/app/views/projects/pipeline_schedules/_pipeline_schedule.html.haml @@ -26,7 +26,7 @@ = pipeline_schedule.owner&.name %td .pull-right.btn-group - - if can?(current_user, :create_pipeline, @project) + - if can?(current_user, :play_pipeline_schedule, pipeline_schedule) = link_to run_pipeline_schedule_path(pipeline_schedule), method: :post, title: s_('Play'), class: 'btn' do = icon('play') - if can?(current_user, :update_pipeline_schedule, pipeline_schedule) diff --git a/spec/controllers/projects/pipeline_schedules_controller_spec.rb b/spec/controllers/projects/pipeline_schedules_controller_spec.rb index e875f5bce08..3878b0a5e4f 100644 --- a/spec/controllers/projects/pipeline_schedules_controller_spec.rb +++ b/spec/controllers/projects/pipeline_schedules_controller_spec.rb @@ -3,8 +3,8 @@ require 'spec_helper' describe Projects::PipelineSchedulesController do include AccessMatchersForController - set(:project) { create(:project, :public) } - let!(:pipeline_schedule) { create(:ci_pipeline_schedule, project: project) } + set(:project) { create(:project, :public, :repository) } + set(:pipeline_schedule) { create(:ci_pipeline_schedule, project: project) } describe 'GET #index' do let(:scope) { nil } @@ -366,25 +366,36 @@ describe Projects::PipelineSchedulesController do describe 'POST #play' do set(:user) { create(:user) } + let(:ref) { 'master' } context 'when a developer makes the request' do before do project.add_developer(user) + sign_in(user) end it 'executes a new pipeline' do expect(RunPipelineScheduleWorker).to receive(:perform_async).with(pipeline_schedule.id, user.id).and_return('job-123') - go + post :play, namespace_id: project.namespace.to_param, project_id: project, id: pipeline_schedule.id expect(flash[:notice]).to eq 'Successfully scheduled pipeline to run immediately' expect(response).to have_gitlab_http_status(302) end end - def go - post :play, namespace_id: project.namespace.to_param, project_id: project, id: pipeline_schedule.id + context 'when a developer attempts to schedule a protected ref' do + it 'does not allow pipeline to be executed' do + create(:protected_branch, project: project, name: ref) + protected_schedule = create(:ci_pipeline_schedule, project: project, ref: ref) + + expect(RunPipelineScheduleWorker).not_to receive(:perform_async) + + post :play, namespace_id: project.namespace.to_param, project_id: project, id: protected_schedule.id + + expect(response).to have_gitlab_http_status(404) + end end end |