Welcome to mirror list, hosted at ThFree Co, Russian Federation.

gitlab.com/gitlab-org/gitlab-foss.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGitLab Bot <gitlab-bot@gitlab.com>2023-08-18 13:50:51 +0300
committerGitLab Bot <gitlab-bot@gitlab.com>2023-08-18 13:50:51 +0300
commitdb384e6b19af03b4c3c82a5760d83a3fd79f7982 (patch)
tree34beaef37df5f47ccbcf5729d7583aae093cffa0 /app/finders
parent54fd7b1bad233e3944434da91d257fa7f63c3996 (diff)
Add latest changes from gitlab-org/gitlab@16-3-stable-eev16.3.0-rc42
Diffstat (limited to 'app/finders')
-rw-r--r--app/finders/abuse_reports_finder.rb60
-rw-r--r--app/finders/admin/abuse_report_labels_finder.rb33
-rw-r--r--app/finders/autocomplete/group_users_finder.rb87
-rw-r--r--app/finders/autocomplete/routes_finder.rb9
-rw-r--r--app/finders/autocomplete/users_finder.rb19
-rw-r--r--app/finders/deployments_finder.rb3
-rw-r--r--app/finders/group_descendants_finder.rb2
-rw-r--r--app/finders/group_members_finder.rb5
-rw-r--r--app/finders/group_projects_finder.rb16
-rw-r--r--app/finders/groups_finder.rb20
-rw-r--r--app/finders/issuable_finder/params.rb2
-rw-r--r--app/finders/issuables/assignee_filter.rb4
-rw-r--r--app/finders/issuables/author_filter.rb3
-rw-r--r--app/finders/issues_finder.rb1
-rw-r--r--app/finders/labels_finder.rb7
-rw-r--r--app/finders/merge_request_target_project_finder.rb5
-rw-r--r--app/finders/metrics/dashboards/annotations_finder.rb43
-rw-r--r--app/finders/metrics/users_starred_dashboards_finder.rb37
-rw-r--r--app/finders/packages/nuget/package_finder.rb32
-rw-r--r--app/finders/packages/pipelines_finder.rb22
-rw-r--r--app/finders/projects/ml/model_finder.rb9
-rw-r--r--app/finders/repositories/tree_finder.rb6
-rw-r--r--app/finders/snippets_finder.rb39
-rw-r--r--app/finders/work_items/namespace_work_items_finder.rb49
24 files changed, 361 insertions, 152 deletions
diff --git a/app/finders/abuse_reports_finder.rb b/app/finders/abuse_reports_finder.rb
index 6a6d0413194..43cebd16d92 100644
--- a/app/finders/abuse_reports_finder.rb
+++ b/app/finders/abuse_reports_finder.rb
@@ -3,9 +3,13 @@
class AbuseReportsFinder
attr_reader :params, :reports
- DEFAULT_STATUS_FILTER = 'open'
- DEFAULT_SORT = 'created_at_desc'
- ALLOWED_SORT = [DEFAULT_SORT, *%w[created_at_asc updated_at_desc updated_at_asc]].freeze
+ STATUS_OPEN = 'open'
+
+ DEFAULT_SORT_STATUS_CLOSED = 'created_at_desc'
+ ALLOWED_SORT = [DEFAULT_SORT_STATUS_CLOSED, *%w[created_at_asc updated_at_desc updated_at_asc]].freeze
+
+ DEFAULT_SORT_STATUS_OPEN = 'number_of_reports_desc'
+ SORT_BY_COUNT = [DEFAULT_SORT_STATUS_OPEN].freeze
def initialize(params = {})
@params = params
@@ -14,6 +18,7 @@ class AbuseReportsFinder
def execute
filter_reports
+ aggregate_reports
sort_reports
reports.with_users.page(params[:page])
@@ -22,20 +27,28 @@ class AbuseReportsFinder
private
def filter_reports
- filter_by_user_id
+ if Feature.disabled?(:abuse_reports_list)
+ filter_by_user_id
+ return
+ end
+ filter_by_status
filter_by_user
filter_by_reporter
- filter_by_status
filter_by_category
end
+ def filter_by_user_id
+ return unless params[:user_id].present?
+
+ @reports = @reports.by_user_id(params[:user_id])
+ end
+
def filter_by_status
- return unless Feature.enabled?(:abuse_reports_list)
return unless params[:status].present?
status = params[:status]
- status = DEFAULT_STATUS_FILTER unless status.in?(AbuseReport.statuses.keys)
+ status = STATUS_OPEN unless status.in?(AbuseReport.statuses.keys)
case status
when 'open'
@@ -69,10 +82,13 @@ class AbuseReportsFinder
@reports = @reports.by_reporter_id(user_id)
end
- def filter_by_user_id
- return unless params[:user_id].present?
+ def sort_key
+ sort_key = params[:sort]
- @reports = @reports.by_user_id(params[:user_id])
+ return sort_key if sort_key.in?(ALLOWED_SORT + SORT_BY_COUNT)
+ return DEFAULT_SORT_STATUS_OPEN if status_open?
+
+ DEFAULT_SORT_STATUS_CLOSED
end
def sort_reports
@@ -81,13 +97,31 @@ class AbuseReportsFinder
return
end
- sort_by = params[:sort]
- sort_by = DEFAULT_SORT unless sort_by.in?(ALLOWED_SORT)
+ # let sub_query in aggregate_reports do the sorting if sorting by number of reports
+ return if sort_key.in?(SORT_BY_COUNT)
- @reports = @reports.order_by(sort_by)
+ @reports = @reports.order_by(sort_key)
end
def find_user_id(username)
User.by_username(username).pick(:id)
end
+
+ def status_open?
+ return unless Feature.enabled?(:abuse_reports_list) && params[:status].present?
+
+ status = params[:status]
+ status = STATUS_OPEN unless status.in?(AbuseReport.statuses.keys)
+
+ status == STATUS_OPEN
+ end
+
+ def aggregate_reports
+ if status_open?
+ sort_by_count = sort_key.in?(SORT_BY_COUNT)
+ @reports = @reports.aggregated_by_user_and_category(sort_by_count)
+ end
+
+ @reports
+ end
end
diff --git a/app/finders/admin/abuse_report_labels_finder.rb b/app/finders/admin/abuse_report_labels_finder.rb
new file mode 100644
index 00000000000..f8ca40f77b2
--- /dev/null
+++ b/app/finders/admin/abuse_report_labels_finder.rb
@@ -0,0 +1,33 @@
+# frozen_string_literal: true
+
+module Admin
+ class AbuseReportLabelsFinder
+ def initialize(current_user, params = {})
+ @current_user = current_user
+ @params = params
+ end
+
+ def execute
+ return Admin::AbuseReportLabel.none unless current_user&.can_admin_all_resources?
+
+ items = Admin::AbuseReportLabel.all
+ items = by_search(items)
+
+ items.order(title: :asc) # rubocop: disable CodeReuse/ActiveRecord
+ end
+
+ private
+
+ attr_reader :current_user, :params
+
+ def by_search(labels)
+ return labels unless search_term
+
+ labels.search(search_term)
+ end
+
+ def search_term
+ params[:search_term]
+ end
+ end
+end
diff --git a/app/finders/autocomplete/group_users_finder.rb b/app/finders/autocomplete/group_users_finder.rb
new file mode 100644
index 00000000000..b24f3f7f032
--- /dev/null
+++ b/app/finders/autocomplete/group_users_finder.rb
@@ -0,0 +1,87 @@
+# frozen_string_literal: true
+
+# This finder returns all users that are related to a given group because:
+# 1. They are members of the group, its sub-groups, or its ancestor groups
+# 2. They are members of a group that is invited to the group, its sub-groups, or its ancestors
+# 3. They are members of a project that belongs to the group
+# 4. They are members of a group that is invited to the group's descendant projects
+#
+# These users are not necessarily members of the given group and may not have access to the group
+# so this should not be used for access control
+module Autocomplete
+ class GroupUsersFinder
+ include Gitlab::Utils::StrongMemoize
+
+ def initialize(group:)
+ @group = group
+ end
+
+ def execute
+ members = Member
+ .with(group_hierarchy_cte.to_arel) # rubocop:disable CodeReuse/ActiveRecord
+ .with(descendant_projects_cte.to_arel) # rubocop:disable CodeReuse/ActiveRecord
+ .from_union(member_relations, remove_duplicates: false)
+
+ User
+ .id_in(members.select(:user_id))
+ .allow_cross_joins_across_databases(url: "https://gitlab.com/gitlab-org/gitlab/-/issues/420387")
+ end
+
+ private
+
+ def member_relations
+ [
+ members_from_group_hierarchy.select(:user_id),
+ members_from_hierarchy_group_shares.select(:user_id),
+ members_from_descendant_projects.select(:user_id),
+ members_from_descendant_project_shares.select(:user_id)
+ ]
+ end
+
+ def members_from_group_hierarchy
+ GroupMember
+ .with_source_id(group_hierarchy_ids)
+ .without_invites_and_requests
+ end
+
+ def members_from_hierarchy_group_shares
+ invited_groups = GroupGroupLink.for_shared_groups(group_hierarchy_ids).select(:shared_with_group_id)
+
+ GroupMember
+ .with_source_id(invited_groups)
+ .without_invites_and_requests
+ end
+
+ def members_from_descendant_projects
+ ProjectMember
+ .with_source_id(descendant_project_ids)
+ .without_invites_and_requests
+ end
+
+ def members_from_descendant_project_shares
+ descendant_project_invited_groups = ProjectGroupLink.for_projects(descendant_project_ids).select(:group_id)
+
+ GroupMember
+ .with_source_id(descendant_project_invited_groups)
+ .without_invites_and_requests
+ end
+
+ def group_hierarchy_cte
+ Gitlab::SQL::CTE.new(:group_hierarchy, @group.self_and_hierarchy.select(:id))
+ end
+ strong_memoize_attr :group_hierarchy_cte
+
+ def group_hierarchy_ids
+ Namespace.from(group_hierarchy_cte.table).select(:id) # rubocop:disable CodeReuse/ActiveRecord
+ end
+
+ def descendant_projects_cte
+ Gitlab::SQL::CTE.new(:descendant_projects, @group.all_projects.select(:id))
+ end
+ strong_memoize_attr :descendant_projects_cte
+
+ def descendant_project_ids
+ Project.from(descendant_projects_cte.table).select(:id) # rubocop:disable CodeReuse/ActiveRecord
+ end
+ end
+end
diff --git a/app/finders/autocomplete/routes_finder.rb b/app/finders/autocomplete/routes_finder.rb
index ecede0c1c1c..ed807d3a295 100644
--- a/app/finders/autocomplete/routes_finder.rb
+++ b/app/finders/autocomplete/routes_finder.rb
@@ -19,6 +19,7 @@ module Autocomplete
.for_routable(routables)
.sort_by_path_length
.fuzzy_search(@search, [:path])
+ .allow_cross_joins_across_databases(url: 'https://gitlab.com/gitlab-org/gitlab/-/issues/421843')
.limit(LIMIT) # rubocop: disable CodeReuse/ActiveRecord
end
@@ -30,9 +31,11 @@ module Autocomplete
class NamespacesOnly < self
def routables
- return Namespace.without_project_namespaces if current_user.can_admin_all_resources?
-
- current_user.namespaces
+ if current_user.can_admin_all_resources?
+ Namespace.without_project_namespaces
+ else
+ current_user.namespaces
+ end.allow_cross_joins_across_databases(url: "https://gitlab.com/gitlab-org/gitlab/-/issues/420046")
end
end
diff --git a/app/finders/autocomplete/users_finder.rb b/app/finders/autocomplete/users_finder.rb
index 7ecf5c98ac0..e7a24cde2bd 100644
--- a/app/finders/autocomplete/users_finder.rb
+++ b/app/finders/autocomplete/users_finder.rb
@@ -10,21 +10,21 @@ module Autocomplete
# ensure good performance.
LIMIT = 20
- attr_reader :current_user, :project, :group, :search, :skip_users,
+ attr_reader :current_user, :project, :group, :search,
:author_id, :todo_filter, :todo_state_filter,
- :filter_by_current_user, :states
+ :filter_by_current_user, :states, :push_code
def initialize(params:, current_user:, project:, group:)
@current_user = current_user
@project = project
@group = group
@search = params[:search]
- @skip_users = params[:skip_users]
@author_id = params[:author_id]
@todo_filter = params[:todo_filter]
@todo_state_filter = params[:todo_state_filter]
@filter_by_current_user = params[:current_user]
@states = params[:states] || ['active']
+ @push_code = params[:push_code]
end
def execute
@@ -39,6 +39,8 @@ module Autocomplete
end
end
+ items = filter_users_by_push_ability(items)
+
items.uniq.tap do |unique_items|
preload_associations(unique_items)
end
@@ -65,7 +67,6 @@ module Autocomplete
.non_internal
.reorder_by_name
.optionally_search(search, use_minimum_char_limit: use_minimum_char_limit)
- .where_not_in(skip_users)
.limit_to_todo_authors(
user: current_user,
with_todos: todo_filter,
@@ -88,7 +89,7 @@ module Autocomplete
if project
project.authorized_users.union_with_user(author_id)
elsif group
- group.users_with_parents
+ ::Autocomplete::GroupUsersFinder.new(group: group).execute # rubocop: disable CodeReuse/Finder
elsif current_user
User.all
else
@@ -96,6 +97,12 @@ module Autocomplete
end
end
+ def filter_users_by_push_ability(items)
+ return items unless project && push_code.present?
+
+ items.select { |user| user.can?(:push_code, project) }
+ end
+
# rubocop: disable CodeReuse/ActiveRecord
def preload_associations(items)
ActiveRecord::Associations::Preloader.new(records: items, associations: :status).call
@@ -109,5 +116,3 @@ module Autocomplete
end
end
end
-
-Autocomplete::UsersFinder.prepend_mod_with('Autocomplete::UsersFinder')
diff --git a/app/finders/deployments_finder.rb b/app/finders/deployments_finder.rb
index 800158dfd0a..9881cb3fc74 100644
--- a/app/finders/deployments_finder.rb
+++ b/app/finders/deployments_finder.rb
@@ -25,7 +25,7 @@ class DeploymentsFinder
# performant with the other filtering/sorting parameters.
# The composed query could be significantly slower when the filtering and sorting columns are different.
# See https://gitlab.com/gitlab-org/gitlab/-/issues/325627 for example.
- ALLOWED_SORT_VALUES = %w[id iid created_at updated_at ref finished_at].freeze
+ ALLOWED_SORT_VALUES = %w[id iid created_at updated_at finished_at].freeze
DEFAULT_SORT_VALUE = 'id'
ALLOWED_SORT_DIRECTIONS = %w[asc desc].freeze
@@ -128,7 +128,6 @@ class DeploymentsFinder
def build_sort_params
order_by = ALLOWED_SORT_VALUES.include?(params[:order_by]) ? params[:order_by] : DEFAULT_SORT_VALUE
- order_by = DEFAULT_SORT_VALUE if order_by == 'ref' && Feature.enabled?(:remove_deployments_api_ref_sort)
order_direction = ALLOWED_SORT_DIRECTIONS.include?(params[:sort]) ? params[:sort] : DEFAULT_SORT_DIRECTION
{ order_by => order_direction }
diff --git a/app/finders/group_descendants_finder.rb b/app/finders/group_descendants_finder.rb
index 72ab30cf567..3e31c7a2bb2 100644
--- a/app/finders/group_descendants_finder.rb
+++ b/app/finders/group_descendants_finder.rb
@@ -141,7 +141,7 @@ class GroupDescendantsFinder
# rubocop: disable CodeReuse/Finder
def direct_child_projects
- GroupProjectsFinder.new(group: parent_group, current_user: current_user, params: params, options: { only_owned: true })
+ GroupProjectsFinder.new(group: parent_group, current_user: current_user, params: params, options: { exclude_shared: true })
.execute
end
# rubocop: enable CodeReuse/Finder
diff --git a/app/finders/group_members_finder.rb b/app/finders/group_members_finder.rb
index 1025e0ebc9b..639db58b00d 100644
--- a/app/finders/group_members_finder.rb
+++ b/app/finders/group_members_finder.rb
@@ -86,11 +86,6 @@ class GroupMembersFinder < UnionFinder
end
def members_of_groups(groups, shared_from_groups)
- if Feature.disabled?(:members_with_shared_group_access, @group.root_ancestor)
- groups << shared_from_groups unless shared_from_groups.nil?
- return GroupMember.non_request.of_groups(find_union(groups, Group))
- end
-
members = GroupMember.non_request.of_groups(find_union(groups, Group))
return members if shared_from_groups.nil?
diff --git a/app/finders/group_projects_finder.rb b/app/finders/group_projects_finder.rb
index db8a0f14fbc..21341797910 100644
--- a/app/finders/group_projects_finder.rb
+++ b/app/finders/group_projects_finder.rb
@@ -9,8 +9,10 @@
# project_ids_relation: int[] - project ids to use
# group
# options:
-# only_owned: boolean
+# exclude_shared: boolean
+# When true, only projects within the group are included in the result.
# only_shared: boolean
+# When true, only projects arising from group-project shares are included in the result.
# limit: integer
# include_subgroups: boolean
# include_ancestor_groups: boolean
@@ -63,10 +65,10 @@ class GroupProjectsFinder < ProjectsFinder
projects =
if only_shared?
[shared_projects]
- elsif only_owned?
- [owned_projects]
+ elsif exclude_shared?
+ [projects_within_group]
else
- [owned_projects, shared_projects]
+ [projects_within_group, shared_projects]
end
projects.map! do |project_relation|
@@ -104,8 +106,8 @@ class GroupProjectsFinder < ProjectsFinder
end
end
- def only_owned?
- options.fetch(:only_owned, false)
+ def exclude_shared?
+ options.fetch(:exclude_shared, false)
end
def owned_projects?
@@ -126,7 +128,7 @@ class GroupProjectsFinder < ProjectsFinder
options.fetch(:include_ancestor_groups, false)
end
- def owned_projects
+ def projects_within_group
return group.projects unless include_subgroups? || include_ancestor_groups?
union_relations = []
diff --git a/app/finders/groups_finder.rb b/app/finders/groups_finder.rb
index 63f7616884f..074eb9add0f 100644
--- a/app/finders/groups_finder.rb
+++ b/app/finders/groups_finder.rb
@@ -32,14 +32,8 @@ class GroupsFinder < UnionFinder
end
def execute
- items = all_groups.map do |item|
- item = by_parent(item)
- item = by_custom_attributes(item)
- item = filter_group_ids(item)
- item = exclude_group_ids(item)
- item = by_search(item)
-
- item
+ items = all_groups.map do |groups|
+ filter_groups(groups)
end
find_union(items, Group).with_route.order_id_desc
@@ -49,6 +43,14 @@ class GroupsFinder < UnionFinder
attr_reader :current_user, :params
+ def filter_groups(groups)
+ groups = by_parent(groups)
+ groups = by_custom_attributes(groups)
+ groups = filter_group_ids(groups)
+ groups = exclude_group_ids(groups)
+ by_search(groups)
+ end
+
def all_groups
return [owned_groups] if params[:owned]
return [groups_with_min_access_level] if min_access_level?
@@ -147,3 +149,5 @@ class GroupsFinder < UnionFinder
groups
end
end
+
+GroupsFinder.prepend_mod_with('GroupsFinder')
diff --git a/app/finders/issuable_finder/params.rb b/app/finders/issuable_finder/params.rb
index e59c2224594..bc136848dd5 100644
--- a/app/finders/issuable_finder/params.rb
+++ b/app/finders/issuable_finder/params.rb
@@ -133,7 +133,7 @@ class IssuableFinder
def projects
strong_memoize(:projects) do
- next [project] if project?
+ next Array.wrap(project) if project?
projects =
if current_user && params[:authorized_only].presence && !current_user_related?
diff --git a/app/finders/issuables/assignee_filter.rb b/app/finders/issuables/assignee_filter.rb
index c97fdffd32e..5efcd5aa23e 100644
--- a/app/finders/issuables/assignee_filter.rb
+++ b/app/finders/issuables/assignee_filter.rb
@@ -5,8 +5,6 @@ module Issuables
def filter(issuables)
filtered = by_assignee(issuables)
filtered = by_assignee_union(filtered)
- # Cross Joins Fails tests in bin/rspec spec/requests/api/graphql/boards/board_list_issues_query_spec.rb
- filtered = filtered.allow_cross_joins_across_databases(url: "https://gitlab.com/gitlab-org/gitlab/-/issues/417462")
by_negated_assignee(filtered)
end
@@ -74,7 +72,7 @@ module Issuables
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)
+ User.by_username(specific_params[:assignee_username]).pluck_primary_key
end
end
end
diff --git a/app/finders/issuables/author_filter.rb b/app/finders/issuables/author_filter.rb
index f36daae553d..7707bf51f18 100644
--- a/app/finders/issuables/author_filter.rb
+++ b/app/finders/issuables/author_filter.rb
@@ -15,6 +15,7 @@ module Issuables
issuables.authored(params[:author_id])
elsif params[:author_username].present?
issuables.authored(User.by_username(params[:author_username]))
+ .allow_cross_joins_across_databases(url: "https://gitlab.com/gitlab-org/gitlab/-/issues/419221")
else
issuables
end
@@ -24,6 +25,7 @@ module Issuables
return issuables unless or_filters_enabled? && or_params&.fetch(:author_username, false).present?
issuables.authored(User.by_username(or_params[:author_username]))
+ .allow_cross_joins_across_databases(url: "https://gitlab.com/gitlab-org/gitlab/-/issues/419221")
end
def by_negated_author(issuables)
@@ -33,6 +35,7 @@ module Issuables
issuables.not_authored(not_params[:author_id])
elsif not_params[:author_username].present?
issuables.not_authored(User.by_username(not_params[:author_username]))
+ .allow_cross_joins_across_databases(url: "https://gitlab.com/gitlab-org/gitlab/-/issues/419221")
else
issuables
end
diff --git a/app/finders/issues_finder.rb b/app/finders/issues_finder.rb
index bd81f06f93b..0ba93a76342 100644
--- a/app/finders/issues_finder.rb
+++ b/app/finders/issues_finder.rb
@@ -72,6 +72,7 @@ class IssuesFinder < IssuableFinder
OR EXISTS (:authorizations)))',
user_id: current_user.id,
authorizations: current_user.authorizations_for_projects(min_access_level: CONFIDENTIAL_ACCESS_LEVEL, related_project_column: "issues.project_id"))
+ .allow_cross_joins_across_databases(url: 'https://gitlab.com/gitlab-org/gitlab/-/issues/422045')
end
# rubocop: enable CodeReuse/ActiveRecord
diff --git a/app/finders/labels_finder.rb b/app/finders/labels_finder.rb
index b1387f2a104..1bf2e3b71e4 100644
--- a/app/finders/labels_finder.rb
+++ b/app/finders/labels_finder.rb
@@ -24,6 +24,7 @@ class LabelsFinder < UnionFinder
items = with_title(items)
items = by_subscription(items)
items = by_search(items)
+ items = by_locked_labels(items)
items = items.with_preloaded_container if @preload_parent_association
sort(items)
@@ -94,6 +95,12 @@ class LabelsFinder < UnionFinder
labels.optionally_subscribed_by(subscriber_id)
end
+ def by_locked_labels(items)
+ return items unless params[:locked_labels]
+
+ items.with_lock_on_merge
+ end
+
def subscriber_id
current_user&.id if subscribed?
end
diff --git a/app/finders/merge_request_target_project_finder.rb b/app/finders/merge_request_target_project_finder.rb
index ea1aa6d2e9e..ee340b79ed0 100644
--- a/app/finders/merge_request_target_project_finder.rb
+++ b/app/finders/merge_request_target_project_finder.rb
@@ -14,7 +14,8 @@ class MergeRequestTargetProjectFinder
def execute(search: nil, include_routes: false)
if source_project.fork_network
items = include_routes ? projects.inc_routes : projects
- by_search(items, search)
+ by_search(items, search).allow_cross_joins_across_databases(
+ url: "https://gitlab.com/gitlab-org/gitlab/-/issues/420046")
else
Project.id_in(source_project.id)
end
@@ -39,3 +40,5 @@ class MergeRequestTargetProjectFinder
end
# rubocop: enable CodeReuse/ActiveRecord
end
+
+MergeRequestTargetProjectFinder.prepend_mod_with("MergeRequestTargetProjectFinder")
diff --git a/app/finders/metrics/dashboards/annotations_finder.rb b/app/finders/metrics/dashboards/annotations_finder.rb
deleted file mode 100644
index e97704738ea..00000000000
--- a/app/finders/metrics/dashboards/annotations_finder.rb
+++ /dev/null
@@ -1,43 +0,0 @@
-# frozen_string_literal: true
-
-module Metrics
- module Dashboards
- class AnnotationsFinder
- def initialize(dashboard:, params:)
- @dashboard = dashboard
- @params = params
- end
-
- def execute
- if dashboard.environment
- apply_filters_to(annotations_for_environment)
- else
- Metrics::Dashboard::Annotation.none
- end
- end
-
- private
-
- attr_reader :dashboard, :params
-
- def apply_filters_to(annotations)
- annotations = annotations.after(params[:from]) if params[:from].present?
- annotations = annotations.before(params[:to]) if params[:to].present? && valid_timespan_boundaries?
-
- by_dashboard(annotations)
- end
-
- def annotations_for_environment
- dashboard.environment.metrics_dashboard_annotations
- end
-
- def by_dashboard(annotations)
- annotations.for_dashboard(dashboard.path)
- end
-
- def valid_timespan_boundaries?
- params[:from].blank? || params[:to] >= params[:from]
- end
- end
- end
-end
diff --git a/app/finders/metrics/users_starred_dashboards_finder.rb b/app/finders/metrics/users_starred_dashboards_finder.rb
deleted file mode 100644
index 2ef706c1b11..00000000000
--- a/app/finders/metrics/users_starred_dashboards_finder.rb
+++ /dev/null
@@ -1,37 +0,0 @@
-# frozen_string_literal: true
-
-module Metrics
- class UsersStarredDashboardsFinder
- def initialize(user:, project:, params: {})
- @user = user
- @project = project
- @params = params
- end
-
- def execute
- return ::Metrics::UsersStarredDashboard.none unless Ability.allowed?(user, :read_metrics_user_starred_dashboard, project)
-
- items = starred_dashboards
- items = by_project(items)
- by_dashboard(items)
- end
-
- private
-
- attr_reader :user, :project, :params
-
- def by_project(items)
- items.for_project(project)
- end
-
- def by_dashboard(items)
- return items unless params[:dashboard_path]
-
- items.merge(starred_dashboards.for_project_dashboard(project, params[:dashboard_path]))
- end
-
- def starred_dashboards
- @starred_dashboards ||= user.metrics_users_starred_dashboards
- end
- end
-end
diff --git a/app/finders/packages/nuget/package_finder.rb b/app/finders/packages/nuget/package_finder.rb
index 23345f29198..064698d3c37 100644
--- a/app/finders/packages/nuget/package_finder.rb
+++ b/app/finders/packages/nuget/package_finder.rb
@@ -4,19 +4,43 @@ module Packages
module Nuget
class PackageFinder < ::Packages::GroupOrProjectPackageFinder
MAX_PACKAGES_COUNT = 300
+ FORCE_NORMALIZATION_CLIENT_VERSION = '>= 3'
def execute
+ return ::Packages::Package.none unless @params[:package_name].present?
+
packages.limit_recent(@params[:limit] || MAX_PACKAGES_COUNT)
end
private
def packages
- result = base.nuget
- .has_version
- .with_name_like(@params[:package_name])
- result = result.with_case_insensitive_version(@params[:package_version]) if @params[:package_version].present?
+ result = find_by_name
+ find_by_version(result)
+ end
+
+ def find_by_name
+ base
+ .nuget
+ .has_version
+ .with_case_insensitive_name(@params[:package_name])
+ end
+
+ def find_by_version(result)
+ return result if @params[:package_version].blank?
+
result
+ .with_nuget_version_or_normalized_version(
+ @params[:package_version],
+ with_normalized: Feature.enabled?(:nuget_normalized_version, @project_or_group) &&
+ client_forces_normalized_version?
+ )
+ end
+
+ def client_forces_normalized_version?
+ return true if @params[:client_version].blank?
+
+ VersionSorter.compare(FORCE_NORMALIZATION_CLIENT_VERSION, @params[:client_version]) <= 0
end
end
end
diff --git a/app/finders/packages/pipelines_finder.rb b/app/finders/packages/pipelines_finder.rb
new file mode 100644
index 00000000000..c814efbf176
--- /dev/null
+++ b/app/finders/packages/pipelines_finder.rb
@@ -0,0 +1,22 @@
+# frozen_string_literal: true
+
+module Packages
+ class PipelinesFinder
+ COLUMNS = %i[id iid project_id sha ref status source created_at updated_at user_id].freeze
+
+ def initialize(pipeline_ids)
+ @pipeline_ids = pipeline_ids
+ end
+
+ def execute
+ ::Ci::Pipeline
+ .id_in(pipeline_ids)
+ .select(COLUMNS)
+ .order_id_desc
+ end
+
+ private
+
+ attr_reader :pipeline_ids
+ end
+end
diff --git a/app/finders/projects/ml/model_finder.rb b/app/finders/projects/ml/model_finder.rb
index 9ef5dacb551..99c66f53de7 100644
--- a/app/finders/projects/ml/model_finder.rb
+++ b/app/finders/projects/ml/model_finder.rb
@@ -8,12 +8,9 @@ module Projects
end
def execute
- @project
- .packages
- .installable
- .ml_model
- .order_name_desc_version_desc
- .select_only_first_by_name
+ ::Ml::Model
+ .by_project(@project)
+ .including_latest_version
.limit(100) # This is a temporary limit before we add pagination
end
end
diff --git a/app/finders/repositories/tree_finder.rb b/app/finders/repositories/tree_finder.rb
index 231c1de1513..2a8971d4d86 100644
--- a/app/finders/repositories/tree_finder.rb
+++ b/app/finders/repositories/tree_finder.rb
@@ -13,7 +13,7 @@ module Repositories
def execute(gitaly_pagination: false)
raise CommitMissingError unless commit_exists?
- request_params = { recursive: recursive }
+ request_params = { recursive: recursive, rescue_not_found: rescue_not_found }
request_params[:pagination_params] = pagination_params if gitaly_pagination
repository.tree(commit.id, path, **request_params).sorted_entries
@@ -51,6 +51,10 @@ module Repositories
params[:recursive]
end
+ def rescue_not_found
+ params[:rescue_not_found]
+ end
+
def pagination_params
{
limit: params[:per_page] || Kaminari.config.default_per_page,
diff --git a/app/finders/snippets_finder.rb b/app/finders/snippets_finder.rb
index 9dd7e508c22..cb824aca33f 100644
--- a/app/finders/snippets_finder.rb
+++ b/app/finders/snippets_finder.rb
@@ -67,17 +67,30 @@ class SnippetsFinder < UnionFinder
return Snippet.none if project.nil? && params[:project].present?
return Snippet.none if project && !project.feature_available?(:snippets, current_user)
- items = init_collection
- items = by_ids(items)
- items = items.with_optional_visibility(visibility_from_scope)
- items = by_created_at(items)
-
- items.order_by(sort_param)
+ filter_snippets.order_by(sort_param)
end
private
- def init_collection
+ def filter_snippets
+ if return_all_available_and_permited?
+ snippets = all_snippets_for_admin
+ else
+ snippets = all_snippets
+ snippets = by_ids(snippets)
+ snippets = snippets.with_optional_visibility(visibility_from_scope)
+ end
+
+ by_created_at(snippets)
+ end
+
+ def return_all_available_and_permited?
+ # Currently limited to access_levels `admin` and `auditor`
+ # See policies/base_policy.rb files for specifics.
+ params[:all_available] && current_user&.can_read_all_resources?
+ end
+
+ def all_snippets
if explore?
snippets_for_explore
elsif only_personal?
@@ -121,6 +134,12 @@ class SnippetsFinder < UnionFinder
prepared_union(queries)
end
+ def all_snippets_for_admin
+ return Snippet.only_project_snippets if only_project?
+
+ Snippet.all
+ end
+
def snippets_for_a_single_project
Snippet.for_project_with_user(project, current_user)
end
@@ -182,10 +201,10 @@ class SnippetsFinder < UnionFinder
end
end
- def by_ids(items)
- return items unless params[:ids].present?
+ def by_ids(snippets)
+ return snippets unless params[:ids].present?
- items.id_in(params[:ids])
+ snippets.id_in(params[:ids])
end
def author
diff --git a/app/finders/work_items/namespace_work_items_finder.rb b/app/finders/work_items/namespace_work_items_finder.rb
new file mode 100644
index 00000000000..aad99d710b6
--- /dev/null
+++ b/app/finders/work_items/namespace_work_items_finder.rb
@@ -0,0 +1,49 @@
+# frozen_string_literal: true
+
+module WorkItems
+ class NamespaceWorkItemsFinder < WorkItemsFinder
+ def initialize(...)
+ super
+
+ self.parent_param = namespace
+ end
+
+ def execute
+ items = init_collection
+ items = by_namespace(items)
+
+ sort(items)
+ end
+
+ override :with_confidentiality_access_check
+ def with_confidentiality_access_check
+ return model_class.all if params.user_can_see_all_issuables?
+
+ # Only admins can see hidden issues, so for non-admins, we filter out any hidden issues
+ issues = model_class.without_hidden
+
+ return issues.all if params.user_can_see_all_confidential_issues?
+
+ return issues.public_only if params.user_cannot_see_confidential_issues?
+
+ issues.with_confidentiality_check(current_user)
+ end
+
+ private
+
+ def by_namespace(items)
+ if namespace.blank? || !Ability.allowed?(current_user, "read_#{namespace.to_ability_name}".to_sym, namespace)
+ return klass.none
+ end
+
+ items.in_namespaces(namespace)
+ end
+
+ def namespace
+ return if params[:namespace_id].blank?
+
+ params[:namespace_id].is_a?(Namespace) ? params[:namespace_id] : Namespace.find_by_id(params[:namespace_id])
+ end
+ strong_memoize_attr :namespace
+ end
+end