diff options
Diffstat (limited to 'lib/gitlab/ci/config/external')
-rw-r--r-- | lib/gitlab/ci/config/external/file/base.rb | 2 | ||||
-rw-r--r-- | lib/gitlab/ci/config/external/file/project.rb | 72 | ||||
-rw-r--r-- | lib/gitlab/ci/config/external/mapper.rb | 8 | ||||
-rw-r--r-- | lib/gitlab/ci/config/external/processor.rb | 4 |
4 files changed, 80 insertions, 6 deletions
diff --git a/lib/gitlab/ci/config/external/file/base.rb b/lib/gitlab/ci/config/external/file/base.rb index 2ac6656a703..a747886093c 100644 --- a/lib/gitlab/ci/config/external/file/base.rb +++ b/lib/gitlab/ci/config/external/file/base.rb @@ -12,7 +12,7 @@ module Gitlab YAML_WHITELIST_EXTENSION = /.+\.(yml|yaml)$/i.freeze - Context = Struct.new(:project, :sha) + Context = Struct.new(:project, :sha, :user) def initialize(params, context) @params = params diff --git a/lib/gitlab/ci/config/external/file/project.rb b/lib/gitlab/ci/config/external/file/project.rb new file mode 100644 index 00000000000..e75540dbe5a --- /dev/null +++ b/lib/gitlab/ci/config/external/file/project.rb @@ -0,0 +1,72 @@ +# frozen_string_literal: true + +module Gitlab + module Ci + class Config + module External + module File + class Project < Base + include Gitlab::Utils::StrongMemoize + + attr_reader :project_name, :ref_name + + def initialize(params, context = {}) + @location = params[:file] + @project_name = params[:project] + @ref_name = params[:ref] || 'HEAD' + + super + end + + def matching? + super && project_name.present? + end + + def content + strong_memoize(:content) { fetch_local_content } + end + + private + + def validate_content! + if !can_access_local_content? + errors.push("Project `#{project_name}` not found or access denied!") + elsif sha.nil? + errors.push("Project `#{project_name}` reference `#{ref_name}` does not exist!") + elsif content.nil? + errors.push("Project `#{project_name}` file `#{location}` does not exist!") + elsif content.blank? + errors.push("Project `#{project_name}` file `#{location}` is empty!") + end + end + + def project + strong_memoize(:project) do + ::Project.find_by_full_path(project_name) + end + end + + def can_access_local_content? + Ability.allowed?(context.user, :download_code, project) + end + + def fetch_local_content + return unless can_access_local_content? + return unless sha + + project.repository.blob_data_at(sha, location) + rescue GRPC::NotFound, GRPC::Internal + nil + end + + def sha + strong_memoize(:sha) do + project.commit(ref_name).try(:sha) + end + end + end + end + end + end + end +end diff --git a/lib/gitlab/ci/config/external/mapper.rb b/lib/gitlab/ci/config/external/mapper.rb index 74bd927da39..108bfd5eb43 100644 --- a/lib/gitlab/ci/config/external/mapper.rb +++ b/lib/gitlab/ci/config/external/mapper.rb @@ -10,15 +10,17 @@ module Gitlab FILE_CLASSES = [ External::File::Remote, External::File::Template, - External::File::Local + External::File::Local, + External::File::Project ].freeze AmbigiousSpecificationError = Class.new(StandardError) - def initialize(values, project:, sha:) + def initialize(values, project:, sha:, user:) @locations = Array.wrap(values.fetch(:include, [])) @project = project @sha = sha + @user = user end def process @@ -61,7 +63,7 @@ module Gitlab def context strong_memoize(:context) do - External::File::Base::Context.new(project, sha) + External::File::Base::Context.new(project, sha, user) end end end diff --git a/lib/gitlab/ci/config/external/processor.rb b/lib/gitlab/ci/config/external/processor.rb index 1d310b29dc8..69bc164a039 100644 --- a/lib/gitlab/ci/config/external/processor.rb +++ b/lib/gitlab/ci/config/external/processor.rb @@ -7,9 +7,9 @@ module Gitlab class Processor IncludeError = Class.new(StandardError) - def initialize(values, project:, sha:) + def initialize(values, project:, sha:, user:) @values = values - @external_files = External::Mapper.new(values, project: project, sha: sha).process + @external_files = External::Mapper.new(values, project: project, sha: sha, user: user).process @content = {} rescue External::Mapper::AmbigiousSpecificationError => e raise IncludeError, e.message |