2019-03-02 22:35:43 +05:30
# frozen_string_literal: true
module Import
class GithubService < Import :: BaseService
2021-04-17 20:07:23 +05:30
include ActiveSupport :: NumberHelper
include Gitlab :: Utils :: StrongMemoize
2019-03-02 22:35:43 +05:30
attr_accessor :client
attr_reader :params , :current_user
def execute ( access_params , provider )
2022-11-25 23:54:43 +05:30
context_error = validate_context
return context_error if context_error
2021-04-17 20:07:23 +05:30
2020-06-23 00:09:42 +05:30
project = create_project ( access_params , provider )
2023-03-04 22:38:38 +05:30
track_access_level ( 'github' )
2019-03-02 22:35:43 +05:30
if project . persisted?
2022-11-25 23:54:43 +05:30
store_import_settings ( project )
2019-03-02 22:35:43 +05:30
success ( project )
2022-07-16 23:28:13 +05:30
elsif project . errors [ :import_source_disabled ] . present?
error ( project . errors [ :import_source_disabled ] , :forbidden )
2019-03-02 22:35:43 +05:30
else
error ( project_save_error ( project ) , :unprocessable_entity )
end
2020-06-23 00:09:42 +05:30
rescue Octokit :: Error = > e
log_error ( e )
end
def create_project ( access_params , provider )
Gitlab :: LegacyGithubImport :: ProjectCreator . new (
repo ,
project_name ,
target_namespace ,
current_user ,
2021-02-22 17:27:13 +05:30
type : provider ,
2021-04-17 20:07:23 +05:30
** access_params
) . execute ( extra_project_attrs )
2019-03-02 22:35:43 +05:30
end
def repo
2020-10-24 23:57:45 +05:30
@repo || = client . repository ( params [ :repo_id ] . to_i )
2019-03-02 22:35:43 +05:30
end
def project_name
2022-10-11 01:57:18 +05:30
@project_name || = params [ :new_name ] . presence || repo [ :name ]
2019-03-02 22:35:43 +05:30
end
def target_namespace
2023-03-17 16:20:25 +05:30
@target_namespace || = Namespace . find_by_full_path ( target_namespace_path )
2019-03-02 22:35:43 +05:30
end
def extra_project_attrs
{ }
end
2021-04-17 20:07:23 +05:30
def oversized?
2022-10-11 01:57:18 +05:30
repository_size_limit > 0 && repo [ :size ] > repository_size_limit
2021-04-17 20:07:23 +05:30
end
def oversize_error_message
_ ( '"%{repository_name}" size (%{repository_size}) is larger than the limit of %{limit}.' ) % {
2022-10-11 01:57:18 +05:30
repository_name : repo [ :name ] ,
repository_size : number_to_human_size ( repo [ :size ] ) ,
2021-04-17 20:07:23 +05:30
limit : number_to_human_size ( repository_size_limit )
}
end
def repository_size_limit
strong_memoize :repository_size_limit do
namespace_limit = target_namespace . repository_size_limit . to_i
if namespace_limit > 0
namespace_limit
else
Gitlab :: CurrentSettings . repository_size_limit . to_i
end
end
end
2021-01-29 00:20:46 +05:30
def url
@url || = params [ :github_hostname ]
end
def allow_local_requests?
Gitlab :: CurrentSettings . allow_local_requests_from_web_hooks_and_services?
end
def blocked_url?
Gitlab :: UrlBlocker . blocked_url? (
url ,
2021-02-22 17:27:13 +05:30
allow_localhost : allow_local_requests? ,
allow_local_network : allow_local_requests? ,
schemes : %w( http https )
2021-01-29 00:20:46 +05:30
)
end
2020-06-23 00:09:42 +05:30
private
2022-11-25 23:54:43 +05:30
def validate_context
if blocked_url?
log_and_return_error ( " Invalid URL: #{ url } " , _ ( " Invalid URL: %{url} " ) % { url : url } , :bad_request )
2023-03-17 16:20:25 +05:30
elsif target_namespace . nil?
error ( _ ( 'Namespace or group to import repository into does not exist.' ) , :unprocessable_entity )
2022-11-25 23:54:43 +05:30
elsif ! authorized?
2023-05-27 22:25:52 +05:30
error ( _ ( 'You are not allowed to import projects in this namespace.' ) , :unprocessable_entity )
2022-11-25 23:54:43 +05:30
elsif oversized?
error ( oversize_error_message , :unprocessable_entity )
end
end
2023-03-17 16:20:25 +05:30
def target_namespace_path
raise ArgumentError , 'Target namespace is required' if params [ :target_namespace ] . blank?
params [ :target_namespace ]
end
2020-06-23 00:09:42 +05:30
def log_error ( exception )
2021-10-27 15:23:28 +05:30
Gitlab :: GithubImport :: Logger . error (
2020-06-23 00:09:42 +05:30
message : 'Import failed due to a GitHub error' ,
status : exception . response_status ,
error : exception . response_body
)
2022-06-21 17:19:12 +05:30
error ( _ ( 'Import failed due to a GitHub error: %{original} (HTTP %{code})' ) % { original : exception . response_body , code : exception . response_status } , :unprocessable_entity )
2020-06-23 00:09:42 +05:30
end
2022-01-26 12:08:38 +05:30
def log_and_return_error ( message , translated_message , http_status )
Gitlab :: GithubImport :: Logger . error (
message : 'Error while attempting to import from GitHub' ,
error : message
)
error ( translated_message , http_status )
end
2022-11-25 23:54:43 +05:30
def store_import_settings ( project )
Gitlab :: GithubImport :: Settings . new ( project ) . write ( params [ :optional_stages ] )
end
2019-03-02 22:35:43 +05:30
end
end
2019-12-04 20:38:33 +05:30
2021-06-08 01:23:25 +05:30
Import :: GithubService . prepend_mod_with ( 'Import::GithubService' )