Welcome to mirror list, hosted at ThFree Co, Russian Federation.

gitlab.com/gitlab-org/gitlab-foss.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGitLab Bot <gitlab-bot@gitlab.com>2022-12-06 21:08:22 +0300
committerGitLab Bot <gitlab-bot@gitlab.com>2022-12-06 21:08:22 +0300
commit5a73318262aab6ab952f2b7205b3674ea1f20053 (patch)
treee53191adbc529ce23ca08a73e1235c7b6fb6ced5 /lib/gitlab/github_gists_import
parent552877c4d1c535f529be13862692a8fe826a72a2 (diff)
Add latest changes from gitlab-org/gitlab@master
Diffstat (limited to 'lib/gitlab/github_gists_import')
-rw-r--r--lib/gitlab/github_gists_import/importer/gist_importer.rb84
-rw-r--r--lib/gitlab/github_gists_import/representation/gist.rb71
2 files changed, 155 insertions, 0 deletions
diff --git a/lib/gitlab/github_gists_import/importer/gist_importer.rb b/lib/gitlab/github_gists_import/importer/gist_importer.rb
new file mode 100644
index 00000000000..a5e87d3cf7d
--- /dev/null
+++ b/lib/gitlab/github_gists_import/importer/gist_importer.rb
@@ -0,0 +1,84 @@
+# frozen_string_literal: true
+
+module Gitlab
+ module GithubGistsImport
+ module Importer
+ class GistImporter
+ attr_reader :gist, :user
+
+ FileCountLimitError = Class.new(StandardError)
+
+ # gist - An instance of `Gitlab::GithubGistsImport::Representation::Gist`.
+ def initialize(gist, user_id)
+ @gist = gist
+ @user = User.find(user_id)
+ end
+
+ def execute
+ snippet = build_snippet
+ import_repository(snippet) if snippet.save!
+
+ return ServiceResponse.success unless max_snippet_files_count_exceeded?(snippet)
+
+ fail_and_track(snippet)
+ end
+
+ private
+
+ def build_snippet
+ attrs = {
+ title: gist.truncated_title,
+ visibility_level: gist.visibility_level,
+ content: gist.first_file[:file_content],
+ file_name: gist.first_file[:file_name],
+ author: user,
+ created_at: gist.created_at,
+ updated_at: gist.updated_at
+ }
+
+ PersonalSnippet.new(attrs)
+ end
+
+ def import_repository(snippet)
+ resolved_address = get_resolved_address
+
+ snippet.create_repository
+ snippet.repository.fetch_as_mirror(gist.git_pull_url, forced: true, resolved_address: resolved_address)
+ rescue StandardError
+ remove_snippet_and_repository(snippet)
+
+ raise
+ end
+
+ def get_resolved_address
+ validated_pull_url, host = Gitlab::UrlBlocker.validate!(gist.git_pull_url,
+ schemes: Project::VALID_IMPORT_PROTOCOLS,
+ ports: Project::VALID_IMPORT_PORTS,
+ allow_localhost: allow_local_requests?,
+ allow_local_network: allow_local_requests?)
+
+ host.present? ? validated_pull_url.host.to_s : ''
+ end
+
+ def max_snippet_files_count_exceeded?(snippet)
+ snippet.all_files.size > Snippet.max_file_limit
+ end
+
+ def remove_snippet_and_repository(snippet)
+ snippet.repository.remove if snippet.repository_exists?
+ snippet.destroy
+ end
+
+ def allow_local_requests?
+ Gitlab::CurrentSettings.allow_local_requests_from_web_hooks_and_services?
+ end
+
+ def fail_and_track(snippet)
+ remove_snippet_and_repository(snippet)
+
+ ServiceResponse.error(message: 'Snippet max file count exceeded').track_exception(as: FileCountLimitError)
+ end
+ end
+ end
+ end
+end
diff --git a/lib/gitlab/github_gists_import/representation/gist.rb b/lib/gitlab/github_gists_import/representation/gist.rb
new file mode 100644
index 00000000000..0d309a98f38
--- /dev/null
+++ b/lib/gitlab/github_gists_import/representation/gist.rb
@@ -0,0 +1,71 @@
+# frozen_string_literal: true
+
+module Gitlab
+ module GithubGistsImport
+ module Representation
+ class Gist
+ include Gitlab::GithubImport::Representation::ToHash
+ include Gitlab::GithubImport::Representation::ExposeAttribute
+
+ attr_reader :attributes
+
+ expose_attribute :id, :description, :is_public, :created_at, :updated_at, :files, :git_pull_url
+
+ # Builds a gist from a GitHub API response.
+ #
+ # gist - An instance of `Hash` containing the gist
+ # details.
+ def self.from_api_response(gist, additional_data = {})
+ hash = {
+ id: gist[:id],
+ description: gist[:description],
+ is_public: gist[:public],
+ files: gist[:files],
+ git_pull_url: gist[:git_pull_url],
+ created_at: gist[:created_at],
+ updated_at: gist[:updated_at]
+ }
+
+ new(hash)
+ end
+
+ # Builds a new gist using a Hash that was built from a JSON payload.
+ def self.from_json_hash(raw_hash)
+ new(Gitlab::GithubImport::Representation.symbolize_hash(raw_hash))
+ end
+
+ # attributes - A hash containing the raw gist details. The keys of this
+ # Hash (and any nested hashes) must be symbols.
+ def initialize(attributes)
+ @attributes = attributes
+ end
+
+ # Gist description can be an empty string, so we returning nil to use first file
+ # name as a title in such case on snippet creation
+ # Gist description has a limit of 256, while the snippet's title can be up to 255
+ def truncated_title
+ title = description.presence || first_file[:file_name]
+
+ title.truncate(255)
+ end
+
+ def visibility_level
+ is_public ? Gitlab::VisibilityLevel::PUBLIC : Gitlab::VisibilityLevel::PRIVATE
+ end
+
+ def first_file
+ _key, value = files.first
+
+ {
+ file_name: value[:filename],
+ file_content: Gitlab::HTTP.try_get(value[:raw_url])&.body
+ }
+ end
+
+ def github_identifiers
+ { id: id }
+ end
+ end
+ end
+ end
+end