From 311b0269b4eb9839fa63f80c8d7a58f32b8138a0 Mon Sep 17 00:00:00 2001 From: GitLab Bot Date: Thu, 18 Nov 2021 13:16:36 +0000 Subject: Add latest changes from gitlab-org/gitlab@14-5-stable-ee --- app/finders/autocomplete/routes_finder.rb | 2 +- app/finders/award_emojis_finder.rb | 2 +- app/finders/ci/pipelines_finder.rb | 17 ++++-- .../ci/pipelines_for_merge_request_finder.rb | 66 +++++----------------- .../clusters/agent_authorizations_finder.rb | 65 +++++++++++++++++++++ .../environments_by_deployments_finder.rb | 16 ++++-- app/finders/events_finder.rb | 5 +- app/finders/issuables/label_filter.rb | 8 +-- app/finders/members_finder.rb | 15 ++--- app/finders/packages/group_packages_finder.rb | 2 +- app/finders/packages/package_finder.rb | 2 +- app/finders/packages/packages_finder.rb | 3 +- app/finders/security/security_jobs_finder.rb | 2 +- app/finders/snippets_finder.rb | 27 ++++++--- app/finders/tags_finder.rb | 35 ++++++++++-- 15 files changed, 169 insertions(+), 98 deletions(-) create mode 100644 app/finders/clusters/agent_authorizations_finder.rb (limited to 'app/finders') diff --git a/app/finders/autocomplete/routes_finder.rb b/app/finders/autocomplete/routes_finder.rb index b3f2693b273..858a4b69376 100644 --- a/app/finders/autocomplete/routes_finder.rb +++ b/app/finders/autocomplete/routes_finder.rb @@ -30,7 +30,7 @@ module Autocomplete class NamespacesOnly < self def routables - return Namespace.all if current_user.admin? + return Namespace.without_project_namespaces if current_user.admin? current_user.namespaces end diff --git a/app/finders/award_emojis_finder.rb b/app/finders/award_emojis_finder.rb index 9ff64637128..709d3f3e593 100644 --- a/app/finders/award_emojis_finder.rb +++ b/app/finders/award_emojis_finder.rb @@ -40,7 +40,7 @@ class AwardEmojisFinder def validate_name_param return unless params[:name] - raise ArgumentError, 'Invalid name param' unless params[:name].to_s.in?(Gitlab::Emoji.emojis_names) + raise ArgumentError, 'Invalid name param' unless TanukiEmoji.find_by_alpha_code(params[:name].to_s) end def validate_awarded_by_param diff --git a/app/finders/ci/pipelines_finder.rb b/app/finders/ci/pipelines_finder.rb index 39355853d88..712d5f8c6fb 100644 --- a/app/finders/ci/pipelines_finder.rb +++ b/app/finders/ci/pipelines_finder.rb @@ -5,6 +5,13 @@ module Ci attr_reader :project, :pipelines, :params, :current_user ALLOWED_INDEXED_COLUMNS = %w[id status ref updated_at user_id].freeze + ALLOWED_SCOPES = { + RUNNING: 'running', + PENDING: 'pending', + FINISHED: 'finished', + BRANCHES: 'branches', + TAGS: 'tags' + }.freeze def initialize(project, current_user, params = {}) @project = project @@ -65,15 +72,15 @@ module Ci def by_scope(items) case params[:scope] - when 'running' + when ALLOWED_SCOPES[:RUNNING] items.running - when 'pending' + when ALLOWED_SCOPES[:PENDING] items.pending - when 'finished' + when ALLOWED_SCOPES[:FINISHED] items.finished - when 'branches' + when ALLOWED_SCOPES[:BRANCHES] from_ids(ids_for_ref(branches)) - when 'tags' + when ALLOWED_SCOPES[:TAGS] from_ids(ids_for_ref(tags)) else items diff --git a/app/finders/ci/pipelines_for_merge_request_finder.rb b/app/finders/ci/pipelines_for_merge_request_finder.rb index 9476c30f525..b623a94541b 100644 --- a/app/finders/ci/pipelines_for_merge_request_finder.rb +++ b/app/finders/ci/pipelines_for_merge_request_finder.rb @@ -31,65 +31,27 @@ module Ci # Fetch all pipelines without permission check. def all - ::Gitlab::Database.allow_cross_joins_across_databases(url: 'https://gitlab.com/gitlab-org/gitlab/-/issues/336891') do - strong_memoize(:all_pipelines) do - next Ci::Pipeline.none unless source_project - - pipelines = - if merge_request.persisted? - all_pipelines_for_merge_request - else - triggered_for_branch.for_sha(commit_shas) - end - - sort(pipelines) - end - end - end - - private + strong_memoize(:all_pipelines) do + next Ci::Pipeline.none unless source_project - # rubocop: disable CodeReuse/ActiveRecord - def pipelines_using_cte - sha_relation = merge_request.all_commits.select(:sha).distinct - - cte = Gitlab::SQL::CTE.new(:shas, sha_relation) - - pipelines_for_merge_requests = triggered_by_merge_request - pipelines_for_branch = filter_by_sha(triggered_for_branch, cte) - - Ci::Pipeline.with(cte.to_arel) # rubocop: disable CodeReuse/ActiveRecord - .from_union([pipelines_for_merge_requests, pipelines_for_branch]) - end - # rubocop: enable CodeReuse/ActiveRecord + pipelines = + if merge_request.persisted? + all_pipelines_for_merge_request + else + triggered_for_branch.for_sha(commit_shas) + end - def filter_by_sha(pipelines, cte) - hex = Arel::Nodes::SqlLiteral.new("'hex'") - string_sha = Arel::Nodes::NamedFunction.new('encode', [cte.table[:sha], hex]) - join_condition = string_sha.eq(Ci::Pipeline.arel_table[:sha]) - - filter_by(pipelines, cte, join_condition) + sort(pipelines) + end end - def filter_by(pipelines, cte, join_condition) - shas_table = - Ci::Pipeline.arel_table - .join(cte.table, Arel::Nodes::InnerJoin) - .on(join_condition) - .join_sources - - pipelines.joins(shas_table) # rubocop: disable CodeReuse/ActiveRecord - end + private def all_pipelines_for_merge_request - if Feature.enabled?(:decomposed_ci_query_in_pipelines_for_merge_request_finder, target_project, default_enabled: :yaml) - pipelines_for_merge_request = triggered_by_merge_request - pipelines_for_branch = triggered_for_branch.for_sha(recent_diff_head_shas(COMMITS_LIMIT)) + pipelines_for_merge_request = triggered_by_merge_request + pipelines_for_branch = triggered_for_branch.for_sha(recent_diff_head_shas(COMMITS_LIMIT)) - Ci::Pipeline.from_union([pipelines_for_merge_request, pipelines_for_branch]) - else - pipelines_using_cte - end + Ci::Pipeline.from_union([pipelines_for_merge_request, pipelines_for_branch]) end # NOTE: this method returns only parent merge request pipelines. diff --git a/app/finders/clusters/agent_authorizations_finder.rb b/app/finders/clusters/agent_authorizations_finder.rb new file mode 100644 index 00000000000..373cf7fe8b9 --- /dev/null +++ b/app/finders/clusters/agent_authorizations_finder.rb @@ -0,0 +1,65 @@ +# frozen_string_literal: true + +module Clusters + class AgentAuthorizationsFinder + def initialize(project) + @project = project + end + + def execute + # closest, most-specific authorization for a given agent wins + (project_authorizations + implicit_authorizations + group_authorizations) + .uniq(&:agent_id) + end + + private + + attr_reader :project + + def implicit_authorizations + project.cluster_agents.map do |agent| + Clusters::Agents::ImplicitAuthorization.new(agent: agent) + end + end + + # rubocop: disable CodeReuse/ActiveRecord + def project_authorizations + ancestor_ids = project.group ? project.ancestors.select(:id) : project.namespace_id + + Clusters::Agents::ProjectAuthorization + .where(project_id: project.id) + .joins(agent: :project) + .preload(agent: :project) + .where(cluster_agents: { projects: { namespace_id: ancestor_ids } }) + .with_available_ci_access_fields(project) + .to_a + end + + def group_authorizations + return [] unless project.group + + authorizations = Clusters::Agents::GroupAuthorization.arel_table + + ordered_ancestors_cte = Gitlab::SQL::CTE.new( + :ordered_ancestors, + project.group.self_and_ancestors(hierarchy_order: :asc).reselect(:id) + ) + + cte_join_sources = authorizations.join(ordered_ancestors_cte.table).on( + authorizations[:group_id].eq(ordered_ancestors_cte.table[:id]) + ).join_sources + + Clusters::Agents::GroupAuthorization + .with(ordered_ancestors_cte.to_arel) + .joins(cte_join_sources) + .joins(agent: :project) + .where('projects.namespace_id IN (SELECT id FROM ordered_ancestors)') + .with_available_ci_access_fields(project) + .order(Arel.sql('agent_id, array_position(ARRAY(SELECT id FROM ordered_ancestors)::bigint[], agent_group_authorizations.group_id)')) + .select('DISTINCT ON (agent_id) agent_group_authorizations.*') + .preload(agent: :project) + .to_a + end + # rubocop: enable CodeReuse/ActiveRecord + end +end diff --git a/app/finders/environments/environments_by_deployments_finder.rb b/app/finders/environments/environments_by_deployments_finder.rb index e0ecc98b1c0..a41cfcb37e4 100644 --- a/app/finders/environments/environments_by_deployments_finder.rb +++ b/app/finders/environments/environments_by_deployments_finder.rb @@ -23,12 +23,18 @@ module Environments deployments.none end - environment_ids = deployments - .group(:environment_id) - .select(:environment_id) + environments = + if Feature.enabled?(:environments_by_deployments_finder_exists_optimization, default_enabled: :yaml) + project.environments.available + .where('EXISTS (?)', deployments.where('environment_id = environments.id')) + else + environment_ids = deployments + .group(:environment_id) + .select(:environment_id) - environments = project.environments.available - .where(id: environment_ids) + project.environments.available + .where(id: environment_ids) + end if params[:find_latest] find_one(environments.order_by_last_deployed_at_desc) diff --git a/app/finders/events_finder.rb b/app/finders/events_finder.rb index 4c619f3d7ea..4ed447a90ce 100644 --- a/app/finders/events_finder.rb +++ b/app/finders/events_finder.rb @@ -44,7 +44,6 @@ class EventsFinder events = by_created_at_after(events) events = sort(events) - events = events.with_associations if params[:with_associations] paginated_filtered_by_user_visibility(events) end @@ -113,10 +112,12 @@ class EventsFinder end def paginated_filtered_by_user_visibility(events) + events_count = events.count + events = events.with_associations if params[:with_associations] limited_events = events.page(page).per(per_page) visible_events = limited_events.select { |event| event.visible_to_user?(current_user) } - Kaminari.paginate_array(visible_events, total_count: events.count) + Kaminari.paginate_array(visible_events, total_count: events_count) end def per_page diff --git a/app/finders/issuables/label_filter.rb b/app/finders/issuables/label_filter.rb index f4712fa6879..9a6ca107b19 100644 --- a/app/finders/issuables/label_filter.rb +++ b/app/finders/issuables/label_filter.rb @@ -82,6 +82,8 @@ module Issuables if root_namespace label_ids = find_label_ids(label_names).flatten(1) + return issuables if label_ids.empty? + issuables.where(label_link_query(target_model, label_ids: label_ids).arel.exists.not) else issuables.where(label_link_query(target_model, label_names: label_names).arel.exists.not) @@ -133,11 +135,7 @@ module Issuables # rubocop: disable CodeReuse/ActiveRecord def label_link_query(target_model, label_ids: nil, label_names: nil) - relation = LabelLink - .where(target_type: target_model.name) - .where(LabelLink.arel_table['target_id'].eq(target_model.arel_table['id'])) - - relation = relation.where(label_id: label_ids) if label_ids + relation = LabelLink.by_target_for_exists_query(target_model.name, target_model.arel_table['id'], label_ids) relation = relation.joins(:label).where(labels: { name: label_names }) if label_names relation diff --git a/app/finders/members_finder.rb b/app/finders/members_finder.rb index 0faafa6df9c..e68a0c8fca9 100644 --- a/app/finders/members_finder.rb +++ b/app/finders/members_finder.rb @@ -70,16 +70,11 @@ class MembersFinder end def project_invited_groups - invited_groups_and_ancestors = if ::Feature.enabled?(:linear_members_finder_ancestor_scopes, current_user, default_enabled: :yaml) - project.invited_groups - .self_and_ancestors - else - Gitlab::ObjectHierarchy - .new(project.invited_groups) - .base_and_ancestors - end - - invited_groups_ids_including_ancestors = invited_groups_and_ancestors.public_or_visible_to_user(current_user).select(:id) + invited_groups_ids_including_ancestors = project + .invited_groups + .self_and_ancestors + .public_or_visible_to_user(current_user) + .select(:id) GroupMember.with_source_id(invited_groups_ids_including_ancestors).non_minimal_access end diff --git a/app/finders/packages/group_packages_finder.rb b/app/finders/packages/group_packages_finder.rb index 3ac5f00d518..2a62dd5c0e5 100644 --- a/app/finders/packages/group_packages_finder.rb +++ b/app/finders/packages/group_packages_finder.rb @@ -22,7 +22,7 @@ module Packages def packages_for_group_projects(installable_only: false) packages = ::Packages::Package - .including_build_info + .preload_pipelines .including_project_route .including_tags .for_projects(group_projects_visible_to_current_user.select(:id)) diff --git a/app/finders/packages/package_finder.rb b/app/finders/packages/package_finder.rb index ee96896e350..e482a0503f0 100644 --- a/app/finders/packages/package_finder.rb +++ b/app/finders/packages/package_finder.rb @@ -9,7 +9,7 @@ module Packages def execute @project .packages - .including_build_info + .preload_pipelines .including_project_route .including_tags .displayable diff --git a/app/finders/packages/packages_finder.rb b/app/finders/packages/packages_finder.rb index 552468ecfd1..3bc348c8dc8 100644 --- a/app/finders/packages/packages_finder.rb +++ b/app/finders/packages/packages_finder.rb @@ -14,9 +14,10 @@ module Packages def execute packages = project.packages - .including_build_info + .preload_pipelines .including_project_route .including_tags + packages = filter_with_version(packages) packages = filter_by_package_type(packages) packages = filter_by_package_name(packages) diff --git a/app/finders/security/security_jobs_finder.rb b/app/finders/security/security_jobs_finder.rb index 008d4e29b13..5754492cfa7 100644 --- a/app/finders/security/security_jobs_finder.rb +++ b/app/finders/security/security_jobs_finder.rb @@ -13,7 +13,7 @@ module Security class SecurityJobsFinder < JobsFinder def self.allowed_job_types - [:sast, :dast, :dependency_scanning, :container_scanning, :secret_detection, :coverage_fuzzing, :api_fuzzing, :cluster_image_scanning] + [:sast, :sast_iac, :dast, :dependency_scanning, :container_scanning, :secret_detection, :coverage_fuzzing, :api_fuzzing, :cluster_image_scanning] end end end diff --git a/app/finders/snippets_finder.rb b/app/finders/snippets_finder.rb index 81643826782..b1e12721712 100644 --- a/app/finders/snippets_finder.rb +++ b/app/finders/snippets_finder.rb @@ -42,12 +42,11 @@ class SnippetsFinder < UnionFinder include FinderMethods include Gitlab::Utils::StrongMemoize - attr_accessor :current_user, :params - delegate :explore, :only_personal, :only_project, :scope, :sort, to: :params + attr_reader :current_user, :params def initialize(current_user = nil, params = {}) @current_user = current_user - @params = OpenStruct.new(params) + @params = params if project && author raise( @@ -77,9 +76,9 @@ class SnippetsFinder < UnionFinder private def init_collection - if explore + if explore? snippets_for_explore - elsif only_personal + elsif only_personal? personal_snippets elsif project snippets_for_a_single_project @@ -110,7 +109,7 @@ class SnippetsFinder < UnionFinder # over the resulting SQL query. def snippets_for_personal_and_multiple_projects queries = [] - queries << personal_snippets unless only_project + queries << personal_snippets unless only_project? if Ability.allowed?(current_user, :read_cross_project) queries << snippets_of_visible_projects @@ -171,7 +170,7 @@ class SnippetsFinder < UnionFinder end def visibility_from_scope - case scope.to_s + case params[:scope].to_s when 'are_private' Snippet::PRIVATE when 'are_internal' @@ -206,7 +205,19 @@ class SnippetsFinder < UnionFinder end def sort_param - sort.presence || 'id_desc' + params[:sort].presence || 'id_desc' + end + + def explore? + params[:explore].present? + end + + def only_personal? + params[:only_personal].present? + end + + def only_project? + params[:only_project].present? end def prepared_union(queries) diff --git a/app/finders/tags_finder.rb b/app/finders/tags_finder.rb index 0ccbbdc1b87..6bc5419e704 100644 --- a/app/finders/tags_finder.rb +++ b/app/finders/tags_finder.rb @@ -5,11 +5,36 @@ class TagsFinder < GitRefsFinder super(repository, params) end - def execute - tags = repository.tags_sorted_by(sort) + def execute(gitaly_pagination: false) + tags = if gitaly_pagination + repository.tags_sorted_by(sort, pagination_params) + else + repository.tags_sorted_by(sort) + end - [by_search(tags), nil] - rescue Gitlab::Git::CommandError => e - [[], e] + by_search(tags) + + rescue ArgumentError => e + raise Gitlab::Git::InvalidPageToken, "Invalid page token: #{page_token}" if e.message.include?('page token') + + raise + end + + def total + repository.tag_count + end + + private + + def per_page + params[:per_page].presence + end + + def page_token + "#{Gitlab::Git::TAG_REF_PREFIX}#{@params[:page_token]}" if params[:page_token] + end + + def pagination_params + { limit: per_page, page_token: page_token } end end -- cgit v1.2.3