Module: API::Helpers

Includes:
Pagination, PaginationStrategies, Gitlab::Utils
Defined in:
lib/api/helpers.rb,
lib/api/helpers/runner.rb,
lib/api/helpers/version.rb,
lib/api/helpers/pagination.rb,
lib/api/helpers/presentable.rb,
lib/api/helpers/rate_limiter.rb,
lib/api/helpers/label_helpers.rb,
lib/api/helpers/notes_helpers.rb,
lib/api/helpers/users_helpers.rb,
lib/api/helpers/wikis_helpers.rb,
lib/api/helpers/badges_helpers.rb,
lib/api/helpers/common_helpers.rb,
lib/api/helpers/events_helpers.rb,
lib/api/helpers/groups_helpers.rb,
lib/api/helpers/issues_helpers.rb,
lib/api/helpers/search_helpers.rb,
lib/api/helpers/graphql_helpers.rb,
lib/api/helpers/headers_helpers.rb,
lib/api/helpers/members_helpers.rb,
lib/api/helpers/internal_helpers.rb,
lib/api/helpers/packages_helpers.rb,
lib/api/helpers/projects_helpers.rb,
lib/api/helpers/services_helpers.rb,
lib/api/helpers/settings_helpers.rb,
lib/api/helpers/snippets_helpers.rb,
lib/api/helpers/custom_attributes.rb,
lib/api/helpers/discussions_helpers.rb,
lib/api/helpers/file_upload_helpers.rb,
lib/api/helpers/pagination_strategies.rb,
lib/api/helpers/merge_requests_helpers.rb,
lib/api/helpers/performance_bar_helpers.rb,
lib/api/helpers/project_snapshots_helpers.rb,
lib/api/helpers/related_resources_helpers.rb,
lib/api/helpers/packages/conan/api_helpers.rb,
lib/api/helpers/protected_branches_helpers.rb,
lib/api/helpers/packages/basic_auth_helpers.rb,
lib/api/helpers/resource_label_events_helpers.rb,
lib/api/helpers/packages_manager_clients_helpers.rb,
lib/api/helpers/packages/dependency_proxy_helpers.rb

Defined Under Namespace

Modules: BadgesHelpers, CommonHelpers, CustomAttributes, DiscussionsHelpers, EventsHelpers, FileUploadHelpers, GraphqlHelpers, GroupsHelpers, HeadersHelpers, InternalHelpers, IssuesHelpers, LabelHelpers, MembersHelpers, MergeRequestsHelpers, NotesHelpers, Packages, PackagesHelpers, PackagesManagerClientsHelpers, Pagination, PaginationStrategies, PerformanceBarHelpers, Presentable, ProjectSnapshotsHelpers, ProjectsHelpers, ProtectedBranchesHelpers, RateLimiter, RelatedResourcesHelpers, ResourceLabelEventsHelpers, Runner, SearchHelpers, ServicesHelpers, SettingsHelpers, SnippetsHelpers, UsersHelpers, WikisHelpers Classes: Version

Constant Summary collapse

SUDO_HEADER =
"HTTP_SUDO"
GITLAB_SHARED_SECRET_HEADER =
"Gitlab-Shared-Secret"
SUDO_PARAM =
:sudo
API_USER_ENV =
'gitlab.api.user'
API_EXCEPTION_ENV =
'gitlab.api.exception'
API_RESPONSE_STATUS_CODE =
'gitlab.api.response_status_code'

Instance Method Summary collapse

Methods included from PaginationStrategies

#paginate_with_strategies, #paginator

Methods included from Pagination

#paginate

Methods included from Gitlab::Utils

#allowlisted?, #append_path, #boolean_to_yes_no, #bytes_to_megabytes, #check_allowed_absolute_path!, #check_path_traversal!, #decode_path, #deep_indifferent_access, #ensure_array_from_string, #ensure_utf8_size, #force_utf8, #ms_to_round_sec, #multiple_key_invert, #nlbr, #parse_url, #random_string, #remove_line_breaks, #slugify, #stable_sort_by, #string_to_ip_object, #to_boolean, #to_exclusive_sentence, #try_megabytes_to_bytes, #which

Instance Method Details

#accepted!Object


427
428
429
# File 'lib/api/helpers.rb', line 427

def accepted!
  render_api_error!('202 Accepted', 202)
end

#attributes_for_keys(keys, custom_params = nil) ⇒ Object


326
327
328
329
330
331
332
333
334
335
336
# File 'lib/api/helpers.rb', line 326

def attributes_for_keys(keys, custom_params = nil)
  params_hash = custom_params || params
  attrs = {}
  keys.each do |key|
    if params_hash[key].present? || (params_hash.key?(key) && params_hash[key] == false)
      attrs[key] = params_hash[key]
    end
  end
  permitted_attrs = ActionController::Parameters.new(attrs).permit!
  permitted_attrs.to_h
end

#authenticate!Object


224
225
226
# File 'lib/api/helpers.rb', line 224

def authenticate!
  unauthorized! unless current_user
end

#authenticate_by_gitlab_shell_token!Object


232
233
234
235
236
237
238
239
# File 'lib/api/helpers.rb', line 232

def authenticate_by_gitlab_shell_token!
  input = params['secret_token']
  input ||= Base64.decode64(headers[GITLAB_SHARED_SECRET_HEADER]) if headers.key?(GITLAB_SHARED_SECRET_HEADER)

  input&.chomp!

  unauthorized! unless Devise.secure_compare(secret_token, input)
end

#authenticate_non_get!Object


228
229
230
# File 'lib/api/helpers.rb', line 228

def authenticate_non_get!
  authenticate! unless %w[GET HEAD].include?(route.request_method)
end

#authenticated_as_admin!Object


246
247
248
249
# File 'lib/api/helpers.rb', line 246

def authenticated_as_admin!
  authenticate!
  forbidden! unless current_user.admin?
end

#authenticated_with_can_read_all_resources!Object


241
242
243
244
# File 'lib/api/helpers.rb', line 241

def authenticated_with_can_read_all_resources!
  authenticate!
  forbidden! unless current_user.can_read_all_resources?
end

#authorize!(action, subject = :global, reason = nil) ⇒ Object


251
252
253
# File 'lib/api/helpers.rb', line 251

def authorize!(action, subject = :global, reason = nil)
  forbidden!(reason) unless can?(current_user, action, subject)
end

#authorize_admin_groupObject


267
268
269
# File 'lib/api/helpers.rb', line 267

def authorize_admin_group
  authorize! :admin_group, user_group
end

#authorize_admin_projectObject


263
264
265
# File 'lib/api/helpers.rb', line 263

def authorize_admin_project
  authorize! :admin_project, user_project
end

#authorize_admin_tagObject


259
260
261
# File 'lib/api/helpers.rb', line 259

def authorize_admin_tag
  authorize! :admin_tag, user_project
end

#authorize_destroy_artifacts!Object


275
276
277
# File 'lib/api/helpers.rb', line 275

def authorize_destroy_artifacts!
  authorize! :destroy_artifacts, user_project
end

#authorize_push_projectObject


255
256
257
# File 'lib/api/helpers.rb', line 255

def authorize_push_project
  authorize! :push_code, user_project
end

#authorize_read_builds!Object


271
272
273
# File 'lib/api/helpers.rb', line 271

def authorize_read_builds!
  authorize! :read_build, user_project
end

#authorize_update_builds!Object


279
280
281
# File 'lib/api/helpers.rb', line 279

def authorize_update_builds!
  authorize! :update_build, user_project
end

#available_labels_for(label_parent, include_ancestor_groups: true) ⇒ Object


92
93
94
95
96
97
98
99
100
101
102
# File 'lib/api/helpers.rb', line 92

def available_labels_for(label_parent, include_ancestor_groups: true)
  search_params = { include_ancestor_groups: include_ancestor_groups }

  if label_parent.is_a?(Project)
    search_params[:project_id] = label_parent.id
  else
    search_params.merge!(group_id: label_parent.id, only_group_labels: true)
  end

  LabelsFinder.new(current_user, search_params).execute
end

#bad_request!(attribute) ⇒ Object


368
369
370
371
372
# File 'lib/api/helpers.rb', line 368

def bad_request!(attribute)
  message = ["400 (Bad request)"]
  message << "\"" + attribute.to_s + "\" not given" if attribute
  render_api_error!(message.join(' '), 400)
end

#can?(object, action, subject = :global) ⇒ Boolean

Returns:

  • (Boolean)

311
312
313
# File 'lib/api/helpers.rb', line 311

def can?(object, action, subject = :global)
  Ability.allowed?(object, action, subject)
end

#check_namespace_access(namespace) ⇒ Object


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

def check_namespace_access(namespace)
  return namespace if can?(current_user, :read_namespace, namespace)

  not_found!('Namespace')
end

#check_sha_param!(params, merge_request) ⇒ Object


381
382
383
384
385
# File 'lib/api/helpers.rb', line 381

def check_sha_param!(params, merge_request)
  if params[:sha] && merge_request.diff_head_sha != params[:sha]
    render_api_error!("SHA does not match HEAD of source branch: #{merge_request.diff_head_sha}", 409)
  end
end

#check_unmodified_since!(last_modified) ⇒ Object


21
22
23
24
25
26
27
# File 'lib/api/helpers.rb', line 21

def check_unmodified_since!(last_modified)
  if_unmodified_since = Time.parse(headers['If-Unmodified-Since']) rescue nil

  if if_unmodified_since && last_modified && last_modified > if_unmodified_since
    render_api_error!('412 Precondition Failed', 412)
  end
end

#conflict!(message = nil) ⇒ Object


403
404
405
# File 'lib/api/helpers.rb', line 403

def conflict!(message = nil)
  render_api_error!(message || '409 Conflict', 409)
end

#created!Object


423
424
425
# File 'lib/api/helpers.rb', line 423

def created!
  render_api_error!('201 Created', 201)
end

#current_authenticated_jobObject

Returns the job associated with the token provided for authentication, if any


50
51
52
# File 'lib/api/helpers.rb', line 50

def current_authenticated_job
  @current_authenticated_job
end

#current_userObject

rubocop:disable Gitlab/ModuleWithInstanceVariables We can't rewrite this with StrongMemoize because `sudo!` would actually write to `@current_user`, and `sudo?` would immediately call `current_user` again which reads from `@current_user`. We should rewrite this in a way that using StrongMemoize is possible


59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
# File 'lib/api/helpers.rb', line 59

def current_user
  return @current_user if defined?(@current_user)

  @current_user = initial_current_user

  Gitlab::I18n.locale = @current_user&.preferred_language

  sudo!

  validate_access_token!(scopes: scopes_registered_for_endpoint) unless sudo?

  save_current_user_in_env(@current_user) if @current_user

  @current_user
end

#declared_params(options = {}) ⇒ Object


16
17
18
19
# File 'lib/api/helpers.rb', line 16

def declared_params(options = {})
  options = { include_parent_namespaces: false }.merge(options)
  declared(params, options).to_h.symbolize_keys
end

#destroy_conditionally!(resource, last_updated: nil) ⇒ Object


29
30
31
32
33
34
35
36
37
38
39
40
41
42
# File 'lib/api/helpers.rb', line 29

def destroy_conditionally!(resource, last_updated: nil)
  last_updated ||= resource.updated_at

  check_unmodified_since!(last_updated)

  status 204
  body false

  if block_given?
    yield resource
  else
    resource.destroy
  end
end

#file_too_large!Object


411
412
413
# File 'lib/api/helpers.rb', line 411

def file_too_large!
  render_api_error!('413 Request Entity Too Large', 413)
end

#filter_by_iid(items, iid) ⇒ Object

rubocop: disable CodeReuse/ActiveRecord


339
340
341
# File 'lib/api/helpers.rb', line 339

def filter_by_iid(items, iid)
  items.where(iid: iid)
end

#filter_by_search(items, text) ⇒ Object

rubocop: enable CodeReuse/ActiveRecord


350
351
352
# File 'lib/api/helpers.rb', line 350

def filter_by_search(items, text)
  items.search(text)
end

#filter_by_title(items, title) ⇒ Object

rubocop: disable CodeReuse/ActiveRecord


345
346
347
# File 'lib/api/helpers.rb', line 345

def filter_by_title(items, title)
  items.where(title: title)
end

#find_branch!(branch_name) ⇒ Object


178
179
180
181
182
183
184
# File 'lib/api/helpers.rb', line 178

def find_branch!(branch_name)
  if Gitlab::GitRefValidator.validate(branch_name)
    user_project.repository.find_branch(branch_name) || not_found!('Branch')
  else
    render_api_error!('The branch refname is invalid', 400)
  end
end

#find_build!(id) ⇒ Object

rubocop: enable CodeReuse/ActiveRecord


220
221
222
# File 'lib/api/helpers.rb', line 220

def find_build!(id)
  user_project.builds.find(id.to_i)
end

#find_group(id) ⇒ Object

rubocop: disable CodeReuse/ActiveRecord


131
132
133
134
135
136
137
# File 'lib/api/helpers.rb', line 131

def find_group(id)
  if id.to_s =~ /^\d+$/
    Group.find_by(id: id)
  else
    Group.find_by_full_path(id)
  end
end

#find_group!(id) ⇒ Object

rubocop: enable CodeReuse/ActiveRecord


140
141
142
143
144
145
146
147
148
# File 'lib/api/helpers.rb', line 140

def find_group!(id)
  group = find_group(id)

  if can?(current_user, :read_group, group)
    group
  else
    not_found!('Group')
  end
end

#find_merge_request_with_access(iid, access_level = :read_merge_request) ⇒ Object

rubocop: disable CodeReuse/ActiveRecord


213
214
215
216
217
# File 'lib/api/helpers.rb', line 213

def find_merge_request_with_access(iid, access_level = :read_merge_request)
  merge_request = user_project.merge_requests.find_by!(iid: iid)
  authorize! access_level, merge_request
  merge_request
end

#find_namespace(id) ⇒ Object

rubocop: disable CodeReuse/ActiveRecord


157
158
159
160
161
162
163
# File 'lib/api/helpers.rb', line 157

def find_namespace(id)
  if id.to_s =~ /^\d+$/
    Namespace.find_by(id: id)
  else
    Namespace.find_by_full_path(id)
  end
end

#find_namespace!(id) ⇒ Object

rubocop: enable CodeReuse/ActiveRecord


166
167
168
# File 'lib/api/helpers.rb', line 166

def find_namespace!(id)
  check_namespace_access(find_namespace(id))
end

#find_namespace_by_path(path) ⇒ Object


170
171
172
# File 'lib/api/helpers.rb', line 170

def find_namespace_by_path(path)
  Namespace.find_by_full_path(path)
end

#find_namespace_by_path!(path) ⇒ Object


174
175
176
# File 'lib/api/helpers.rb', line 174

def find_namespace_by_path!(path)
  check_namespace_access(find_namespace_by_path(path))
end

#find_project(id) ⇒ Object

rubocop: disable CodeReuse/ActiveRecord


109
110
111
112
113
114
115
116
117
# File 'lib/api/helpers.rb', line 109

def find_project(id)
  projects = Project.without_deleted

  if id.is_a?(Integer) || id =~ /^\d+$/
    projects.find_by(id: id)
  elsif id.include?("/")
    projects.find_by_full_path(id)
  end
end

#find_project!(id) ⇒ Object

rubocop: enable CodeReuse/ActiveRecord


120
121
122
123
124
125
126
127
128
# File 'lib/api/helpers.rb', line 120

def find_project!(id)
  project = find_project(id)

  if can?(current_user, :read_project, project)
    project
  else
    not_found!('Project')
  end
end

#find_project_commit(id) ⇒ Object

rubocop: enable CodeReuse/ActiveRecord


208
209
210
# File 'lib/api/helpers.rb', line 208

def find_project_commit(id)
  user_project.commit_by(oid: id)
end

#find_project_issue(iid, project_id = nil) ⇒ Object

rubocop: disable CodeReuse/ActiveRecord


195
196
197
198
199
# File 'lib/api/helpers.rb', line 195

def find_project_issue(iid, project_id = nil)
  project = project_id ? find_project!(project_id) : user_project

  ::IssuesFinder.new(current_user, project_id: project.id).find_by!(iid: iid)
end

#find_project_merge_request(iid) ⇒ Object

rubocop: disable CodeReuse/ActiveRecord


203
204
205
# File 'lib/api/helpers.rb', line 203

def find_project_merge_request(iid)
  MergeRequestsFinder.new(current_user, project_id: user_project.id).find_by!(iid: iid)
end

#find_tag!(tag_name) ⇒ Object


186
187
188
189
190
191
192
# File 'lib/api/helpers.rb', line 186

def find_tag!(tag_name)
  if Gitlab::GitRefValidator.validate(tag_name)
    user_project.repository.find_tag(tag_name) || not_found!('Tag')
  else
    render_api_error!('The tag refname is invalid', 400)
  end
end

#find_user(id) ⇒ Object


104
105
106
# File 'lib/api/helpers.rb', line 104

def find_user(id)
  UserFinder.new(id).find_by_id_or_username
end

#forbidden!(reason = nil) ⇒ Object

error helpers


362
363
364
365
366
# File 'lib/api/helpers.rb', line 362

def forbidden!(reason = nil)
  message = ['403 Forbidden']
  message << " - #{reason}" if reason
  render_api_error!(message.join(' '), 403)
end

#handle_api_exception(exception) ⇒ Object


454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
# File 'lib/api/helpers.rb', line 454

def handle_api_exception(exception)
  if report_exception?(exception)
    define_params_for_grape_middleware
    Gitlab::ErrorTracking.with_context(current_user) do
      Gitlab::ErrorTracking.track_exception(exception)
    end
  end

  # This is used with GrapeLogging::Loggers::ExceptionLogger
  env[API_EXCEPTION_ENV] = exception

  # lifted from https://github.com/rails/rails/blob/master/actionpack/lib/action_dispatch/middleware/debug_exceptions.rb#L60
  trace = exception.backtrace

  message = ["\n#{exception.class} (#{exception.message}):\n"]
  message << exception.annoted_source_code.to_s if exception.respond_to?(:annoted_source_code)
  message << "  " << trace.join("\n  ")
  message = message.join

  API.logger.add Logger::FATAL, message

  response_message =
    if Rails.env.test?
      message
    else
      '500 Internal Server Error'
    end

  rack_response({ 'message' => response_message }.to_json, 500)
end

#increment_unique_values(event_name, values) ⇒ Object

Parameters:

  • event_name (String)

    the event name

  • values (Array|String)

    the values counted


542
543
544
545
546
547
548
549
550
551
552
# File 'lib/api/helpers.rb', line 542

def increment_unique_values(event_name, values)
  return unless values.present?

  feature_name = "usage_data_#{event_name}"
  return unless Feature.enabled?(feature_name)
  return unless Gitlab::CurrentSettings.usage_ping_enabled?

  Gitlab::UsageDataCounters::HLLRedisCounter.track_event(values, event_name)
rescue => error
  Gitlab::AppLogger.warn("Redis tracking event failed for event: #{event_name}, message: #{error.message}")
end

#job_token_authentication?Boolean

Returns:

  • (Boolean)

44
45
46
# File 'lib/api/helpers.rb', line 44

def job_token_authentication?
  initial_current_user && @current_authenticated_job.present? # rubocop:disable Gitlab/ModuleWithInstanceVariables
end

#model_error_messages(model) ⇒ Object


437
438
439
# File 'lib/api/helpers.rb', line 437

def model_error_messages(model)
  model.errors.messages
end

#no_content!Object


419
420
421
# File 'lib/api/helpers.rb', line 419

def no_content!
  render_api_error!('204 No Content', 204)
end

#not_acceptable!Object


395
396
397
# File 'lib/api/helpers.rb', line 395

def not_acceptable!
  render_api_error!('406 Not Acceptable', 406)
end

#not_allowed!Object


391
392
393
# File 'lib/api/helpers.rb', line 391

def not_allowed!
  render_api_error!('405 Method Not Allowed', 405)
end

#not_found!(resource = nil) ⇒ Object


374
375
376
377
378
379
# File 'lib/api/helpers.rb', line 374

def not_found!(resource = nil)
  message = ["404"]
  message << resource if resource
  message << "Not Found"
  render_api_error!(message.join(' '), 404)
end

#not_modified!Object


415
416
417
# File 'lib/api/helpers.rb', line 415

def not_modified!
  render_api_error!('304 Not Modified', 304)
end

#order_options_with_tie_breakerObject


354
355
356
357
358
# File 'lib/api/helpers.rb', line 354

def order_options_with_tie_breaker
  order_options = { params[:order_by] => params[:sort] }
  order_options['id'] ||= params[:sort] || 'asc'
  order_options
end

#present_carrierwave_file!(file, supports_direct_download: true) ⇒ Object


515
516
517
518
519
520
521
522
523
524
525
526
527
# File 'lib/api/helpers.rb', line 515

def present_carrierwave_file!(file, supports_direct_download: true)
  return not_found! unless file&.exists?

  if file.file_storage?
    present_disk_file!(file.path, file.filename)
  elsif supports_direct_download && file.class.direct_download_enabled?
    redirect(file.url)
  else
    header(*Gitlab::Workhorse.send_url(file.url))
    status :ok
    body
  end
end

#present_disk_file!(path, filename, content_type = 'application/octet-stream') ⇒ Object

file helpers


499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
# File 'lib/api/helpers.rb', line 499

def present_disk_file!(path, filename, content_type = 'application/octet-stream')
  filename ||= File.basename(path)
  header['Content-Disposition'] = ActionDispatch::Http::ContentDisposition.format(disposition: 'attachment', filename: filename)
  header['Content-Transfer-Encoding'] = 'binary'
  content_type content_type

  # Support download acceleration
  case headers['X-Sendfile-Type']
  when 'X-Sendfile'
    header['X-Sendfile'] = path
    body
  else
    sendfile path
  end
end

#process_create_params(args) ⇒ Object


74
75
76
77
78
79
80
81
82
83
# File 'lib/api/helpers/snippets_helpers.rb', line 74

def process_create_params(args)
  with_api_params do |api_params|
    args[:snippet_actions] = args.delete(:files)&.map do |file|
      file[:action] = :create
      file.symbolize_keys
    end

    args.merge(api_params)
  end
end

#process_update_params(args) ⇒ Object


85
86
87
88
89
90
91
# File 'lib/api/helpers/snippets_helpers.rb', line 85

def process_update_params(args)
  with_api_params do |api_params|
    args[:snippet_actions] = args.delete(:files)&.map(&:symbolize_keys)

    args.merge(api_params)
  end
end

#project_finder_paramsObject

rubocop: enable CodeReuse/ActiveRecord


493
494
495
# File 'lib/api/helpers.rb', line 493

def project_finder_params
  project_finder_params_ce.merge(project_finder_params_ee)
end

#render_api_error!(message, status) ⇒ Object


445
446
447
448
449
450
451
452
# File 'lib/api/helpers.rb', line 445

def render_api_error!(message, status)
  # grape-logging doesn't pass the status code, so this is a
  # workaround for getting that information in the loggers:
  # https://github.com/aserafin/grape_logging/issues/71
  env[API_RESPONSE_STATUS_CODE] = Rack::Utils.status_code(status)

  error!({ 'message' => message }, status, header)
end

#render_spam_error!Object


441
442
443
# File 'lib/api/helpers.rb', line 441

def render_spam_error!
  render_api_error!({ error: 'Spam detected' }, 400)
end

#render_validation_error!(model) ⇒ Object


431
432
433
434
435
# File 'lib/api/helpers.rb', line 431

def render_validation_error!(model)
  if model.errors.any?
    render_api_error!(model_error_messages(model) || '400 Bad Request', 400)
  end
end

#reorder_projects(projects) ⇒ Object

rubocop: disable CodeReuse/ActiveRecord


488
489
490
# File 'lib/api/helpers.rb', line 488

def reorder_projects(projects)
  projects.reorder(order_options_with_tie_breaker)
end

#require_gitlab_workhorse!Object


287
288
289
290
291
292
293
# File 'lib/api/helpers.rb', line 287

def require_gitlab_workhorse!
  verify_workhorse_api!

  unless env['HTTP_GITLAB_WORKHORSE'].present?
    forbidden!('Request should be executed via GitLab Workhorse')
  end
end

#require_pages_config_enabled!Object


307
308
309
# File 'lib/api/helpers.rb', line 307

def require_pages_config_enabled!
  not_found! unless Gitlab.config.pages.enabled
end

#require_pages_enabled!Object


303
304
305
# File 'lib/api/helpers.rb', line 303

def require_pages_enabled!
  not_found! unless user_project.pages_available?
end

#require_repository_enabled!(subject = :global) ⇒ Object


283
284
285
# File 'lib/api/helpers.rb', line 283

def require_repository_enabled!(subject = :global)
  not_found!("Repository") unless user_project.feature_available?(:repository, current_user)
end

#required_attributes!(keys) ⇒ Object

Checks the occurrences of required attributes, each attribute must be present in the params hash or a Bad Request error is invoked.

Parameters:

keys (required) - A hash consisting of keys that must be present

320
321
322
323
324
# File 'lib/api/helpers.rb', line 320

def required_attributes!(keys)
  keys.each do |key|
    bad_request!(key) unless params[key].present?
  end
end

#save_current_user_in_env(user) ⇒ Object

rubocop:enable Gitlab/ModuleWithInstanceVariables


76
77
78
# File 'lib/api/helpers.rb', line 76

def save_current_user_in_env(user)
  env[API_USER_ENV] = { user_id: user.id, username: user.username }
end

#service_unavailable!Object


399
400
401
# File 'lib/api/helpers.rb', line 399

def service_unavailable!
  render_api_error!('503 Service Unavailable', 503)
end

#sudo?Boolean

Returns:

  • (Boolean)

80
81
82
# File 'lib/api/helpers.rb', line 80

def sudo?
  initial_current_user != current_user
end

#track_event(action = action_name, **args) ⇒ Object


529
530
531
532
533
534
535
536
537
538
# File 'lib/api/helpers.rb', line 529

def track_event(action = action_name, **args)
  category = args.delete(:category) || self.options[:for].name
  raise "invalid category" unless category

  ::Gitlab::Tracking.event(category, action.to_s, **args)
rescue => error
  Gitlab::AppLogger.warn(
    "Tracking event failed for action: #{action}, category: #{category}, message: #{error.message}"
  )
end

#unauthorized!Object


387
388
389
# File 'lib/api/helpers.rb', line 387

def unauthorized!
  render_api_error!('401 Unauthorized', 401)
end

#unprocessable_entity!(message = nil) ⇒ Object


407
408
409
# File 'lib/api/helpers.rb', line 407

def unprocessable_entity!(message = nil)
  render_api_error!(message || '422 Unprocessable Entity', :unprocessable_entity)
end

#user_groupObject


84
85
86
# File 'lib/api/helpers.rb', line 84

def user_group
  @group ||= find_group!(params[:id])
end

#user_projectObject


88
89
90
# File 'lib/api/helpers.rb', line 88

def user_project
  @project ||= find_project!(params[:id])
end

#validate_params_for_multiple_files(snippet) ⇒ Object


93
94
95
96
97
98
99
# File 'lib/api/helpers/snippets_helpers.rb', line 93

def validate_params_for_multiple_files(snippet)
  return unless params[:content] || params[:file_name]

  if Feature.enabled?(:snippet_multiple_files, current_user) && snippet.multiple_files?
    render_api_error!({ error: _('To update Snippets with multiple files, you must use the `files` parameter') }, 400)
  end
end

#verify_workhorse_api!Object


295
296
297
298
299
300
301
# File 'lib/api/helpers.rb', line 295

def verify_workhorse_api!
  Gitlab::Workhorse.verify_api_request!(request.headers)
rescue => e
  Gitlab::ErrorTracking.track_exception(e)

  forbidden!
end

#with_api_params {|{ api: true, request: request }| ... } ⇒ Object

Yields:

  • ({ api: true, request: request })

554
555
556
# File 'lib/api/helpers.rb', line 554

def with_api_params(&block)
  yield({ api: true, request: request })
end