2019-01-17 10:37:08 +00:00
# frozen_string_literal: true
module Import
class GithubService < Import :: BaseService
2021-02-23 06:11:16 +00:00
include ActiveSupport :: NumberHelper
include Gitlab :: Utils :: StrongMemoize
2019-01-17 10:37:08 +00:00
attr_accessor :client
attr_reader :params , :current_user
def execute ( access_params , provider )
2020-10-28 03:08:41 +00:00
if blocked_url?
2021-12-09 06:11:13 +00:00
return log_and_return_error ( " Invalid URL: #{ url } " , _ ( " Invalid URL: %{url} " ) % { url : url } , :bad_request )
2020-10-28 03:08:41 +00:00
end
2019-01-17 10:37:08 +00:00
unless authorized?
2019-04-15 12:25:48 +00:00
return error ( _ ( 'This namespace has already been taken! Please choose another one.' ) , :unprocessable_entity )
2019-01-17 10:37:08 +00:00
end
2021-02-23 06:11:16 +00:00
if oversized?
return error ( oversize_error_message , :unprocessable_entity )
end
2020-05-29 03:08:11 +00:00
project = create_project ( access_params , provider )
2019-01-17 10:37:08 +00:00
if project . persisted?
success ( project )
else
error ( project_save_error ( project ) , :unprocessable_entity )
end
2020-05-29 03:08:11 +00:00
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 ,
2020-12-01 12:09:17 +00:00
type : provider ,
2021-02-23 06:11:16 +00:00
** access_params
) . execute ( extra_project_attrs )
2019-01-17 10:37:08 +00:00
end
def repo
2020-08-11 12:09:55 +00:00
@repo || = client . repository ( params [ :repo_id ] . to_i )
2019-01-17 10:37:08 +00:00
end
def project_name
@project_name || = params [ :new_name ] . presence || repo . name
end
def namespace_path
@namespace_path || = params [ :target_namespace ] . presence || current_user . namespace_path
end
def target_namespace
@target_namespace || = find_or_create_namespace ( namespace_path , current_user . namespace_path )
end
def extra_project_attrs
{ }
end
2021-02-23 06:11:16 +00:00
def oversized?
repository_size_limit > 0 && repo . size > repository_size_limit
end
def oversize_error_message
_ ( '"%{repository_name}" size (%{repository_size}) is larger than the limit of %{limit}.' ) % {
repository_name : repo . name ,
repository_size : number_to_human_size ( repo . size ) ,
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
2019-01-17 10:37:08 +00:00
def authorized?
can? ( current_user , :create_projects , target_namespace )
end
2020-05-29 03:08:11 +00:00
2020-10-28 03:08:41 +00:00
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 ,
2020-12-10 00:09:50 +00:00
allow_localhost : allow_local_requests? ,
allow_local_network : allow_local_requests? ,
schemes : %w( http https )
2020-10-28 03:08:41 +00:00
)
end
2020-05-29 03:08:11 +00:00
private
def log_error ( exception )
2021-08-04 18:09:57 +00:00
Gitlab :: GithubImport :: Logger . error (
2020-05-29 03:08:11 +00:00
message : 'Import failed due to a GitHub error' ,
status : exception . response_status ,
error : exception . response_body
)
2022-03-29 21:08:04 +00:00
error ( _ ( 'Import failed due to a GitHub error: %{original} (HTTP %{code})' ) % { original : exception . response_body , code : exception . response_status } , :unprocessable_entity )
2020-05-29 03:08:11 +00:00
end
2021-12-09 06:11:13 +00:00
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
2019-01-17 10:37:08 +00:00
end
end
2019-09-13 13:26:31 +00:00
2021-05-11 21:10:21 +00:00
Import :: GithubService . prepend_mod_with ( 'Import::GithubService' )