diff options
Diffstat (limited to 'lib/api/helpers')
-rw-r--r-- | lib/api/helpers/award_emoji.rb | 22 | ||||
-rw-r--r-- | lib/api/helpers/discussions_helpers.rb | 2 | ||||
-rw-r--r-- | lib/api/helpers/integrations_helpers.rb | 9 | ||||
-rw-r--r-- | lib/api/helpers/merge_requests_helpers.rb | 173 | ||||
-rw-r--r-- | lib/api/helpers/notes_helpers.rb | 16 | ||||
-rw-r--r-- | lib/api/helpers/packages/conan/api_helpers.rb | 10 | ||||
-rw-r--r-- | lib/api/helpers/packages/dependency_proxy_helpers.rb | 6 | ||||
-rw-r--r-- | lib/api/helpers/packages_helpers.rb | 14 | ||||
-rw-r--r-- | lib/api/helpers/projects_helpers.rb | 8 |
9 files changed, 143 insertions, 117 deletions
diff --git a/lib/api/helpers/award_emoji.rb b/lib/api/helpers/award_emoji.rb index 3ea35381c97..f8417366ea4 100644 --- a/lib/api/helpers/award_emoji.rb +++ b/lib/api/helpers/award_emoji.rb @@ -7,7 +7,7 @@ module API [ { type: 'issue', resource: :projects, find_by: :iid, feature_category: :team_planning }, { type: 'merge_request', resource: :projects, find_by: :iid, feature_category: :code_review }, - { type: 'snippet', resource: :projects, find_by: :id, feature_category: :snippets } + { type: 'snippet', resource: :projects, find_by: :id, feature_category: :source_code_management } ] end @@ -18,18 +18,16 @@ module API # rubocop: disable CodeReuse/ActiveRecord def awardable @awardable ||= - begin - if params.include?(:note_id) - note_id = params.delete(:note_id) + if params.include?(:note_id) + note_id = params.delete(:note_id) - awardable.notes.find(note_id) - elsif params.include?(:issue_iid) - user_project.issues.find_by!(iid: params[:issue_iid]) - elsif params.include?(:merge_request_iid) - user_project.merge_requests.find_by!(iid: params[:merge_request_iid]) - elsif params.include?(:snippet_id) - user_project.snippets.find(params[:snippet_id]) - end + awardable.notes.find(note_id) + elsif params.include?(:issue_iid) + user_project.issues.find_by!(iid: params[:issue_iid]) + elsif params.include?(:merge_request_iid) + user_project.merge_requests.find_by!(iid: params[:merge_request_iid]) + elsif params.include?(:snippet_id) + user_project.snippets.find(params[:snippet_id]) end end # rubocop: enable CodeReuse/ActiveRecord diff --git a/lib/api/helpers/discussions_helpers.rb b/lib/api/helpers/discussions_helpers.rb index c94199b17bc..182ada54a12 100644 --- a/lib/api/helpers/discussions_helpers.rb +++ b/lib/api/helpers/discussions_helpers.rb @@ -8,7 +8,7 @@ module API # extend it. { Issue => :team_planning, - Snippet => :snippets, + Snippet => :source_code_management, MergeRequest => :code_review, Commit => :code_review } diff --git a/lib/api/helpers/integrations_helpers.rb b/lib/api/helpers/integrations_helpers.rb index 99273e81730..543449c0349 100644 --- a/lib/api/helpers/integrations_helpers.rb +++ b/lib/api/helpers/integrations_helpers.rb @@ -415,14 +415,6 @@ module API desc: 'The URL of the external wiki' } ], - 'flowdock' => [ - { - required: true, - name: :token, - type: String, - desc: 'Flowdock token' - } - ], 'hangouts-chat' => [ { required: true, @@ -893,7 +885,6 @@ module API ::Integrations::EmailsOnPush, ::Integrations::Ewm, ::Integrations::ExternalWiki, - ::Integrations::Flowdock, ::Integrations::HangoutsChat, ::Integrations::Harbor, ::Integrations::Irker, diff --git a/lib/api/helpers/merge_requests_helpers.rb b/lib/api/helpers/merge_requests_helpers.rb index eed9fa30d3c..ee3bb49c97f 100644 --- a/lib/api/helpers/merge_requests_helpers.rb +++ b/lib/api/helpers/merge_requests_helpers.rb @@ -11,100 +11,107 @@ module API params :ee_approval_params do end - params :merge_requests_negatable_params do - optional :author_id, type: Integer, desc: 'Return merge requests which are authored by the user with the given ID' - optional :author_username, type: String, desc: 'Return merge requests which are authored by the user with the given username' + params :merge_requests_negatable_params do |options| + optional :author_id, type: Integer, + desc: "#{options[:prefix]}Returns merge requests created by the given user `id`. Mutually exclusive with `author_username`. Combine with `scope=all` or `scope=assigned_to_me`." + optional :author_username, type: String, + desc: "#{options[:prefix]}Returns merge requests created by the given `username`. Mutually exclusive with `author_id`." mutually_exclusive :author_id, :author_username - - optional :assignee_id, - types: [Integer, String], - integer_none_any: true, - desc: 'Return merge requests which are assigned to the user with the given ID' - optional :assignee_username, - type: Array[String], - check_assignees_count: true, - coerce_with: Validations::Validators::CheckAssigneesCount.coerce, - desc: 'Return merge requests which are assigned to the user with the given username' + optional :assignee_id, types: [Integer, String], + integer_none_any: true, + desc: "#{options[:prefix]}Returns merge requests assigned to the given user `id`. `None` returns unassigned merge requests. `Any` returns merge requests with an assignee." + optional :assignee_username, type: Array[String], + check_assignees_count: true, + coerce_with: Validations::Validators::CheckAssigneesCount.coerce, + desc: "#{options[:prefix]}Returns merge requests created by the given `username`. Mutually exclusive with `author_id`.", + documentation: { is_array: true } mutually_exclusive :assignee_id, :assignee_username - optional :reviewer_username, - type: String, - desc: 'Return merge requests which have the user as a reviewer with the given username' - - optional :labels, - type: Array[String], - coerce_with: Validations::Types::CommaSeparatedToArray.coerce, - desc: 'Comma-separated list of label names' - optional :milestone, type: String, desc: 'Return merge requests for a specific milestone' - optional :my_reaction_emoji, type: String, desc: 'Return issues reacted by the authenticated user by the given emoji' + optional :reviewer_username, type: String, + desc: "#{options[:prefix]}Returns merge requests which have the user as a reviewer with the given `username`. `None` returns merge requests with no reviewers. `Any` returns merge requests with any reviewer. Mutually exclusive with `reviewer_id`. Introduced in GitLab 13.8." + optional :labels, type: Array[String], + coerce_with: Validations::Types::CommaSeparatedToArray.coerce, + desc: "#{options[:prefix]}Returns merge requests matching a comma-separated list of labels. `None` lists all merge requests with no labels. `Any` lists all merge requests with at least one label. Predefined names are case-insensitive.", + documentation: { is_array: true } + optional :milestone, type: String, + desc: "#{options[:prefix]}Returns merge requests for a specific milestone. `None` returns merge requests with no milestone. `Any` returns merge requests that have an assigned milestone." + optional :my_reaction_emoji, type: String, + desc: "#{options[:prefix]}Returns merge requests reacted by the authenticated user by the given `emoji`. `None` returns issues not given a reaction. `Any` returns issues given at least one reaction." end params :merge_requests_base_params do - use :merge_requests_negatable_params - optional :reviewer_id, - types: [Integer, String], - integer_none_any: true, - desc: 'Return merge requests which have the user as a reviewer with the given ID' + use :merge_requests_negatable_params, prefix: '' + + optional :reviewer_id, types: [Integer, String], + integer_none_any: true, + desc: 'Returns merge requests which have the user as a reviewer with the given user `id`. `None` returns merge requests with no reviewers. `Any` returns merge requests with any reviewer. Mutually exclusive with `reviewer_username`.' mutually_exclusive :reviewer_id, :reviewer_username - optional :state, - type: String, - values: %w[opened closed locked merged all], - default: 'all', - desc: 'Return opened, closed, locked, merged, or all merge requests' - optional :order_by, - type: String, - values: Helpers::MergeRequestsHelpers.sort_options, - default: 'created_at', - desc: "Return merge requests ordered by #{Helpers::MergeRequestsHelpers.sort_options_help} fields." - optional :sort, - type: String, - values: %w[asc desc], - default: 'desc', - desc: 'Return merge requests sorted in `asc` or `desc` order.' - optional :with_labels_details, type: Boolean, desc: 'Return titles of labels and other details', default: false - optional :with_merge_status_recheck, type: Boolean, desc: 'Request that stale merge statuses be rechecked asynchronously', default: false - optional :created_after, type: DateTime, desc: 'Return merge requests created after the specified time' - optional :created_before, type: DateTime, desc: 'Return merge requests created before the specified time' - optional :updated_after, type: DateTime, desc: 'Return merge requests updated after the specified time' - optional :updated_before, type: DateTime, desc: 'Return merge requests updated before the specified time' - optional :view, - type: String, - values: %w[simple], - desc: 'If simple, returns the `iid`, URL, title, description, and basic state of merge request' - - optional :scope, - type: String, - values: %w[created-by-me assigned-to-me created_by_me assigned_to_me all], - desc: 'Return merge requests for the given scope: `created_by_me`, `assigned_to_me` or `all`' - optional :source_branch, type: String, desc: 'Return merge requests with the given source branch' - optional :source_project_id, type: Integer, desc: 'Return merge requests with the given source project id' - optional :target_branch, type: String, desc: 'Return merge requests with the given target branch' - optional :search, - type: String, - desc: 'Search merge requests for text present in the title, description, or any combination of these' - optional :in, type: String, desc: '`title`, `description`, or a string joining them with comma' - optional :wip, type: String, values: %w[yes no], desc: 'Search merge requests for WIP in the title' - optional :not, type: Hash, desc: 'Parameters to negate' do - use :merge_requests_negatable_params - optional :reviewer_id, - types: Integer, - desc: 'Return merge requests which have the user as a reviewer with the given ID' + optional :state, type: String, + values: %w[opened closed locked merged all], + default: 'all', + desc: 'Returns `all` merge requests or just those that are `opened`, `closed`, `locked`, or `merged`.' + optional :order_by, type: String, + values: Helpers::MergeRequestsHelpers.sort_options, + default: 'created_at', + desc: "Returns merge requests ordered by #{Helpers::MergeRequestsHelpers.sort_options_help} fields. Introduced in GitLab 14.8." + optional :sort, type: String, + values: %w[asc desc], + default: 'desc', + desc: 'Returns merge requests sorted in `asc` or `desc` order.' + optional :with_labels_details, type: Boolean, + default: false, + desc: 'If `true`, response returns more details for each label in labels field: `:name`,`:color`, `:description`, `:description_html`, `:text_color`' + optional :with_merge_status_recheck, type: Boolean, + default: false, + desc: 'If `true`, this projection requests (but does not guarantee) that the `merge_status` field be recalculated asynchronously. Introduced in GitLab 13.0.' + optional :created_after, type: DateTime, + desc: 'Returns merge requests created on or after the given time. Expected in ISO 8601 format.', + documentation: { example: '2019-03-15T08:00:00Z' } + optional :created_before, type: DateTime, + desc: 'Returns merge requests created on or before the given time. Expected in ISO 8601 format.', + documentation: { example: '2019-03-15T08:00:00Z' } + optional :updated_after, type: DateTime, + desc: 'Returns merge requests updated on or after the given time. Expected in ISO 8601 format.', + documentation: { example: '2019-03-15T08:00:00Z' } + optional :updated_before, type: DateTime, + desc: 'Returns merge requests updated on or before the given time. Expected in ISO 8601 format.', + documentation: { example: '2019-03-15T08:00:00Z' } + optional :view, type: String, + values: %w[simple], + desc: 'If simple, returns the `iid`, URL, title, description, and basic state of merge request' + optional :scope, type: String, + values: %w[created-by-me assigned-to-me created_by_me assigned_to_me all], + desc: 'Returns merge requests for the given scope: `created_by_me`, `assigned_to_me` or `all`' + optional :source_branch, type: String, desc: 'Returns merge requests with the given source branch' + optional :source_project_id, type: Integer, desc: 'Returns merge requests with the given source project id' + optional :target_branch, type: String, desc: 'Returns merge requests with the given target branch' + optional :search, type: String, + desc: 'Search merge requests against their `title` and `description`.' + optional :in, type: String, + desc: 'Modify the scope of the search attribute. `title`, `description`, or a string joining them with comma.', + documentation: { example: 'title,description' } + optional :wip, type: String, + values: %w[yes no], + desc: 'Filter merge requests against their `wip` status. `yes` to return only draft merge requests, `no` to return non-draft merge requests.' + optional :not, type: Hash, desc: 'Returns merge requests that do not match the parameters supplied' do + use :merge_requests_negatable_params, prefix: '`<Negated>` ' + + optional :reviewer_id, types: Integer, + desc: '`<Negated>` Returns merge requests which have the user as a reviewer with the given user `id`. `None` returns merge requests with no reviewers. `Any` returns merge requests with any reviewer. Mutually exclusive with `reviewer_username`.' mutually_exclusive :reviewer_id, :reviewer_username end - - optional :deployed_before, - 'Return merge requests deployed before the given date/time' - optional :deployed_after, - 'Return merge requests deployed after the given date/time' - optional :environment, - 'Returns merge requests deployed to the given environment' + optional :deployed_before, desc: 'Returns merge requests deployed before the given date/time. Expected in ISO 8601 format.', + documentation: { example: '2019-03-15T08:00:00Z' } + optional :deployed_after, desc: 'Returns merge requests deployed after the given date/time. Expected in ISO 8601 format', + documentation: { example: '2019-03-15T08:00:00Z' } + optional :environment, desc: 'Returns merge requests deployed to the given environment', + documentation: { example: '2019-03-15T08:00:00Z' } end params :optional_scope_param do - optional :scope, - type: String, - values: %w[created-by-me assigned-to-me created_by_me assigned_to_me all], - default: 'created_by_me', - desc: 'Return merge requests for the given scope: `created_by_me`, `assigned_to_me` or `all`' + optional :scope, type: String, + values: %w[created-by-me assigned-to-me created_by_me assigned_to_me all], + default: 'created_by_me', + desc: 'Returns merge requests for the given scope: `created_by_me`, `assigned_to_me` or `all`' end def handle_merge_request_errors!(merge_request) diff --git a/lib/api/helpers/notes_helpers.rb b/lib/api/helpers/notes_helpers.rb index 45671b09be9..302dac4abf7 100644 --- a/lib/api/helpers/notes_helpers.rb +++ b/lib/api/helpers/notes_helpers.rb @@ -9,7 +9,7 @@ module API { Issue => :team_planning, MergeRequest => :code_review, - Snippet => :snippets + Snippet => :source_code_management } end @@ -90,7 +90,12 @@ module API params = finder_params_by_noteable_type_and_id(noteable_type, noteable_id) noteable = NotesFinder.new(current_user, params).target - noteable = nil unless can?(current_user, noteable_read_ability_name(noteable), noteable) + + # Checking `read_note` permission here, because API code does not seem to use NoteFinder to find notes, + # but rather pulls notes directly through notes association, so there is no chance to check read_note + # permission at service level. With WorkItem model we need to make sure that it has WorkItem::Widgets::Note + # available in order to access notes. + noteable = nil unless can_read_notes?(noteable) noteable || not_found!(noteable_type) end @@ -147,6 +152,13 @@ module API def disable_query_limiting Gitlab::QueryLimiting.disable!('https://gitlab.com/gitlab-org/gitlab/-/issues/211538') end + + private + + def can_read_notes?(noteable) + Ability.allowed?(current_user, noteable_read_ability_name(noteable), noteable) && + Ability.allowed?(current_user, :read_note, noteable) + end end end end diff --git a/lib/api/helpers/packages/conan/api_helpers.rb b/lib/api/helpers/packages/conan/api_helpers.rb index a9d91895cfe..3ea558f3569 100644 --- a/lib/api/helpers/packages/conan/api_helpers.rb +++ b/lib/api/helpers/packages/conan/api_helpers.rb @@ -47,14 +47,14 @@ module API end def recipe_upload_urls - { upload_urls: file_names.select(&method(:recipe_file?)).to_h do |file_name| - [file_name, build_recipe_file_upload_url(file_name)] + { upload_urls: file_names.select(&method(:recipe_file?)).index_with do |file_name| + build_recipe_file_upload_url(file_name) end } end def package_upload_urls - { upload_urls: file_names.select(&method(:package_file?)).to_h do |file_name| - [file_name, build_package_file_upload_url(file_name)] + { upload_urls: file_names.select(&method(:package_file?)).index_with do |file_name| + build_package_file_upload_url(file_name) end } end @@ -128,7 +128,7 @@ module API strong_memoize(:project) do case package_scope when :project - find_project!(params[:id]) + user_project(action: :read_package) when :instance full_path = ::Packages::Conan::Metadatum.full_path_from(package_username: params[:package_username]) find_project!(full_path) diff --git a/lib/api/helpers/packages/dependency_proxy_helpers.rb b/lib/api/helpers/packages/dependency_proxy_helpers.rb index 1ae863a5a25..4b0e63c8f3b 100644 --- a/lib/api/helpers/packages/dependency_proxy_helpers.rb +++ b/lib/api/helpers/packages/dependency_proxy_helpers.rb @@ -19,7 +19,9 @@ module API def redirect_registry_request(forward_to_registry: false, package_type: nil, target: nil, **options) if forward_to_registry && redirect_registry_request_available?(package_type, target) && maven_forwarding_ff_enabled?(package_type, target) ::Gitlab::Tracking.event(self.options[:for].name, "#{package_type}_request_forward") - redirect(registry_url(package_type, options)) + redirect(registry_url(package_type, options), body: options[:body]) + # For the requests with POST methods we need to set status 307 in order to keep request's method + status :temporary_redirect if options[:method] == 'POST' else yield end @@ -32,7 +34,7 @@ module API case package_type when :npm - "#{base_url}#{options[:package_name]}" + "#{base_url}#{[options[:path], options[:package_name]].compact.join('/')}" when :pypi "#{base_url}#{options[:package_name]}/" when :maven diff --git a/lib/api/helpers/packages_helpers.rb b/lib/api/helpers/packages_helpers.rb index 96a10d43401..8d913268405 100644 --- a/lib/api/helpers/packages_helpers.rb +++ b/lib/api/helpers/packages_helpers.rb @@ -78,10 +78,18 @@ module API end end - def track_package_event(event_name, scope, **args) - ::Packages::CreateEventService.new(nil, current_user, event_name: event_name, scope: scope).execute + def track_package_event(action, scope, **args) + ::Packages::CreateEventService.new(nil, current_user, event_name: action, scope: scope).execute category = args.delete(:category) || self.options[:for].name - ::Gitlab::Tracking.event(category, event_name.to_s, **args) + event_name = "i_package_#{scope}_user" + ::Gitlab::Tracking.event( + category, + action.to_s, + property: event_name, + label: 'redis_hll_counters.user_packages.user_packages_total_unique_counts_monthly', + context: [Gitlab::Tracking::ServicePingContext.new(data_source: :redis_hll, event: event_name).to_context], + **args + ) end def present_package_file!(package_file, supports_direct_download: true) diff --git a/lib/api/helpers/projects_helpers.rb b/lib/api/helpers/projects_helpers.rb index c95bf0f0c21..9d370176e62 100644 --- a/lib/api/helpers/projects_helpers.rb +++ b/lib/api/helpers/projects_helpers.rb @@ -37,6 +37,10 @@ module API optional :container_registry_access_level, type: String, values: %w(disabled private enabled), desc: 'Controls visibility of the container registry. One of `disabled`, `private` or `enabled`. `private` will make the container registry accessible only to project members (reporter role and above). `enabled` will make the container registry accessible to everyone who has access to the project. `disabled` will disable the container registry' optional :security_and_compliance_access_level, type: String, values: %w(disabled private enabled), desc: 'Security and compliance access level. One of `disabled`, `private` or `enabled`' optional :releases_access_level, type: String, values: %w(disabled private enabled), desc: 'Releases access level. One of `disabled`, `private` or `enabled`' + optional :environments_access_level, type: String, values: %w(disabled private enabled), desc: 'Environments access level. One of `disabled`, `private` or `enabled`' + optional :feature_flags_access_level, type: String, values: %w(disabled private enabled), desc: 'Feature flags access level. One of `disabled`, `private` or `enabled`' + optional :infrastructure_access_level, type: String, values: %w(disabled private enabled), desc: 'Infrastructure access level. One of `disabled`, `private` or `enabled`' + optional :monitor_access_level, type: String, values: %w(disabled private enabled), desc: 'Monitor access level. One of `disabled`, `private` or `enabled`' optional :emails_disabled, type: Boolean, desc: 'Disable email notifications' optional :show_default_award_emojis, type: Boolean, desc: 'Show default award emojis' @@ -183,6 +187,10 @@ module API :mr_default_target_self, :enforce_auth_checks_on_uploads, :releases_access_level, + :environments_access_level, + :feature_flags_access_level, + :infrastructure_access_level, + :monitor_access_level, # TODO: remove in API v5, replaced by *_access_level :issues_enabled, |