Commit fa3fb23f authored by Grzegorz Bizon's avatar Grzegorz Bizon

Move pipeline builder validation chain to a module

parent 609fa45f
...@@ -2,9 +2,9 @@ module Ci ...@@ -2,9 +2,9 @@ module Ci
class CreatePipelineService < BaseService class CreatePipelineService < BaseService
attr_reader :pipeline attr_reader :pipeline
SEQUENCE = [Gitlab::Ci::Pipeline::Chain::ValidateAbilities, SEQUENCE = [Gitlab::Ci::Pipeline::Chain::Validate::Abilities,
Gitlab::Ci::Pipeline::Chain::ValidateRepository, Gitlab::Ci::Pipeline::Chain::Validate::Repository,
Gitlab::Ci::Pipeline::Chain::ValidateConfig, Gitlab::Ci::Pipeline::Chain::Validate::Config,
Gitlab::Ci::Pipeline::Chain::Skip, Gitlab::Ci::Pipeline::Chain::Skip,
Gitlab::Ci::Pipeline::Chain::Create].freeze Gitlab::Ci::Pipeline::Chain::Create].freeze
......
module Gitlab
module Ci
module Pipeline
module Chain
module Validate
class Abilities < Chain::Base
include Gitlab::Allowable
include Chain::Helpers
def perform!
unless project.builds_enabled?
return error('Pipelines are disabled!')
end
unless allowed_to_trigger_pipeline?
if can?(current_user, :create_pipeline, project)
return error("Insufficient permissions for protected ref '#{pipeline.ref}'")
else
return error('Insufficient permissions to create a new pipeline')
end
end
end
def break?
@pipeline.errors.any?
end
def allowed_to_trigger_pipeline?
if current_user
allowed_to_create?
else # legacy triggers don't have a corresponding user
!project.protected_for?(@pipeline.ref)
end
end
def allowed_to_create?
return unless can?(current_user, :create_pipeline, project)
access = Gitlab::UserAccess.new(current_user, project: project)
if branch_exists?
access.can_update_branch?(@pipeline.ref)
elsif tag_exists?
access.can_create_tag?(@pipeline.ref)
else
true # Allow it for now and we'll reject when we check ref existence
end
end
end
end
end
end
end
end
module Gitlab
module Ci
module Pipeline
module Chain
module Validate
class Config < Chain::Base
include Chain::Helpers
def perform!
unless @pipeline.config_processor
unless @pipeline.ci_yaml_file
return error("Missing #{@pipeline.ci_yaml_file_path} file")
end
if @command.save_incompleted && @pipeline.has_yaml_errors?
@pipeline.drop
end
return error(@pipeline.yaml_errors)
end
unless @pipeline.has_stage_seeds?
return error('No stages / jobs for this pipeline.')
end
end
def break?
@pipeline.errors.any? || @pipeline.persisted?
end
end
end
end
end
end
end
module Gitlab
module Ci
module Pipeline
module Chain
module Validate
class Repository < Chain::Base
include Chain::Helpers
def perform!
unless branch_exists? || tag_exists?
return error('Reference not found')
end
## TODO, we check commit in the service, that is why
# there is no repository access here.
#
# Should we validate repository before building a pipeline?
#
unless pipeline.sha
return error('Commit not found')
end
end
def break?
@pipeline.errors.any?
end
end
end
end
end
end
end
module Gitlab
module Ci
module Pipeline
module Chain
class ValidateAbilities < Chain::Base
include Gitlab::Allowable
include Chain::Helpers
def perform!
unless project.builds_enabled?
return error('Pipelines are disabled!')
end
unless allowed_to_trigger_pipeline?
if can?(current_user, :create_pipeline, project)
return error("Insufficient permissions for protected ref '#{pipeline.ref}'")
else
return error('Insufficient permissions to create a new pipeline')
end
end
end
def break?
@pipeline.errors.any?
end
def allowed_to_trigger_pipeline?
if current_user
allowed_to_create?
else # legacy triggers don't have a corresponding user
!project.protected_for?(@pipeline.ref)
end
end
def allowed_to_create?
return unless can?(current_user, :create_pipeline, project)
access = Gitlab::UserAccess.new(current_user, project: project)
if branch_exists?
access.can_update_branch?(@pipeline.ref)
elsif tag_exists?
access.can_create_tag?(@pipeline.ref)
else
true # Allow it for now and we'll reject when we check ref existence
end
end
end
end
end
end
end
module Gitlab
module Ci
module Pipeline
module Chain
class ValidateConfig < Chain::Base
include Chain::Helpers
def perform!
unless @pipeline.config_processor
unless @pipeline.ci_yaml_file
return error("Missing #{@pipeline.ci_yaml_file_path} file")
end
if @command.save_incompleted && @pipeline.has_yaml_errors?
@pipeline.drop
end
return error(@pipeline.yaml_errors)
end
unless @pipeline.has_stage_seeds?
return error('No stages / jobs for this pipeline.')
end
end
def break?
@pipeline.errors.any? || @pipeline.persisted?
end
end
end
end
end
end
module Gitlab
module Ci
module Pipeline
module Chain
class ValidateRepository < Chain::Base
include Chain::Helpers
def perform!
unless branch_exists? || tag_exists?
return error('Reference not found')
end
## TODO, we check commit in the service, that is why
# there is no repository access here.
#
# Should we validate repository before building a pipeline?
#
unless pipeline.sha
return error('Commit not found')
end
end
def break?
@pipeline.errors.any?
end
end
end
end
end
end
require 'spec_helper' require 'spec_helper'
describe Gitlab::Ci::Pipeline::Chain::ValidateAbilities do describe Gitlab::Ci::Pipeline::Chain::Validate::Abilities do
describe '#allowed_to_create?' do describe '#allowed_to_create?' do
let(:user) { create(:user) } let(:user) { create(:user) }
let(:project) { create(:project, :repository) } let(:project) { create(:project, :repository) }
......
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