78 lines
2.3 KiB
Ruby
78 lines
2.3 KiB
Ruby
# frozen_string_literal: true
|
|
|
|
module Ci
|
|
# TODO: rename this (and worker) to CreateDownstreamPipelineService
|
|
class CreateCrossProjectPipelineService < ::BaseService
|
|
include Gitlab::Utils::StrongMemoize
|
|
|
|
def execute(bridge)
|
|
@bridge = bridge
|
|
|
|
pipeline_params = @bridge.downstream_pipeline_params
|
|
target_ref = pipeline_params.dig(:target_revision, :ref)
|
|
|
|
return unless ensure_preconditions!(target_ref)
|
|
|
|
service = ::Ci::CreatePipelineService.new(
|
|
pipeline_params.fetch(:project),
|
|
current_user,
|
|
pipeline_params.fetch(:target_revision))
|
|
|
|
service.execute(
|
|
pipeline_params.fetch(:source), pipeline_params[:execute_params]) do |pipeline|
|
|
pipeline.variables.build(@bridge.downstream_variables)
|
|
end
|
|
end
|
|
|
|
private
|
|
|
|
def ensure_preconditions!(target_ref)
|
|
unless downstream_project_accessible?
|
|
@bridge.drop!(:downstream_bridge_project_not_found)
|
|
return false
|
|
end
|
|
|
|
# TODO: Remove this condition if favour of model validation
|
|
# https://gitlab.com/gitlab-org/gitlab/issues/38338
|
|
if downstream_project == project && !@bridge.triggers_child_pipeline?
|
|
@bridge.drop!(:invalid_bridge_trigger)
|
|
return false
|
|
end
|
|
|
|
# TODO: Remove this condition if favour of model validation
|
|
# https://gitlab.com/gitlab-org/gitlab/issues/38338
|
|
if @bridge.triggers_child_pipeline? && @bridge.pipeline.parent_pipeline.present?
|
|
@bridge.drop!(:bridge_pipeline_is_child_pipeline)
|
|
return false
|
|
end
|
|
|
|
unless can_create_downstream_pipeline?(target_ref)
|
|
@bridge.drop!(:insufficient_bridge_permissions)
|
|
return false
|
|
end
|
|
|
|
true
|
|
end
|
|
|
|
def downstream_project_accessible?
|
|
downstream_project.present? &&
|
|
can?(current_user, :read_project, downstream_project)
|
|
end
|
|
|
|
def can_create_downstream_pipeline?(target_ref)
|
|
can?(current_user, :update_pipeline, project) &&
|
|
can?(current_user, :create_pipeline, downstream_project) &&
|
|
can_update_branch?(target_ref)
|
|
end
|
|
|
|
def can_update_branch?(target_ref)
|
|
::Gitlab::UserAccess.new(current_user, project: downstream_project).can_update_branch?(target_ref)
|
|
end
|
|
|
|
def downstream_project
|
|
strong_memoize(:downstream_project) do
|
|
@bridge.downstream_project
|
|
end
|
|
end
|
|
end
|
|
end
|