1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
|
# frozen_string_literal: true
module API
class ImportGithub < ::API::Base
before { authenticate! }
feature_category :importers
urgency :low
rescue_from Octokit::Unauthorized, with: :provider_unauthorized
rescue_from Gitlab::GithubImport::RateLimitError, with: :too_many_requests
helpers do
def client
@client ||= if Feature.enabled?(:remove_legacy_github_client)
Gitlab::GithubImport::Client.new(params[:personal_access_token], host: params[:github_hostname])
else
Gitlab::LegacyGithubImport::Client.new(params[:personal_access_token], **client_options)
end
end
def access_params
{
github_access_token: params[:personal_access_token],
additional_access_tokens: params[:additional_access_tokens]
}
end
def client_options
{ host: params[:github_hostname] }
end
def provider
:github
end
def provider_unauthorized
error!("Access denied to your #{Gitlab::ImportSources.title(provider.to_s)} account.", 401)
end
def too_many_requests
error!('Too Many Requests', 429)
end
end
desc 'Import a GitHub project' do
detail 'This feature was introduced in GitLab 11.3.4.'
success code: 201, model: ::ProjectEntity
failure [
{ code: 400, message: 'Bad request' },
{ code: 401, message: 'Unauthorized' },
{ code: 403, message: 'Forbidden' },
{ code: 422, message: 'Unprocessable entity' },
{ code: 503, message: 'Service unavailable' }
]
tags ['project_import_github']
end
params do
requires :personal_access_token, type: String, desc: 'GitHub personal access token'
requires :repo_id, type: Integer, desc: 'GitHub repository ID'
optional :new_name, type: String, desc: 'New repo name'
requires :target_namespace, type: String, allow_blank: false, desc: 'Namespace or group to import repository into'
optional :github_hostname, type: String, desc: 'Custom GitHub enterprise hostname'
optional :optional_stages, type: Hash, desc: 'Optional stages of import to be performed'
optional :additional_access_tokens,
type: Array[String],
coerce_with: ::API::Validations::Types::CommaSeparatedToArray.coerce,
desc: 'Additional list of personal access tokens',
documentation: { example: 'foo,bar' }
end
post 'import/github' do
result = Import::GithubService.new(client, current_user, params).execute(access_params, provider)
if result[:status] == :success
present ProjectSerializer.new.represent(result[:project])
else
status result[:http_status]
{ errors: result[:message] }
end
end
desc 'Cancel GitHub project import' do
detail 'This feature was introduced in GitLab 15.5'
success code: 200, model: ProjectImportEntity
failure [
{ code: 400, message: 'Bad request' },
{ code: 401, message: 'Unauthorized' },
{ code: 403, message: 'Forbidden' },
{ code: 404, message: 'Not found' },
{ code: 503, message: 'Service unavailable' }
]
tags ['project_import_github']
end
params do
requires :project_id, type: Integer, desc: 'ID of importing project to be canceled'
end
post 'import/github/cancel' do
project = Project.imported_from(provider.to_s).find(params[:project_id])
result = Import::Github::CancelProjectImportService.new(project, current_user).execute
if result[:status] == :success
status :ok
present ProjectSerializer.new.represent(project, serializer: :import)
else
render_api_error!(result[:message], result[:http_status])
end
end
desc 'Import User Gists' do
detail 'This feature was introduced in GitLab 15.8'
success code: 202
failure [
{ code: 401, message: 'Unauthorized' },
{ code: 422, message: 'Unprocessable Entity' },
{ code: 429, message: 'Too Many Requests' }
]
end
params do
requires :personal_access_token, type: String, desc: 'GitHub personal access token'
end
post 'import/github/gists' do
authorize! :create_snippet
result = Import::Github::GistsImportService.new(current_user, client, access_params).execute
if result[:status] == :success
status 202
else
status result[:http_status]
{ errors: result[:message] }
end
end
end
end
|