diff options
Diffstat (limited to 'app/finders')
20 files changed, 172 insertions, 95 deletions
diff --git a/app/finders/ci/auth_job_finder.rb b/app/finders/ci/auth_job_finder.rb index aee7dd16341..d207a522aa8 100644 --- a/app/finders/ci/auth_job_finder.rb +++ b/app/finders/ci/auth_job_finder.rb @@ -15,6 +15,10 @@ module Ci next unless job validate_job!(job) + + if job.user && Feature.enabled?(:ci_scoped_job_token, job.project, default_enabled: :yaml) + job.user.set_ci_job_token_scope!(job) + end end end diff --git a/app/finders/ci/pipelines_for_merge_request_finder.rb b/app/finders/ci/pipelines_for_merge_request_finder.rb index be65b1f6b3c..6c5038128f8 100644 --- a/app/finders/ci/pipelines_for_merge_request_finder.rb +++ b/app/finders/ci/pipelines_for_merge_request_finder.rb @@ -48,7 +48,7 @@ module Ci # rubocop: disable CodeReuse/ActiveRecord def pipelines_using_cte sha_relation = merge_request.all_commits.select(:sha) - sha_relation = sha_relation.distinct if Feature.enabled?(:use_distinct_in_shas_cte) + sha_relation = sha_relation.distinct if Feature.enabled?(:use_distinct_in_shas_cte, default_enabled: :yaml) cte = Gitlab::SQL::CTE.new(:shas, sha_relation) diff --git a/app/finders/ci/runners_finder.rb b/app/finders/ci/runners_finder.rb index 60dd977ff94..7ad51361efd 100644 --- a/app/finders/ci/runners_finder.rb +++ b/app/finders/ci/runners_finder.rb @@ -4,6 +4,9 @@ module Ci class RunnersFinder < UnionFinder include Gitlab::Allowable + ALLOWED_SORTS = %w[contacted_asc contacted_desc created_at_asc created_at_desc created_date].freeze + DEFAULT_SORT = 'created_at_desc' + def initialize(current_user:, group: nil, params:) @params = params @group = group @@ -24,11 +27,7 @@ module Ci end def sort_key - if @params[:sort] == 'contacted_asc' - 'contacted_asc' - else - 'created_date' - end + ALLOWED_SORTS.include?(@params[:sort]) ? @params[:sort] : DEFAULT_SORT end private diff --git a/app/finders/concerns/packages/finder_helper.rb b/app/finders/concerns/packages/finder_helper.rb index f0ad998cadb..d2784a1d270 100644 --- a/app/finders/concerns/packages/finder_helper.rb +++ b/app/finders/concerns/packages/finder_helper.rb @@ -29,7 +29,7 @@ module Packages end def projects_visible_to_reporters(user, within_group:) - if user.is_a?(DeployToken) && Feature.enabled?(:packages_finder_helper_deploy_token, default_enabled: :yaml) + if user.is_a?(DeployToken) user.accessible_projects else within_group.all_projects diff --git a/app/finders/deployments_finder.rb b/app/finders/deployments_finder.rb index acce038dba6..bb9d204ab73 100644 --- a/app/finders/deployments_finder.rb +++ b/app/finders/deployments_finder.rb @@ -136,7 +136,7 @@ class DeploymentsFinder # Implicitly enforce the ordering when filtered by `updated_at` column for performance optimization. # See https://gitlab.com/gitlab-org/gitlab/-/issues/325627#note_552417509. # We remove this in https://gitlab.com/gitlab-org/gitlab/-/issues/328500. - if filter_by_updated_at? && implicitly_enforce_ordering_for_updated_at_filter? + if filter_by_updated_at? sort_params.replace('updated_at' => sort_direction) end @@ -170,15 +170,6 @@ class DeploymentsFinder params[:order_by].to_s == 'finished_at' end - def implicitly_enforce_ordering_for_updated_at_filter? - return false unless params[:project].present? - - ::Feature.enabled?( - :deployments_finder_implicitly_enforce_ordering_for_updated_at_filter, - params[:project], - default_enabled: :yaml) - end - # rubocop: disable CodeReuse/ActiveRecord def preload_associations(scope) scope.includes( diff --git a/app/finders/feature_flags_finder.rb b/app/finders/feature_flags_finder.rb index 7b38841970d..20b18c62f7a 100644 --- a/app/finders/feature_flags_finder.rb +++ b/app/finders/feature_flags_finder.rb @@ -24,7 +24,7 @@ class FeatureFlagsFinder private def feature_flags - project.operations_feature_flags + project.operations_feature_flags.new_version_only end def by_scope(items) diff --git a/app/finders/issuable_finder.rb b/app/finders/issuable_finder.rb index d1885b5ae08..086dadcf5b7 100644 --- a/app/finders/issuable_finder.rb +++ b/app/finders/issuable_finder.rb @@ -50,7 +50,7 @@ class IssuableFinder attr_reader :original_params attr_writer :parent - delegate(*%i[assignee milestones], to: :params) + delegate(*%i[milestones], to: :params) class << self def scalar_params @@ -148,7 +148,6 @@ class IssuableFinder # Negates all params found in `negatable_params` def filter_negated_items(items) - items = by_negated_assignee(items) items = by_negated_label(items) items = by_negated_milestone(items) items = by_negated_release(items) @@ -365,32 +364,21 @@ class IssuableFinder def by_author(items) Issuables::AuthorFilter.new( - items, params: original_params, or_filters_enabled: or_filters_enabled? - ).filter + ).filter(items) end def by_assignee(items) - if params.filter_by_no_assignee? - items.unassigned - elsif params.filter_by_any_assignee? - items.assigned - elsif params.assignee - items.assigned_to(params.assignee) - elsif params.assignee_id? || params.assignee_username? # assignee not found - items.none - else - items - end + assignee_filter.filter(items) end - def by_negated_assignee(items) - # We want CE users to be able to say "Issues not assigned to either PersonA nor PersonB" - if not_params.assignees.present? - items.not_assigned_to(not_params.assignees) - else - items + def assignee_filter + strong_memoize(:assignee_filter) do + Issuables::AssigneeFilter.new( + params: original_params, + or_filters_enabled: or_filters_enabled? + ) end end diff --git a/app/finders/issuable_finder/params.rb b/app/finders/issuable_finder/params.rb index a62210ceac5..51e12dde51d 100644 --- a/app/finders/issuable_finder/params.rb +++ b/app/finders/issuable_finder/params.rb @@ -27,14 +27,6 @@ class IssuableFinder params.present? end - def filter_by_no_assignee? - params[:assignee_id].to_s.downcase == FILTER_NONE - end - - def filter_by_any_assignee? - params[:assignee_id].to_s.downcase == FILTER_ANY - end - def filter_by_no_label? downcased = label_names.map(&:downcase) @@ -156,24 +148,6 @@ class IssuableFinder end end - # rubocop: disable CodeReuse/ActiveRecord - def assignees - strong_memoize(:assignees) do - if assignee_id? - User.where(id: params[:assignee_id]) - elsif assignee_username? - User.where(username: params[:assignee_username]) - else - User.none - end - end - end - # rubocop: enable CodeReuse/ActiveRecord - - def assignee - assignees.first - end - def label_names if labels? params[:label_name].is_a?(String) ? params[:label_name].split(',') : params[:label_name] diff --git a/app/finders/issuables/assignee_filter.rb b/app/finders/issuables/assignee_filter.rb new file mode 100644 index 00000000000..2e58a6b34c9 --- /dev/null +++ b/app/finders/issuables/assignee_filter.rb @@ -0,0 +1,79 @@ +# frozen_string_literal: true + +module Issuables + class AssigneeFilter < BaseFilter + def filter(issuables) + filtered = by_assignee(issuables) + filtered = by_assignee_union(filtered) + by_negated_assignee(filtered) + end + + def includes_user?(user) + Array(params[:assignee_ids]).include?(user.id) || + Array(params[:assignee_id]).include?(user.id) || + Array(params[:assignee_username]).include?(user.username) + end + + private + + def by_assignee(issuables) + if filter_by_no_assignee? + issuables.unassigned + elsif filter_by_any_assignee? + issuables.assigned + elsif has_assignee_param?(params) + filter_by_assignees(issuables) + else + issuables + end + end + + def by_assignee_union(issuables) + return issuables unless or_filters_enabled? && has_assignee_param?(or_params) + + issuables.assigned_to(assignee_ids(or_params)) + end + + def by_negated_assignee(issuables) + return issuables unless has_assignee_param?(not_params) + + issuables.not_assigned_to(assignee_ids(not_params)) + end + + def filter_by_no_assignee? + params[:assignee_id].to_s.downcase == FILTER_NONE + end + + def filter_by_any_assignee? + params[:assignee_id].to_s.downcase == FILTER_ANY + end + + def filter_by_assignees(issuables) + assignee_ids = assignee_ids(params) + + return issuables.none if assignee_ids.blank? + + assignee_ids.each do |assignee_id| + issuables = issuables.assigned_to(assignee_id) + end + + issuables + end + + def has_assignee_param?(specific_params) + return if specific_params.nil? + + specific_params[:assignee_ids].present? || specific_params[:assignee_id].present? || specific_params[:assignee_username].present? + end + + def assignee_ids(specific_params) + if specific_params[:assignee_ids].present? + Array(specific_params[:assignee_ids]) + elsif specific_params[:assignee_id].present? + Array(specific_params[:assignee_id]) + elsif specific_params[:assignee_username].present? + User.by_username(specific_params[:assignee_username]).select(:id) + end + end + end +end diff --git a/app/finders/issuables/author_filter.rb b/app/finders/issuables/author_filter.rb index 522751a384e..f36daae553d 100644 --- a/app/finders/issuables/author_filter.rb +++ b/app/finders/issuables/author_filter.rb @@ -2,7 +2,7 @@ module Issuables class AuthorFilter < BaseFilter - def filter + def filter(issuables) filtered = by_author(issuables) filtered = by_author_union(filtered) by_negated_author(filtered) @@ -21,7 +21,7 @@ module Issuables end def by_author_union(issuables) - return issuables unless or_filters_enabled? && or_params&.fetch(:author_username).present? + return issuables unless or_filters_enabled? && or_params&.fetch(:author_username, false).present? issuables.authored(User.by_username(or_params[:author_username])) end diff --git a/app/finders/issuables/base_filter.rb b/app/finders/issuables/base_filter.rb index 6d1a3f96062..7c607e2d048 100644 --- a/app/finders/issuables/base_filter.rb +++ b/app/finders/issuables/base_filter.rb @@ -2,10 +2,12 @@ module Issuables class BaseFilter - attr_reader :issuables, :params + attr_reader :params - def initialize(issuables, params:, or_filters_enabled: false) - @issuables = issuables + FILTER_NONE = 'none' + FILTER_ANY = 'any' + + def initialize(params:, or_filters_enabled: false) @params = params @or_filters_enabled = or_filters_enabled end diff --git a/app/finders/issues_finder.rb b/app/finders/issues_finder.rb index eb9099fe256..40d6730d232 100644 --- a/app/finders/issues_finder.rb +++ b/app/finders/issues_finder.rb @@ -52,7 +52,7 @@ class IssuesFinder < IssuableFinder # can always see confidential issues assigned to them. This is just an # optimization since a very common usecase of this Finder is to load the # count of issues assigned to the user for the header bar. - return Issue.all if current_user && params.assignees.include?(current_user) + return Issue.all if current_user && assignee_filter.includes_user?(current_user) return Issue.where('issues.confidential IS NOT TRUE') if params.user_cannot_see_confidential_issues? diff --git a/app/finders/packages/group_or_project_package_finder.rb b/app/finders/packages/group_or_project_package_finder.rb index fb8bcfc7d42..5b5f70bf459 100644 --- a/app/finders/packages/group_or_project_package_finder.rb +++ b/app/finders/packages/group_or_project_package_finder.rb @@ -26,9 +26,9 @@ module Packages def base if project? - packages_for_project(@project_or_group) + project_packages elsif group? - packages_visible_to_user(@current_user, within_group: @project_or_group) + group_packages else ::Packages::Package.none end @@ -41,5 +41,13 @@ module Packages def group? @project_or_group.is_a?(::Group) end + + def project_packages + packages_for_project(@project_or_group) + end + + def group_packages + packages_visible_to_user(@current_user, within_group: @project_or_group) + end end end diff --git a/app/finders/packages/helm/package_files_finder.rb b/app/finders/packages/helm/package_files_finder.rb new file mode 100644 index 00000000000..74f9eaaca82 --- /dev/null +++ b/app/finders/packages/helm/package_files_finder.rb @@ -0,0 +1,26 @@ +# frozen_string_literal: true + +module Packages + module Helm + class PackageFilesFinder + def initialize(project, channel, params = {}) + @project = project + @channel = channel + @params = params + end + + def execute + package_files = Packages::PackageFile.for_helm_with_channel(@project, @channel).preload_helm_file_metadata + by_file_name(package_files) + end + + private + + def by_file_name(files) + return files unless @params[:file_name] + + files.with_file_name(@params[:file_name]) + end + end + end +end diff --git a/app/finders/packages/pypi/package_finder.rb b/app/finders/packages/pypi/package_finder.rb index 574e9770363..3a37e404b79 100644 --- a/app/finders/packages/pypi/package_finder.rb +++ b/app/finders/packages/pypi/package_finder.rb @@ -12,6 +12,16 @@ module Packages def packages base.pypi.has_version end + + def group_packages + # PyPI finds packages without checking permissions. + # The package download endpoint uses obfuscation to secure the file + # instead of authentication. This is behavior the PyPI package + # manager defines and is not something GitLab controls. + ::Packages::Package.for_projects( + @project_or_group.all_projects.select(:id) + ).installable + end end end end diff --git a/app/finders/pending_todos_finder.rb b/app/finders/pending_todos_finder.rb index d79a2340379..509370b49a8 100644 --- a/app/finders/pending_todos_finder.rb +++ b/app/finders/pending_todos_finder.rb @@ -26,6 +26,7 @@ class PendingTodosFinder todos = by_project(todos) todos = by_target_id(todos) todos = by_target_type(todos) + todos = by_discussion(todos) by_commit_id(todos) end @@ -60,4 +61,12 @@ class PendingTodosFinder todos end end + + def by_discussion(todos) + if (discussion = params[:discussion]) + todos.for_note(discussion.notes) + else + todos + end + end end diff --git a/app/finders/projects/serverless/functions_finder.rb b/app/finders/projects/serverless/functions_finder.rb index 13f84e0e3a5..f8ccea6b820 100644 --- a/app/finders/projects/serverless/functions_finder.rb +++ b/app/finders/projects/serverless/functions_finder.rb @@ -49,7 +49,7 @@ module Projects def has_prometheus?(environment_scope) finders_for_scope(environment_scope).any? do |finder| - finder.cluster.application_prometheus_available? + finder.cluster.integration_prometheus_available? end end diff --git a/app/finders/projects_finder.rb b/app/finders/projects_finder.rb index 272747a124e..582075efc4e 100644 --- a/app/finders/projects_finder.rb +++ b/app/finders/projects_finder.rb @@ -14,7 +14,8 @@ # starred: boolean # sort: string # visibility_level: int -# tags: string[] +# tag: string[] - deprecated, use 'topic' instead +# topic: string[] # personal: boolean # search: string # search_namespaces: boolean @@ -37,6 +38,8 @@ class ProjectsFinder < UnionFinder @params = params @current_user = current_user @project_ids_relation = project_ids_relation + + @params[:topic] ||= @params.delete(:tag) if @params[:tag].present? end def execute @@ -76,7 +79,7 @@ class ProjectsFinder < UnionFinder collection = by_starred(collection) collection = by_trending(collection) collection = by_visibility_level(collection) - collection = by_tags(collection) + collection = by_topics(collection) collection = by_search(collection) collection = by_archived(collection) collection = by_custom_attributes(collection) @@ -176,8 +179,8 @@ class ProjectsFinder < UnionFinder end # rubocop: enable CodeReuse/ActiveRecord - def by_tags(items) - params[:tag].present? ? items.tagged_with(params[:tag]) : items + def by_topics(items) + params[:topic].present? ? items.tagged_with(params[:topic]) : items end def by_search(items) diff --git a/app/finders/security/jobs_finder.rb b/app/finders/security/jobs_finder.rb index e2efb2e18c9..b8649520c20 100644 --- a/app/finders/security/jobs_finder.rb +++ b/app/finders/security/jobs_finder.rb @@ -15,7 +15,7 @@ module Security attr_reader :pipeline def self.allowed_job_types - # Example return: [:sast, :dast, :dependency_scanning, :container_scanning, :license_management, :coverage_fuzzing] + # Example return: [:sast, :dast, :dependency_scanning, :container_scanning, :license_scanning, :coverage_fuzzing] raise NotImplementedError, 'allowed_job_types must be overwritten to return an array of job types' end diff --git a/app/finders/template_finder.rb b/app/finders/template_finder.rb index 0f5622f2df0..b82b601541c 100644 --- a/app/finders/template_finder.rb +++ b/app/finders/template_finder.rb @@ -21,27 +21,11 @@ class TemplateFinder end end - # This is temporary and will be removed once we introduce group level inherited templates and - # remove the inherited_issuable_templates FF - def all_template_names_hash_or_array(project, issuable_type) - if project.inherited_issuable_templates_enabled? - all_template_names(project, issuable_type.pluralize) - else - all_template_names_array(project, issuable_type.pluralize) - end - end - def all_template_names(project, type) return {} if !VENDORED_TEMPLATES.key?(type.to_s) && type.to_s != 'licenses' build(type, project).template_names end - - # This is for issues and merge requests description templates only. - # This will be removed once we introduce group level inherited templates and remove the inherited_issuable_templates FF - def all_template_names_array(project, type) - all_template_names(project, type).values.flatten.select { |tmpl| tmpl[:project_id] == project.id }.compact.uniq - end end attr_reader :type, :project, :params |