Commit bc2d32ac authored by Stan Hu's avatar Stan Hu

Create a play_pipeline_schedule policy and use it

parent f6966cfa
class Projects::PipelineSchedulesController < Projects::ApplicationController class Projects::PipelineSchedulesController < Projects::ApplicationController
before_action :schedule, except: [:index, :new, :create] 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_read_pipeline_schedule!
before_action :authorize_create_pipeline_schedule!, only: [:new, :create] before_action :authorize_create_pipeline_schedule!, only: [:new, :create]
before_action :authorize_update_pipeline_schedule!, except: [:index, :new, :create, :play] before_action :authorize_update_pipeline_schedule!, except: [:index, :new, :create, :play]
...@@ -84,6 +84,10 @@ class Projects::PipelineSchedulesController < Projects::ApplicationController ...@@ -84,6 +84,10 @@ class Projects::PipelineSchedulesController < Projects::ApplicationController
variables_attributes: [:id, :key, :value, :_destroy] ) variables_attributes: [:id, :key, :value, :_destroy] )
end end
def authorize_play_pipeline_schedule!
return access_denied! unless can?(current_user, :play_pipeline_schedule, schedule)
end
def authorize_update_pipeline_schedule! def authorize_update_pipeline_schedule!
return access_denied! unless can?(current_user, :update_pipeline_schedule, schedule) return access_denied! unless can?(current_user, :update_pipeline_schedule, schedule)
end end
......
...@@ -2,13 +2,31 @@ module Ci ...@@ -2,13 +2,31 @@ module Ci
class PipelineSchedulePolicy < PipelinePolicy class PipelineSchedulePolicy < PipelinePolicy
alias_method :pipeline_schedule, :subject 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 condition(:owner_of_schedule) do
can?(:developer_access) && pipeline_schedule.owned_by?(@user) can?(:developer_access) && pipeline_schedule.owned_by?(@user)
end end
rule { can?(:developer_access) }.policy do
enable :play_pipeline_schedule
end
rule { can?(:master_access) | owner_of_schedule }.policy do rule { can?(:master_access) | owner_of_schedule }.policy do
enable :update_pipeline_schedule enable :update_pipeline_schedule
enable :admin_pipeline_schedule enable :admin_pipeline_schedule
end end
rule { protected_ref }.prevent :play_pipeline_schedule
end end
end end
...@@ -26,7 +26,7 @@ ...@@ -26,7 +26,7 @@
= pipeline_schedule.owner&.name = pipeline_schedule.owner&.name
%td %td
.pull-right.btn-group .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 = link_to run_pipeline_schedule_path(pipeline_schedule), method: :post, title: s_('Play'), class: 'btn' do
= icon('play') = icon('play')
- if can?(current_user, :update_pipeline_schedule, pipeline_schedule) - if can?(current_user, :update_pipeline_schedule, pipeline_schedule)
......
...@@ -3,8 +3,8 @@ require 'spec_helper' ...@@ -3,8 +3,8 @@ require 'spec_helper'
describe Projects::PipelineSchedulesController do describe Projects::PipelineSchedulesController do
include AccessMatchersForController include AccessMatchersForController
set(:project) { create(:project, :public) } set(:project) { create(:project, :public, :repository) }
let!(:pipeline_schedule) { create(:ci_pipeline_schedule, project: project) } set(:pipeline_schedule) { create(:ci_pipeline_schedule, project: project) }
describe 'GET #index' do describe 'GET #index' do
let(:scope) { nil } let(:scope) { nil }
...@@ -366,25 +366,36 @@ describe Projects::PipelineSchedulesController do ...@@ -366,25 +366,36 @@ describe Projects::PipelineSchedulesController do
describe 'POST #play' do describe 'POST #play' do
set(:user) { create(:user) } set(:user) { create(:user) }
let(:ref) { 'master' }
context 'when a developer makes the request' do context 'when a developer makes the request' do
before do before do
project.add_developer(user) project.add_developer(user)
sign_in(user) sign_in(user)
end end
it 'executes a new pipeline' do it 'executes a new pipeline' do
expect(RunPipelineScheduleWorker).to receive(:perform_async).with(pipeline_schedule.id, user.id).and_return('job-123') 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(flash[:notice]).to eq 'Successfully scheduled pipeline to run immediately'
expect(response).to have_gitlab_http_status(302) expect(response).to have_gitlab_http_status(302)
end end
end end
def go context 'when a developer attempts to schedule a protected ref' do
post :play, namespace_id: project.namespace.to_param, project_id: project, id: pipeline_schedule.id 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
end end
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment