Module: API::Helpers::Packages::Conan::ApiHelpers

Defined in:
lib/api/helpers/packages/conan/api_helpers.rb

Instance Method Summary collapse

Instance Method Details

#create_package_file_with_type(file_type, current_package) ⇒ Object


150
151
152
153
154
155
# File 'lib/api/helpers/packages/conan/api_helpers.rb', line 150

def create_package_file_with_type(file_type, current_package)
  unless params[:file].size == 0 # rubocop: disable Style/ZeroLengthPredicate
    # conan sends two upload requests, the first has no file, so we skip record creation if file.size == 0
    ::Packages::Conan::CreatePackageFileService.new(current_package, params[:file], params.merge(conan_file_type: file_type)).execute
  end
end

#decode_oauth_token_from_jwtObject


228
229
230
231
232
233
234
235
236
237
238
# File 'lib/api/helpers/packages/conan/api_helpers.rb', line 228

def decode_oauth_token_from_jwt
  jwt = Doorkeeper::OAuth::Token.from_bearer_authorization(current_request)

  return unless jwt

  token = ::Gitlab::ConanToken.decode(jwt)

  return unless token && token.access_token_id && token.user_id

  token
end

#deploy_token_from_requestObject


187
188
189
# File 'lib/api/helpers/packages/conan/api_helpers.rb', line 187

def deploy_token_from_request
  find_deploy_token_from_conan_jwt || find_deploy_token_from_http_basic_auth
end

#download_package_file(file_type) ⇒ Object


116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
# File 'lib/api/helpers/packages/conan/api_helpers.rb', line 116

def download_package_file(file_type)
  authorize!(:read_package, project)

  package_file = ::Packages::Conan::PackageFileFinder
    .new(
      package,
      params[:file_name].to_s,
      conan_file_type: file_type,
      conan_package_reference: params[:conan_package_reference]
    ).execute!

  package_event('pull_package') if params[:file_name] == ::Packages::Conan::FileMetadatum::PACKAGE_BINARY

  present_carrierwave_file!(package_file.file)
end

#file_namesObject


142
143
144
145
146
147
148
# File 'lib/api/helpers/packages/conan/api_helpers.rb', line 142

def file_names
  json_payload = Gitlab::Json.parse(request.body.read)

  bad_request!(nil) unless json_payload.is_a?(Hash)

  json_payload.keys
end

#find_deploy_token_from_conan_jwtObject


208
209
210
211
212
213
214
215
216
217
218
# File 'lib/api/helpers/packages/conan/api_helpers.rb', line 208

def find_deploy_token_from_conan_jwt
  token = decode_oauth_token_from_jwt

  return unless token

  deploy_token = DeployToken.active.find_by_token(token.access_token_id.to_s)
  # note: uesr_id is not a user record id, but is the attribute set on ConanToken
  return if token.user_id != deploy_token&.username

  deploy_token
end

#find_job_from_conan_jwtObject


220
221
222
223
224
225
226
# File 'lib/api/helpers/packages/conan/api_helpers.rb', line 220

def find_job_from_conan_jwt
  token = decode_oauth_token_from_jwt

  return unless token

  ::Ci::AuthJobFinder.new(token: token.access_token_id.to_s).execute
end

#find_job_from_tokenObject


191
192
193
# File 'lib/api/helpers/packages/conan/api_helpers.rb', line 191

def find_job_from_token
  find_job_from_conan_jwt || find_job_from_http_basic_auth
end

#find_oauth_access_tokenObject

We need to override this one because it looks into Bearer authorization header


197
198
# File 'lib/api/helpers/packages/conan/api_helpers.rb', line 197

def find_oauth_access_token
end

#find_or_create_packageObject


132
133
134
# File 'lib/api/helpers/packages/conan/api_helpers.rb', line 132

def find_or_create_package
  package || ::Packages::Conan::CreatePackageService.new(project, current_user, params).execute
end

#find_personal_access_tokenObject


172
173
174
175
176
177
# File 'lib/api/helpers/packages/conan/api_helpers.rb', line 172

def find_personal_access_token
  personal_access_token = find_personal_access_token_from_conan_jwt ||
    find_personal_access_token_from_http_basic_auth

  personal_access_token
end

#find_personal_access_token_from_conan_jwtObject


200
201
202
203
204
205
206
# File 'lib/api/helpers/packages/conan/api_helpers.rb', line 200

def find_personal_access_token_from_conan_jwt
  token = decode_oauth_token_from_jwt

  return unless token

  PersonalAccessToken.find_by_id_and_user_id(token.access_token_id, token.user_id)
end

#find_user_from_job_tokenObject


179
180
181
182
183
184
185
# File 'lib/api/helpers/packages/conan/api_helpers.rb', line 179

def find_user_from_job_token
  return unless route_authentication_setting[:job_token_allowed]

  job = find_job_from_token || raise(::Gitlab::Auth::UnauthorizedError)

  job.user
end

#packageObject


94
95
96
97
98
99
100
101
102
103
104
# File 'lib/api/helpers/packages/conan/api_helpers.rb', line 94

def package
  strong_memoize(:package) do
    project.packages
      .conan
      .with_name(params[:package_name])
      .with_version(params[:package_version])
      .with_conan_channel(params[:package_channel])
      .order_created
      .last
  end
end

#package_file?(file_name) ⇒ Boolean

Returns:

  • (Boolean)

51
52
53
# File 'lib/api/helpers/packages/conan/api_helpers.rb', line 51

def package_file?(file_name)
  file_name.in?(::Packages::Conan::FileMetadatum::PACKAGE_FILES)
end

#package_file_upload_url(file_name) ⇒ Object


55
56
57
58
59
60
61
62
63
64
65
66
67
68
# File 'lib/api/helpers/packages/conan/api_helpers.rb', line 55

def package_file_upload_url(file_name)
  expose_url(
    api_v4_packages_conan_v1_files_package_path(
      package_name: params[:package_name],
      package_version: params[:package_version],
      package_username: params[:package_username],
      package_channel: params[:package_channel],
      recipe_revision: '0',
      conan_package_reference: params[:conan_package_reference],
      package_revision: '0',
      file_name: file_name
    )
  )
end

#package_upload_urlsObject


39
40
41
42
43
44
45
# File 'lib/api/helpers/packages/conan/api_helpers.rb', line 39

def package_upload_urls
  { upload_urls: Hash[
    file_names.select(&method(:package_file?)).map do |file_name|
      [file_name, package_file_upload_url(file_name)]
    end
  ] }
end

#present_download_urls(entity) ⇒ Object


8
9
10
11
12
13
14
15
16
17
18
19
20
21
# File 'lib/api/helpers/packages/conan/api_helpers.rb', line 8

def present_download_urls(entity)
  authorize!(:read_package, project)

  presenter = ::Packages::Conan::PackagePresenter.new(
    package,
    current_user,
    project,
    conan_package_reference: params[:conan_package_reference]
  )

  render_api_error!("No recipe manifest found", 404) if yield(presenter).empty?

  present presenter, with: entity
end

#present_package_download_urlsObject


23
24
25
# File 'lib/api/helpers/packages/conan/api_helpers.rb', line 23

def present_package_download_urls
  present_download_urls(::API::Entities::ConanPackage::ConanPackageManifest, &:package_urls)
end

#present_recipe_download_urlsObject


27
28
29
# File 'lib/api/helpers/packages/conan/api_helpers.rb', line 27

def present_recipe_download_urls
  present_download_urls(::API::Entities::ConanPackage::ConanRecipeManifest, &:recipe_urls)
end

#projectObject


87
88
89
90
91
92
# File 'lib/api/helpers/packages/conan/api_helpers.rb', line 87

def project
  strong_memoize(:project) do
    full_path = ::Packages::Conan::Metadatum.full_path_from(package_username: params[:package_username])
    Project.find_by_full_path(full_path)
  end
end

#recipeObject


83
84
85
# File 'lib/api/helpers/packages/conan/api_helpers.rb', line 83

def recipe
  "%{package_name}/%{package_version}@%{package_username}/%{package_channel}" % params.symbolize_keys
end

#recipe_file?(file_name) ⇒ Boolean

Returns:

  • (Boolean)

47
48
49
# File 'lib/api/helpers/packages/conan/api_helpers.rb', line 47

def recipe_file?(file_name)
  file_name.in?(::Packages::Conan::FileMetadatum::RECIPE_FILES)
end

#recipe_file_upload_url(file_name) ⇒ Object


70
71
72
73
74
75
76
77
78
79
80
81
# File 'lib/api/helpers/packages/conan/api_helpers.rb', line 70

def recipe_file_upload_url(file_name)
  expose_url(
    api_v4_packages_conan_v1_files_export_path(
      package_name: params[:package_name],
      package_version: params[:package_version],
      package_username: params[:package_username],
      package_channel: params[:package_channel],
      recipe_revision: '0',
      file_name: file_name
    )
  )
end

#recipe_upload_urlsObject


31
32
33
34
35
36
37
# File 'lib/api/helpers/packages/conan/api_helpers.rb', line 31

def recipe_upload_urls
  { upload_urls: Hash[
    file_names.select(&method(:recipe_file?)).map do |file_name|
      [file_name, recipe_file_upload_url(file_name)]
    end
  ] }
end

#tokenObject


106
107
108
109
110
111
112
113
114
# File 'lib/api/helpers/packages/conan/api_helpers.rb', line 106

def token
  strong_memoize(:token) do
    token = nil
    token = ::Gitlab::ConanToken.from_personal_access_token(access_token) if access_token
    token = ::Gitlab::ConanToken.from_deploy_token(deploy_token_from_request) if deploy_token_from_request
    token = ::Gitlab::ConanToken.from_job(find_job_from_token) if find_job_from_token
    token
  end
end

#track_push_package_eventObject


136
137
138
139
140
# File 'lib/api/helpers/packages/conan/api_helpers.rb', line 136

def track_push_package_event
  if params[:file_name] == ::Packages::Conan::FileMetadatum::PACKAGE_BINARY && params[:file].size > 0 # rubocop: disable Style/ZeroLengthPredicate
    package_event('push_package')
  end
end

#upload_package_file(file_type) ⇒ Object


157
158
159
160
161
162
163
164
165
166
167
168
169
170
# File 'lib/api/helpers/packages/conan/api_helpers.rb', line 157

def upload_package_file(file_type)
  authorize_upload!(project)
  bad_request!('File is too large') if project.actual_limits.exceeded?(:conan_max_file_size, params['file.size'].to_i)

  current_package = find_or_create_package

  track_push_package_event

  create_package_file_with_type(file_type, current_package)
rescue ObjectStorage::RemoteStoreError => e
  Gitlab::ErrorTracking.track_exception(e, file_name: params[:file_name], project_id: project.id)

  forbidden!
end