diff options
Diffstat (limited to 'lib/api')
32 files changed, 177 insertions, 61 deletions
diff --git a/lib/api/api.rb b/lib/api/api.rb index dcecaeae558..5984879413f 100644 --- a/lib/api/api.rb +++ b/lib/api/api.rb @@ -299,6 +299,7 @@ module API mount ::API::Internal::Lfs mount ::API::Internal::Pages mount ::API::Internal::Kubernetes + mount ::API::Internal::MailRoom version 'v3', using: :path do # Although the following endpoints are kept behind V3 namespace, diff --git a/lib/api/ci/helpers/runner.rb b/lib/api/ci/helpers/runner.rb index 72c388160b4..43ed35b99fd 100644 --- a/lib/api/ci/helpers/runner.rb +++ b/lib/api/ci/helpers/runner.rb @@ -11,14 +11,6 @@ module API JOB_TOKEN_HEADER = 'HTTP_JOB_TOKEN' JOB_TOKEN_PARAM = :token - def runner_registration_token_valid? - ActiveSupport::SecurityUtils.secure_compare(params[:token], Gitlab::CurrentSettings.runners_registration_token) - end - - def runner_registrar_valid?(type) - Feature.disabled?(:runner_registration_control) || Gitlab::CurrentSettings.valid_runner_registrars.include?(type) - end - def authenticate_runner! forbidden! unless current_runner diff --git a/lib/api/ci/job_artifacts.rb b/lib/api/ci/job_artifacts.rb index 6431436b50d..ca76d2664f8 100644 --- a/lib/api/ci/job_artifacts.rb +++ b/lib/api/ci/job_artifacts.rb @@ -137,6 +137,17 @@ module API status :no_content end + + desc 'Expire the artifacts files from a project' + delete ':id/artifacts' do + not_found! unless Feature.enabled?(:bulk_expire_project_artifacts, default_enabled: :yaml) + + authorize_destroy_artifacts! + + ::Ci::JobArtifacts::DeleteProjectArtifactsService.new(project: user_project).execute + + accepted! + end end end end diff --git a/lib/api/ci/runner.rb b/lib/api/ci/runner.rb index 4317789f7aa..fef6a7891c2 100644 --- a/lib/api/ci/runner.rb +++ b/lib/api/ci/runner.rb @@ -15,6 +15,7 @@ module API params do requires :token, type: String, desc: 'Registration token' optional :description, type: String, desc: %q(Runner's description) + optional :maintainer_note, type: String, desc: %q(Runner's maintainer notes) optional :info, type: Hash, desc: %q(Runner's metadata) optional :active, type: Boolean, desc: 'Should Runner be active' optional :locked, type: Boolean, desc: 'Should Runner be locked for current project' @@ -25,24 +26,11 @@ module API optional :maximum_timeout, type: Integer, desc: 'Maximum timeout set when this Runner will handle the job' end post '/', feature_category: :runner do - attributes = attributes_for_keys([:description, :active, :locked, :run_untagged, :tag_list, :access_level, :maximum_timeout]) + attributes = attributes_for_keys(%i[description maintainer_note active locked run_untagged tag_list access_level maximum_timeout]) .merge(get_runner_details_from_request) - attributes = - if runner_registration_token_valid? - # Create shared runner. Requires admin access - attributes.merge(runner_type: :instance_type) - elsif runner_registrar_valid?('project') && @project = Project.find_by_runners_token(params[:token]) - # Create a specific runner for the project - attributes.merge(runner_type: :project_type, projects: [@project]) - elsif runner_registrar_valid?('group') && @group = Group.find_by_runners_token(params[:token]) - # Create a specific runner for the group - attributes.merge(runner_type: :group_type, groups: [@group]) - else - forbidden! - end - - @runner = ::Ci::Runner.create(attributes) + @runner = ::Ci::RegisterRunnerService.new.execute(params[:token], attributes) + forbidden! unless @runner if @runner.persisted? present @runner, with: Entities::Ci::RunnerRegistrationDetails diff --git a/lib/api/ci/runners.rb b/lib/api/ci/runners.rb index ef712c84804..f21782a698f 100644 --- a/lib/api/ci/runners.rb +++ b/lib/api/ci/runners.rb @@ -229,7 +229,12 @@ module API use :pagination end get ':id/runners' do - runners = ::Ci::Runner.belonging_to_group(user_group.id, include_ancestors: true) + runners = if ::Feature.enabled?(:ci_find_runners_by_ci_mirrors, user_group, default_enabled: :yaml) + ::Ci::Runner.belonging_to_group_and_ancestors(user_group.id) + else + ::Ci::Runner.legacy_belonging_to_group(user_group.id, include_ancestors: true) + end + runners = apply_filter(runners, params) present paginate(runners), with: Entities::Ci::Runner diff --git a/lib/api/ci/triggers.rb b/lib/api/ci/triggers.rb index 6a2b16e1568..ae89b475ef8 100644 --- a/lib/api/ci/triggers.rb +++ b/lib/api/ci/triggers.rb @@ -5,7 +5,7 @@ module API class Triggers < ::API::Base include PaginationParams - HTTP_GITLAB_EVENT_HEADER = "HTTP_#{WebHookService::GITLAB_EVENT_HEADER}".underscore.upcase + HTTP_GITLAB_EVENT_HEADER = "HTTP_#{::Gitlab::WebHooks::GITLAB_EVENT_HEADER}".underscore.upcase feature_category :continuous_integration diff --git a/lib/api/debian_project_packages.rb b/lib/api/debian_project_packages.rb index 497ce2f4356..5fb11db8938 100644 --- a/lib/api/debian_project_packages.rb +++ b/lib/api/debian_project_packages.rb @@ -83,7 +83,6 @@ module API ::Packages::Debian::ProcessChangesWorker.perform_async(package_file.id, current_user.id) # rubocop:disable CodeReuse/Worker end - track_package_event('push_package', :debian, user: current_user, project: authorized_user_project, namespace: authorized_user_project.namespace) created! rescue ObjectStorage::RemoteStoreError => e Gitlab::ErrorTracking.track_exception(e, extra: { file_name: params[:file_name], project_id: authorized_user_project.id }) diff --git a/lib/api/deployments.rb b/lib/api/deployments.rb index 80a50ded522..486ff5d89bc 100644 --- a/lib/api/deployments.rb +++ b/lib/api/deployments.rb @@ -165,3 +165,5 @@ module API end end end + +API::Deployments.prepend_mod diff --git a/lib/api/entities/group_detail.rb b/lib/api/entities/group_detail.rb index 5eaccbc7154..e6872709432 100644 --- a/lib/api/entities/group_detail.rb +++ b/lib/api/entities/group_detail.rb @@ -4,7 +4,7 @@ module API module Entities class GroupDetail < Group expose :shared_with_groups do |group, options| - SharedGroupWithGroup.represent(group.shared_with_group_links.public_or_visible_to_user(group, options[:current_user])) + SharedGroupWithGroup.represent(group.shared_with_group_links_visible_to_user(options[:current_user])) end expose :runners_token, if: lambda { |group, options| options[:user_can_admin_group] } expose :prevent_sharing_groups_outside_hierarchy, if: ->(group) { group.root? } diff --git a/lib/api/entities/issue_basic.rb b/lib/api/entities/issue_basic.rb index 6125dc05a6e..20f66c026e6 100644 --- a/lib/api/entities/issue_basic.rb +++ b/lib/api/entities/issue_basic.rb @@ -23,7 +23,7 @@ module API expose :issue_type, as: :type, format_with: :upcase, - documentation: { type: "String", desc: "One of #{::WorkItem::Type.allowed_types_for_issues.map(&:upcase)}" } + documentation: { type: "String", desc: "One of #{::WorkItems::Type.allowed_types_for_issues.map(&:upcase)}" } expose :assignee, using: ::API::Entities::UserBasic do |issue| issue.assignees.first diff --git a/lib/api/entities/merge_request_basic.rb b/lib/api/entities/merge_request_basic.rb index d5cf2f653db..55d58166590 100644 --- a/lib/api/entities/merge_request_basic.rb +++ b/lib/api/entities/merge_request_basic.rb @@ -3,9 +3,13 @@ module API module Entities class MergeRequestBasic < IssuableEntity + # Deprecated in favour of merge_user expose :merged_by, using: Entities::UserBasic do |merge_request, _options| merge_request.metrics&.merged_by end + expose :merge_user, using: Entities::UserBasic do |merge_request| + merge_request.metrics&.merged_by || merge_request.merge_user + end expose :merged_at do |merge_request, _options| merge_request.metrics&.merged_at end diff --git a/lib/api/entities/project.rb b/lib/api/entities/project.rb index 1b9299ed17e..74097dc2883 100644 --- a/lib/api/entities/project.rb +++ b/lib/api/entities/project.rb @@ -82,6 +82,8 @@ module API expose :forked_from_project, using: Entities::BasicProjectDetails, if: ->(project, options) do project.forked? && Ability.allowed?(options[:current_user], :read_project, project.forked_from_project) end + expose :mr_default_target_self, if: -> (project) { project.forked? } + expose :import_status expose :import_error, if: lambda { |_project, options| options[:user_can_admin_project] } do |project| @@ -130,6 +132,7 @@ module API Ability.allowed?(options[:current_user], :change_repository_storage, project) } expose :keep_latest_artifacts_available?, as: :keep_latest_artifact + expose :runner_token_expiration_interval # rubocop: disable CodeReuse/ActiveRecord def self.preload_resource(project) diff --git a/lib/api/entities/project_with_access.rb b/lib/api/entities/project_with_access.rb index ac89cb52e43..b541ccbadcf 100644 --- a/lib/api/entities/project_with_access.rb +++ b/lib/api/entities/project_with_access.rb @@ -8,7 +8,7 @@ module API if options[:project_members] options[:project_members].find { |member| member.source_id == project.id } else - project.project_member(options[:current_user]) + project.member(options[:current_user]) end end diff --git a/lib/api/entities/resource_access_token.rb b/lib/api/entities/resource_access_token.rb index a1c7b28af45..569fd16f488 100644 --- a/lib/api/entities/resource_access_token.rb +++ b/lib/api/entities/resource_access_token.rb @@ -4,7 +4,7 @@ module API module Entities class ResourceAccessToken < Entities::PersonalAccessToken expose :access_level do |token, options| - options[:project].project_member(token.user).access_level + options[:resource].member(token.user).access_level end end end diff --git a/lib/api/helpers/integrations_helpers.rb b/lib/api/helpers/integrations_helpers.rb index e7fdb6645a5..3af0dd4c532 100644 --- a/lib/api/helpers/integrations_helpers.rb +++ b/lib/api/helpers/integrations_helpers.rb @@ -314,25 +314,33 @@ module API required: false, name: :datadog_site, type: String, - desc: 'Choose the Datadog site to send data to. Set to "datadoghq.eu" to send data to the EU site' + desc: 'The Datadog site to send data to. To send data to the EU site, use datadoghq.eu' }, { required: false, name: :api_url, type: String, - desc: '(Advanced) Define the full URL for your Datadog site directly' + desc: '(Advanced) The full URL for your Datadog site' }, + # TODO: uncomment this field once :datadog_integration_logs_collection is rolled out + # https://gitlab.com/gitlab-org/gitlab/-/issues/346339 + # { + # required: false, + # name: :archive_trace_events, + # type: Boolean, + # desc: 'When enabled, job logs will be collected by Datadog and shown along pipeline execution traces' + # }, { required: false, name: :datadog_service, type: String, - desc: 'Name of this GitLab instance that all data will be tagged with' + desc: 'Tag all data from this GitLab instance in Datadog. Useful when managing several self-managed deployments' }, { required: false, name: :datadog_env, type: String, - desc: 'The environment tag that traces will be tagged with' + desc: 'For self-managed deployments, set the env tag for all the data sent to Datadog. How do I use tags?' } ], 'discord' => [ diff --git a/lib/api/helpers/members_helpers.rb b/lib/api/helpers/members_helpers.rb index c2710be6c03..6c20993431d 100644 --- a/lib/api/helpers/members_helpers.rb +++ b/lib/api/helpers/members_helpers.rb @@ -50,7 +50,7 @@ module API end def find_all_members_for_group(group) - GroupMembersFinder.new(group).execute + GroupMembersFinder.new(group, current_user).execute(include_relations: [:inherited, :direct, :shared_from_groups]) end def present_members(members) diff --git a/lib/api/helpers/projects_helpers.rb b/lib/api/helpers/projects_helpers.rb index d7de8bd8b8b..00f745067e7 100644 --- a/lib/api/helpers/projects_helpers.rb +++ b/lib/api/helpers/projects_helpers.rb @@ -71,6 +71,7 @@ module API optional :repository_storage, type: String, desc: 'Which storage shard the repository is on. Available only to admins' optional :packages_enabled, type: Boolean, desc: 'Enable project packages feature' optional :squash_option, type: String, values: %w(never always default_on default_off), desc: 'Squash default for project. One of `never`, `always`, `default_on`, or `default_off`.' + optional :mr_default_target_self, Boolean, desc: 'Merge requests of this forked project targets itself by default' end params :optional_project_params_ee do @@ -169,6 +170,7 @@ module API :packages_enabled, :service_desk_enabled, :keep_latest_artifact, + :mr_default_target_self, # TODO: remove in API v5, replaced by *_access_level :issues_enabled, diff --git a/lib/api/helpers/rate_limiter.rb b/lib/api/helpers/rate_limiter.rb index 7d87c74097d..0ad4f089907 100644 --- a/lib/api/helpers/rate_limiter.rb +++ b/lib/api/helpers/rate_limiter.rb @@ -10,6 +10,7 @@ module API # See app/controllers/concerns/check_rate_limit.rb for Rails controllers version module RateLimiter def check_rate_limit!(key, scope:, **options) + return if bypass_header_set? return unless rate_limiter.throttled?(key, scope: scope, **options) rate_limiter.log_request(request, "#{key}_request_limit".to_sym, current_user) @@ -24,6 +25,10 @@ module API def rate_limiter ::Gitlab::ApplicationRateLimiter end + + def bypass_header_set? + ::Gitlab::Throttle.bypass_header.present? && request.get_header(Gitlab::Throttle.bypass_header) == '1' + end end end end diff --git a/lib/api/integrations.rb b/lib/api/integrations.rb index bab8e556a73..ff1d88e35f0 100644 --- a/lib/api/integrations.rb +++ b/lib/api/integrations.rb @@ -111,7 +111,14 @@ module API integration = user_project.find_or_initialize_integration(params[:slug].underscore) destroy_conditionally!(integration) do - attrs = integration_attributes(integration).index_with { nil }.merge(active: false) + attrs = integration_attributes(integration).index_with do |attr| + column = integration.column_for_attribute(attr) + if column.is_a?(ActiveRecord::ConnectionAdapters::NullColumn) + nil + else + column.default + end + end.merge(active: false) render_api_error!('400 Bad Request', 400) unless integration.update(attrs) end diff --git a/lib/api/internal/base.rb b/lib/api/internal/base.rb index d8e39d089e4..48157a91477 100644 --- a/lib/api/internal/base.rb +++ b/lib/api/internal/base.rb @@ -43,6 +43,10 @@ module API # This is a separate method so that EE can alter its behaviour more # easily. + if Feature.enabled?(:rate_limit_gitlab_shell, default_enabled: :yaml) + check_rate_limit!(:gitlab_shell_operation, scope: [params[:action], params[:project], actor.key_or_user]) + end + # Stores some Git-specific env thread-safely env = parse_env Gitlab::Git::HookEnv.set(gl_repository, env) if container diff --git a/lib/api/internal/kubernetes.rb b/lib/api/internal/kubernetes.rb index f3974236fe3..3977da4bda4 100644 --- a/lib/api/internal/kubernetes.rb +++ b/lib/api/internal/kubernetes.rb @@ -53,7 +53,7 @@ module API def check_agent_token unauthorized! unless agent_token - agent_token.track_usage + Clusters::AgentTokens::TrackUsageService.new(agent_token).execute end end diff --git a/lib/api/internal/mail_room.rb b/lib/api/internal/mail_room.rb new file mode 100644 index 00000000000..6e24cf6e7c5 --- /dev/null +++ b/lib/api/internal/mail_room.rb @@ -0,0 +1,51 @@ +# frozen_string_literal: true + +module API + # This internal endpoint receives webhooks sent from the MailRoom component. + # This component constantly listens to configured email accounts. When it + # finds any incoming email or service desk email, it makes a POST request to + # this endpoint. The target mailbox type is indicated in the request path. + # The email raw content is attached to the request body. + # + # For more information, please visit https://gitlab.com/groups/gitlab-com/gl-infra/-/epics/644 + module Internal + class MailRoom < ::API::Base + feature_category :service_desk + + before do + authenticate_gitlab_mailroom_request! + end + + helpers do + def authenticate_gitlab_mailroom_request! + unauthorized! unless Gitlab::MailRoom::Authenticator.verify_api_request(headers, params[:mailbox_type]) + end + end + + namespace 'internal' do + namespace 'mail_room' do + params do + requires :mailbox_type, type: String, + desc: 'The destination mailbox type configuration. Must either be incoming_email or service_desk_email' + end + post "/*mailbox_type" do + worker = Gitlab::MailRoom.worker_for(params[:mailbox_type]) + raw = request.body.read + begin + worker.perform_async(raw) + rescue Gitlab::SidekiqMiddleware::SizeLimiter::ExceedLimitError + receiver = Gitlab::Email::Receiver.new(raw) + reason = Gitlab::Email::FailureHandler.handle(receiver, Gitlab::Email::EmailTooLarge.new) + + status 400 + break { success: false, message: reason } + end + + status 200 + { success: true } + end + end + end + end + end +end diff --git a/lib/api/issues.rb b/lib/api/issues.rb index 4d67cbd1272..46124a74e9d 100644 --- a/lib/api/issues.rb +++ b/lib/api/issues.rb @@ -82,7 +82,7 @@ module API desc: 'Return issues sorted in `asc` or `desc` order.' optional :due_date, type: String, values: %w[0 overdue week month next_month_and_previous_two_weeks] << '', desc: 'Return issues that have no due date (`0`), or whose due date is this week, this month, between two weeks ago and next month, or which are overdue. Accepts: `overdue`, `week`, `month`, `next_month_and_previous_two_weeks`, `0`' - optional :issue_type, type: String, values: WorkItem::Type.allowed_types_for_issues, desc: "The type of the issue. Accepts: #{WorkItem::Type.allowed_types_for_issues.join(', ')}" + optional :issue_type, type: String, values: WorkItems::Type.allowed_types_for_issues, desc: "The type of the issue. Accepts: #{WorkItems::Type.allowed_types_for_issues.join(', ')}" use :issues_stats_params use :pagination @@ -99,7 +99,7 @@ module API optional :due_date, type: String, desc: 'Date string in the format YEAR-MONTH-DAY' optional :confidential, type: Boolean, desc: 'Boolean parameter if the issue should be confidential' optional :discussion_locked, type: Boolean, desc: " Boolean parameter indicating if the issue's discussion is locked" - optional :issue_type, type: String, values: WorkItem::Type.allowed_types_for_issues, desc: "The type of the issue. Accepts: #{WorkItem::Type.allowed_types_for_issues.join(', ')}" + optional :issue_type, type: String, values: WorkItems::Type.allowed_types_for_issues, desc: "The type of the issue. Accepts: #{WorkItems::Type.allowed_types_for_issues.join(', ')}" use :optional_issue_params_ee end diff --git a/lib/api/package_files.rb b/lib/api/package_files.rb index 79ebf18ff27..5e421da2c55 100644 --- a/lib/api/package_files.rb +++ b/lib/api/package_files.rb @@ -28,10 +28,15 @@ module API package = ::Packages::PackageFinder .new(user_project, params[:package_id]).execute - files = package.package_files - .preload_pipelines + package_files = if Feature.enabled?(:packages_installable_package_files, default_enabled: :yaml) + package.installable_package_files + else + package.package_files + end - present paginate(files), with: ::API::Entities::PackageFile + package_files = package_files.preload_pipelines + + present paginate(package_files), with: ::API::Entities::PackageFile end desc 'Remove a package file' do @@ -50,7 +55,13 @@ module API not_found! unless package - package_file = package.package_files.find_by_id(params[:package_file_id]) + package_files = if Feature.enabled?(:packages_installable_package_files, default_enabled: :yaml) + package.installable_package_files + else + package.package_files + end + + package_file = package_files.find_by_id(params[:package_file_id]) not_found! unless package_file diff --git a/lib/api/project_container_repositories.rb b/lib/api/project_container_repositories.rb index 82b6082c3fe..d4efca6e8f2 100644 --- a/lib/api/project_container_repositories.rb +++ b/lib/api/project_container_repositories.rb @@ -123,7 +123,6 @@ module API end delete ':id/registry/repositories/:repository_id/tags/:tag_name', requirements: REPOSITORY_ENDPOINT_REQUIREMENTS do authorize_destroy_container_image! - validate_tag! result = ::Projects::ContainerRepository::DeleteTagsService .new(repository.project, current_user, tags: [declared_params[:tag_name]]) diff --git a/lib/api/projects.rb b/lib/api/projects.rb index 887c76941cf..d772079372c 100644 --- a/lib/api/projects.rb +++ b/lib/api/projects.rb @@ -363,6 +363,7 @@ module API optional :name, type: String, desc: 'The name that will be assigned to the fork' optional :description, type: String, desc: 'The description that will be assigned to the fork' optional :visibility, type: String, values: Gitlab::VisibilityLevel.string_values, desc: 'The visibility of the fork' + optional :mr_default_target_self, Boolean, desc: 'Merge requests of this forked project targets itself by default' end post ':id/fork', feature_category: :source_code_management do Gitlab::QueryLimiting.disable!('https://gitlab.com/gitlab-org/gitlab/-/issues/20759') diff --git a/lib/api/resource_access_tokens.rb b/lib/api/resource_access_tokens.rb index f42acc6b2eb..e52f8fd9111 100644 --- a/lib/api/resource_access_tokens.rb +++ b/lib/api/resource_access_tokens.rb @@ -8,7 +8,7 @@ module API feature_category :authentication_and_authorization - %w[project].each do |source_type| + %w[project group].each do |source_type| resource source_type.pluralize, requirements: API::NAMESPACE_OR_PROJECT_REQUIREMENTS do desc 'Get list of all access tokens for the specified resource' do detail 'This feature was introduced in GitLab 13.9.' @@ -23,8 +23,8 @@ module API tokens = PersonalAccessTokensFinder.new({ user: resource.bots, impersonation: false }).execute.preload_users - resource.project_members.load - present paginate(tokens), with: Entities::ResourceAccessToken, project: resource + resource.members.load + present paginate(tokens), with: Entities::ResourceAccessToken, resource: resource end desc 'Revoke a resource access token' do @@ -58,7 +58,7 @@ module API requires :id, type: String, desc: "The #{source_type} ID" requires :name, type: String, desc: "Resource access token name" requires :scopes, type: Array[String], desc: "The permissions of the token" - optional :access_level, type: Integer, desc: "The access level of the token in the project" + optional :access_level, type: Integer, desc: "The access level of the token in the #{source_type}" optional :expires_at, type: Date, desc: "The expiration date of the token" end post ':id/access_tokens' do @@ -71,7 +71,7 @@ module API ).execute if token_response.success? - present token_response.payload[:access_token], with: Entities::ResourceAccessTokenWithToken, project: resource + present token_response.payload[:access_token], with: Entities::ResourceAccessTokenWithToken, resource: resource else bad_request!(token_response.message) end diff --git a/lib/api/rubygem_packages.rb b/lib/api/rubygem_packages.rb index 9ef6ec03a41..3effa370e84 100644 --- a/lib/api/rubygem_packages.rb +++ b/lib/api/rubygem_packages.rb @@ -66,9 +66,12 @@ module API get "gems/:file_name", requirements: FILE_NAME_REQUIREMENTS do authorize!(:read_package, user_project) - package_file = ::Packages::PackageFile.for_rubygem_with_file_name( - user_project, params[:file_name] - ).last! + package_files = ::Packages::PackageFile + .for_rubygem_with_file_name(user_project, params[:file_name]) + + package_files = package_files.installable if Feature.enabled?(:packages_installable_package_files, default_enabled: :yaml) + + package_file = package_files.last! track_package_event('pull_package', :rubygems, project: user_project, namespace: user_project.namespace) diff --git a/lib/api/search.rb b/lib/api/search.rb index fbdbe3476db..60a7e944b43 100644 --- a/lib/api/search.rb +++ b/lib/api/search.rb @@ -4,7 +4,11 @@ module API class Search < ::API::Base include PaginationParams - before { authenticate! } + before do + authenticate! + + check_rate_limit!(:user_email_lookup, scope: [current_user]) if search_service.params.email_lookup? + end feature_category :global_search @@ -36,7 +40,7 @@ module API }.freeze end - def search(additional_params = {}) + def search_service(additional_params = {}) search_params = { scope: params[:scope], search: params[:search], @@ -50,7 +54,11 @@ module API sort: params[:sort] }.merge(additional_params) - results = SearchService.new(current_user, search_params).search_objects(preload_method) + SearchService.new(current_user, search_params) + end + + def search(additional_params = {}) + results = search_service(additional_params).search_objects(preload_method) Gitlab::UsageDataCounters::SearchCounter.count(:all_searches) diff --git a/lib/api/terraform/modules/v1/packages.rb b/lib/api/terraform/modules/v1/packages.rb index ad5a4ae7ea6..970fdeba734 100644 --- a/lib/api/terraform/modules/v1/packages.rb +++ b/lib/api/terraform/modules/v1/packages.rb @@ -71,7 +71,11 @@ module API def package_file strong_memoize(:package_file) do - package.package_files.first + if Feature.enabled?(:packages_installable_package_files, default_enabled: :yaml) + package.installable_package_files.first + else + package.package_files.first + end end end end diff --git a/lib/api/users.rb b/lib/api/users.rb index ce0a0e9b502..eeb5244466a 100644 --- a/lib/api/users.rb +++ b/lib/api/users.rb @@ -142,11 +142,15 @@ module API get ":id", feature_category: :users do forbidden!('Not authorized!') unless current_user + if Feature.enabled?(:rate_limit_user_by_id_endpoint, type: :development) + check_rate_limit! :users_get_by_id, scope: current_user unless current_user.admin? + end + user = User.find_by(id: params[:id]) not_found!('User') unless user && can?(current_user, :read_user, user) - opts = { with: current_user&.admin? ? Entities::UserDetailsWithAdmin : Entities::User, current_user: current_user } + opts = { with: current_user.admin? ? Entities::UserDetailsWithAdmin : Entities::User, current_user: current_user } user, opts = with_custom_attributes(user, opts) present user, opts @@ -1072,7 +1076,7 @@ module API attrs = declared_params(include_missing: false) - service = ::Users::UpsertCreditCardValidationService.new(attrs).execute + service = ::Users::UpsertCreditCardValidationService.new(attrs, user).execute if service.success? present user.credit_card_validation, with: Entities::UserCreditCardValidations diff --git a/lib/api/v3/github.rb b/lib/api/v3/github.rb index d6c026963e1..c86b7785ce2 100644 --- a/lib/api/v3/github.rb +++ b/lib/api/v3/github.rb @@ -183,7 +183,9 @@ module API params do use :project_full_path end - get ':namespace/:project/pulls' do + # TODO Remove the custom Apdex SLO target `urgency: :low` when this endpoint has been optimised. + # https://gitlab.com/gitlab-org/gitlab/-/issues/337269 + get ':namespace/:project/pulls', urgency: :low do user_project = find_project_with_access(params) merge_requests = authorized_merge_requests_for_project(user_project) @@ -236,7 +238,9 @@ module API use :project_full_path use :pagination end - get ':namespace/:project/branches' do + # TODO Remove the custom Apdex SLO target `urgency: :low` when this endpoint has been optimised. + # https://gitlab.com/gitlab-org/gitlab/-/issues/337268 + get ':namespace/:project/branches', urgency: :low do user_project = find_project_with_access(params) update_project_feature_usage_for(user_project) |