2020-09-15 21:09:35 +00:00
|
|
|
# frozen_string_literal: true
|
|
|
|
|
|
|
|
module StaticSiteEditor
|
|
|
|
class ConfigService < ::BaseContainerService
|
|
|
|
ValidationError = Class.new(StandardError)
|
|
|
|
|
2020-09-29 06:09:45 +00:00
|
|
|
def initialize(container:, current_user: nil, params: {})
|
|
|
|
super
|
|
|
|
|
2020-09-15 21:09:35 +00:00
|
|
|
@project = container
|
2020-09-29 06:09:45 +00:00
|
|
|
@repository = project.repository
|
|
|
|
@ref = params.fetch(:ref)
|
|
|
|
end
|
|
|
|
|
|
|
|
def execute
|
2020-09-15 21:09:35 +00:00
|
|
|
check_access!
|
|
|
|
|
2020-09-29 06:09:45 +00:00
|
|
|
file_config = load_file_config!
|
|
|
|
file_data = file_config.to_hash_with_defaults
|
|
|
|
generated_data = load_generated_config.data
|
|
|
|
|
|
|
|
check_for_duplicate_keys!(generated_data, file_data)
|
|
|
|
data = merged_data(generated_data, file_data)
|
|
|
|
|
2020-09-15 21:09:35 +00:00
|
|
|
ServiceResponse.success(payload: data)
|
|
|
|
rescue ValidationError => e
|
|
|
|
ServiceResponse.error(message: e.message)
|
2021-04-26 12:09:44 +00:00
|
|
|
rescue StandardError => e
|
2020-09-29 06:09:45 +00:00
|
|
|
Gitlab::ErrorTracking.track_and_raise_exception(e)
|
2020-09-15 21:09:35 +00:00
|
|
|
end
|
|
|
|
|
|
|
|
private
|
|
|
|
|
2020-09-29 06:09:45 +00:00
|
|
|
attr_reader :project, :repository, :ref
|
|
|
|
|
|
|
|
def static_site_editor_config_file
|
|
|
|
'.gitlab/static-site-editor.yml'
|
|
|
|
end
|
2020-09-15 21:09:35 +00:00
|
|
|
|
|
|
|
def check_access!
|
|
|
|
unless can?(current_user, :download_code, project)
|
|
|
|
raise ValidationError, 'Insufficient permissions to read configuration'
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
2020-09-29 06:09:45 +00:00
|
|
|
def load_file_config!
|
|
|
|
yaml = yaml_from_repo.presence || '{}'
|
|
|
|
file_config = Gitlab::StaticSiteEditor::Config::FileConfig.new(yaml)
|
|
|
|
|
|
|
|
unless file_config.valid?
|
|
|
|
raise ValidationError, file_config.errors.first
|
|
|
|
end
|
|
|
|
|
|
|
|
file_config
|
|
|
|
rescue Gitlab::StaticSiteEditor::Config::FileConfig::ConfigError => e
|
|
|
|
raise ValidationError, e.message
|
2020-09-15 21:09:35 +00:00
|
|
|
end
|
|
|
|
|
2020-09-29 06:09:45 +00:00
|
|
|
def load_generated_config
|
|
|
|
Gitlab::StaticSiteEditor::Config::GeneratedConfig.new(
|
2020-10-01 00:10:16 +00:00
|
|
|
repository,
|
2020-09-29 06:09:45 +00:00
|
|
|
ref,
|
2020-09-15 21:09:35 +00:00
|
|
|
params.fetch(:path),
|
|
|
|
params[:return_url]
|
2020-09-29 06:09:45 +00:00
|
|
|
)
|
2020-09-15 21:09:35 +00:00
|
|
|
end
|
|
|
|
|
2020-09-29 06:09:45 +00:00
|
|
|
def check_for_duplicate_keys!(generated_data, file_data)
|
2020-09-15 21:09:35 +00:00
|
|
|
duplicate_keys = generated_data.keys & file_data.keys
|
2021-05-04 15:10:36 +00:00
|
|
|
raise ValidationError, "Duplicate key(s) '#{duplicate_keys}' found." if duplicate_keys.present?
|
2020-09-15 21:09:35 +00:00
|
|
|
end
|
2020-09-29 06:09:45 +00:00
|
|
|
|
|
|
|
def merged_data(generated_data, file_data)
|
|
|
|
generated_data.merge(file_data)
|
|
|
|
end
|
|
|
|
|
|
|
|
def yaml_from_repo
|
2020-10-01 00:10:16 +00:00
|
|
|
repository.blob_data_at(ref, static_site_editor_config_file)
|
2020-09-29 06:09:45 +00:00
|
|
|
rescue GRPC::NotFound
|
|
|
|
# Return nil in the case of a GRPC::NotFound exception, so the default config will be used.
|
|
|
|
# Allow any other unexpected exception will be tracked and re-raised.
|
|
|
|
nil
|
|
|
|
end
|
2020-09-15 21:09:35 +00:00
|
|
|
end
|
|
|
|
end
|