summaryrefslogtreecommitdiff
path: root/app/finders
diff options
context:
space:
mode:
authorGitLab Bot <gitlab-bot@gitlab.com>2020-09-19 01:45:44 +0000
committerGitLab Bot <gitlab-bot@gitlab.com>2020-09-19 01:45:44 +0000
commit85dc423f7090da0a52c73eb66faf22ddb20efff9 (patch)
tree9160f299afd8c80c038f08e1545be119f5e3f1e1 /app/finders
parent15c2c8c66dbe422588e5411eee7e68f1fa440bb8 (diff)
downloadgitlab-ce-85dc423f7090da0a52c73eb66faf22ddb20efff9.tar.gz
Add latest changes from gitlab-org/gitlab@13-4-stable-ee
Diffstat (limited to 'app/finders')
-rw-r--r--app/finders/ci/jobs_finder.rb55
-rw-r--r--app/finders/concerns/finder_methods.rb11
-rw-r--r--app/finders/concerns/merged_at_filter.rb12
-rw-r--r--app/finders/design_management/designs_finder.rb6
-rw-r--r--app/finders/feature_flags_finder.rb44
-rw-r--r--app/finders/fork_targets_finder.rb6
-rw-r--r--app/finders/group_members_finder.rb4
-rw-r--r--app/finders/issuable_finder.rb30
-rw-r--r--app/finders/issues_finder.rb4
-rw-r--r--app/finders/labels_finder.rb9
-rw-r--r--app/finders/members_finder.rb4
-rw-r--r--app/finders/merge_requests_finder.rb4
-rw-r--r--app/finders/packages/group_packages_finder.rb3
-rw-r--r--app/finders/packages/package_finder.rb3
-rw-r--r--app/finders/packages/packages_finder.rb7
-rw-r--r--app/finders/projects_finder.rb1
-rw-r--r--app/finders/user_group_notification_settings_finder.rb48
-rw-r--r--app/finders/users_finder.rb8
18 files changed, 218 insertions, 41 deletions
diff --git a/app/finders/ci/jobs_finder.rb b/app/finders/ci/jobs_finder.rb
index 2169bf8c53e..8515b77ec0b 100644
--- a/app/finders/ci/jobs_finder.rb
+++ b/app/finders/ci/jobs_finder.rb
@@ -4,31 +4,38 @@ module Ci
class JobsFinder
include Gitlab::Allowable
- def initialize(current_user:, project: nil, params: {})
+ def initialize(current_user:, pipeline: nil, project: nil, params: {}, type: ::Ci::Build)
+ @pipeline = pipeline
@current_user = current_user
@project = project
@params = params
+ @type = type
+ raise ArgumentError 'type must be a subclass of Ci::Processable' unless type < ::Ci::Processable
end
def execute
builds = init_collection.order_id_desc
filter_by_scope(builds)
rescue Gitlab::Access::AccessDeniedError
- Ci::Build.none
+ type.none
end
private
- attr_reader :current_user, :project, :params
+ attr_reader :current_user, :pipeline, :project, :params, :type
def init_collection
- project ? project_builds : all_builds
+ if Feature.enabled?(:ci_jobs_finder_refactor)
+ pipeline_jobs || project_jobs || all_jobs
+ else
+ project ? project_builds : all_jobs
+ end
end
- def all_builds
+ def all_jobs
raise Gitlab::Access::AccessDeniedError unless current_user&.admin?
- Ci::Build.all
+ type.all
end
def project_builds
@@ -37,7 +44,25 @@ module Ci
project.builds.relevant
end
+ def project_jobs
+ return unless project
+ raise Gitlab::Access::AccessDeniedError unless can?(current_user, :read_build, project)
+
+ jobs_by_type(project, type).relevant
+ end
+
+ def pipeline_jobs
+ return unless pipeline
+ raise Gitlab::Access::AccessDeniedError unless can?(current_user, :read_build, pipeline)
+
+ jobs_by_type(pipeline, type).latest
+ end
+
def filter_by_scope(builds)
+ if Feature.enabled?(:ci_jobs_finder_refactor)
+ return filter_by_statuses!(params[:scope], builds) if params[:scope].is_a?(Array)
+ end
+
case params[:scope]
when 'pending'
builds.pending.reverse_order
@@ -49,5 +74,23 @@ module Ci
builds
end
end
+
+ def filter_by_statuses!(statuses, builds)
+ unknown_statuses = params[:scope] - ::CommitStatus::AVAILABLE_STATUSES
+ raise ArgumentError, 'Scope contains invalid value(s)' unless unknown_statuses.empty?
+
+ builds.where(status: params[:scope]) # rubocop: disable CodeReuse/ActiveRecord
+ end
+
+ def jobs_by_type(relation, type)
+ case type.name
+ when ::Ci::Build.name
+ relation.builds
+ when ::Ci::Bridge.name
+ relation.bridges
+ else
+ raise ArgumentError, "finder does not support #{type} type"
+ end
+ end
end
end
diff --git a/app/finders/concerns/finder_methods.rb b/app/finders/concerns/finder_methods.rb
index 8de3276184d..622cbcf4928 100644
--- a/app/finders/concerns/finder_methods.rb
+++ b/app/finders/concerns/finder_methods.rb
@@ -30,7 +30,7 @@ module FinderMethods
def if_authorized(result)
# Return the result if the finder does not perform authorization checks.
# this is currently the case in the `MilestoneFinder`
- return result unless respond_to?(:current_user)
+ return result unless respond_to?(:current_user, true)
if can_read_object?(result)
result
@@ -44,9 +44,14 @@ module FinderMethods
# for Todos
return true unless DeclarativePolicy.has_policy?(object)
- model_name = object&.model_name || model.model_name
+ Ability.allowed?(current_user, :"read_#{to_ability_name(object)}", object)
+ end
+
+ def to_ability_name(object)
+ return object.to_ability_name if object.respond_to?(:to_ability_name)
- Ability.allowed?(current_user, :"read_#{model_name.singular}", object)
+ # Not all objects define `#to_ability_name`, so attempt to derive it:
+ object.model_name.singular
end
# This fetches the model from the `ActiveRecord::Relation` but does not
diff --git a/app/finders/concerns/merged_at_filter.rb b/app/finders/concerns/merged_at_filter.rb
index d2858ba2f88..581bcca3c25 100644
--- a/app/finders/concerns/merged_at_filter.rb
+++ b/app/finders/concerns/merged_at_filter.rb
@@ -3,7 +3,6 @@
module MergedAtFilter
private
- # rubocop: disable CodeReuse/ActiveRecord
def by_merged_at(items)
return items unless merged_after || merged_before
@@ -11,11 +10,8 @@ module MergedAtFilter
mr_metrics_scope = mr_metrics_scope.merged_after(merged_after) if merged_after.present?
mr_metrics_scope = mr_metrics_scope.merged_before(merged_before) if merged_before.present?
- scope = items.joins(:metrics).merge(mr_metrics_scope)
- scope = target_project_id_filter_on_metrics(scope) if Feature.enabled?(:improved_mr_merged_at_queries)
- scope
+ items.join_metrics.merge(mr_metrics_scope)
end
- # rubocop: enable CodeReuse/ActiveRecord
def merged_after
params[:merged_after]
@@ -24,10 +20,4 @@ module MergedAtFilter
def merged_before
params[:merged_before]
end
-
- # rubocop: disable CodeReuse/ActiveRecord
- def target_project_id_filter_on_metrics(scope)
- scope.where(MergeRequest.arel_table[:target_project_id].eq(MergeRequest::Metrics.arel_table[:target_project_id]))
- end
- # rubocop: enable CodeReuse/ActiveRecord
end
diff --git a/app/finders/design_management/designs_finder.rb b/app/finders/design_management/designs_finder.rb
index d9732f6b6f4..857b828dc47 100644
--- a/app/finders/design_management/designs_finder.rb
+++ b/app/finders/design_management/designs_finder.rb
@@ -3,6 +3,7 @@
module DesignManagement
class DesignsFinder
include Gitlab::Allowable
+ include FinderMethods
# Params:
# ids: integer[]
@@ -21,10 +22,7 @@ module DesignManagement
items = by_visible_at_version(items)
items = by_filename(items)
items = by_id(items)
-
- # TODO: We don't need to pass the project anymore after the feature flag is removed
- # https://gitlab.com/gitlab-org/gitlab/-/issues/34382
- items.ordered(issue.project)
+ items.ordered
end
private
diff --git a/app/finders/feature_flags_finder.rb b/app/finders/feature_flags_finder.rb
new file mode 100644
index 00000000000..9cb3bf7fa23
--- /dev/null
+++ b/app/finders/feature_flags_finder.rb
@@ -0,0 +1,44 @@
+# frozen_string_literal: true
+
+class FeatureFlagsFinder
+ attr_reader :project, :params, :current_user
+
+ def initialize(project, current_user, params = {})
+ @project = project
+ @current_user = current_user
+ @params = params
+ end
+
+ def execute(preload: true)
+ unless Ability.allowed?(current_user, :read_feature_flag, project)
+ return Operations::FeatureFlag.none
+ end
+
+ items = feature_flags
+ items = by_scope(items)
+
+ items = items.preload_relations if preload
+ items.ordered
+ end
+
+ private
+
+ def feature_flags
+ if Feature.enabled?(:feature_flags_new_version, project, default_enabled: true)
+ project.operations_feature_flags
+ else
+ project.operations_feature_flags.legacy_flag
+ end
+ end
+
+ def by_scope(items)
+ case params[:scope]
+ when 'enabled'
+ items.enabled
+ when 'disabled'
+ items.disabled
+ else
+ items
+ end
+ end
+end
diff --git a/app/finders/fork_targets_finder.rb b/app/finders/fork_targets_finder.rb
index 7a08273fa0d..719c244a207 100644
--- a/app/finders/fork_targets_finder.rb
+++ b/app/finders/fork_targets_finder.rb
@@ -7,8 +7,10 @@ class ForkTargetsFinder
end
# rubocop: disable CodeReuse/ActiveRecord
- def execute
- ::Namespace.where(id: user.manageable_namespaces).sort_by_type
+ def execute(options = {})
+ return ::Namespace.where(id: user.manageable_namespaces).sort_by_type unless options[:only_groups]
+
+ ::Group.where(id: user.manageable_groups)
end
# rubocop: enable CodeReuse/ActiveRecord
diff --git a/app/finders/group_members_finder.rb b/app/finders/group_members_finder.rb
index a4b00588368..ce0d52ad97a 100644
--- a/app/finders/group_members_finder.rb
+++ b/app/finders/group_members_finder.rb
@@ -27,7 +27,7 @@ class GroupMembersFinder < UnionFinder
relations << group_members if include_relations.include?(:direct)
if include_relations.include?(:inherited) && group.parent
- parents_members = GroupMember.non_request
+ parents_members = GroupMember.non_request.non_minimal_access
.where(source_id: group.ancestors.select(:id))
.where.not(user_id: group.users.select(:id))
@@ -35,7 +35,7 @@ class GroupMembersFinder < UnionFinder
end
if include_relations.include?(:descendants)
- descendant_members = GroupMember.non_request
+ descendant_members = GroupMember.non_request.non_minimal_access
.where(source_id: group.descendants.select(:id))
.where.not(user_id: group.users.select(:id))
diff --git a/app/finders/issuable_finder.rb b/app/finders/issuable_finder.rb
index 5cdc22fd873..f13dc8c2451 100644
--- a/app/finders/issuable_finder.rb
+++ b/app/finders/issuable_finder.rb
@@ -37,12 +37,14 @@ class IssuableFinder
include FinderMethods
include CreatedAtFilter
include Gitlab::Utils::StrongMemoize
+ prepend OptimizedIssuableLabelFilter
requires_cross_project_access unless: -> { params.project? }
NEGATABLE_PARAMS_HELPER_KEYS = %i[project_id scope status include_subgroups].freeze
attr_accessor :current_user, :params
+ attr_writer :parent
delegate(*%i[assignee milestones], to: :params)
@@ -103,8 +105,8 @@ class IssuableFinder
items = filter_negated_items(items)
# This has to be last as we use a CTE as an optimization fence
- # for counts by passing the force_cte param and enabling the
- # attempt_group_search_optimizations feature flag
+ # for counts by passing the force_cte param and passing the
+ # attempt_group_search_optimizations param
# https://www.postgresql.org/docs/current/static/queries-with.html
items = by_search(items)
@@ -203,8 +205,26 @@ class IssuableFinder
end
end
+ def parent_param=(obj)
+ @parent = obj
+ params[parent_param] = parent if parent
+ end
+
+ def parent_param
+ case parent
+ when Project
+ :project_id
+ when Group
+ :group_id
+ else
+ raise "Unexpected parent: #{parent.class}"
+ end
+ end
+
private
+ attr_reader :parent
+
def not_params
strong_memoize(:not_params) do
params_class.new(params[:not].dup, current_user, klass).tap do |not_params|
@@ -229,13 +249,11 @@ class IssuableFinder
end
def attempt_group_search_optimizations?
- params[:attempt_group_search_optimizations] &&
- Feature.enabled?(:attempt_group_search_optimizations, default_enabled: true)
+ params[:attempt_group_search_optimizations]
end
def attempt_project_search_optimizations?
- params[:attempt_project_search_optimizations] &&
- Feature.enabled?(:attempt_project_search_optimizations, default_enabled: true)
+ params[:attempt_project_search_optimizations]
end
def count_key(value)
diff --git a/app/finders/issues_finder.rb b/app/finders/issues_finder.rb
index bbb624f543b..32be5bee0db 100644
--- a/app/finders/issues_finder.rb
+++ b/app/finders/issues_finder.rb
@@ -8,7 +8,7 @@
# current_user - which user use
# params:
# scope: 'created_by_me' or 'assigned_to_me' or 'all'
-# state: 'open' or 'closed' or 'all'
+# state: 'opened' or 'closed' or 'all'
# group_id: integer
# project_id: integer
# milestone_title: string
@@ -41,7 +41,7 @@ class IssuesFinder < IssuableFinder
# rubocop: enable CodeReuse/ActiveRecord
def params_class
- IssuesFinder::Params
+ self.class.const_get(:Params, false)
end
# rubocop: disable CodeReuse/ActiveRecord
diff --git a/app/finders/labels_finder.rb b/app/finders/labels_finder.rb
index e726772fba4..4358cf249f7 100644
--- a/app/finders/labels_finder.rb
+++ b/app/finders/labels_finder.rb
@@ -172,7 +172,14 @@ class LabelsFinder < UnionFinder
ProjectsFinder.new(params: { non_archived: true }, current_user: current_user).execute # rubocop: disable CodeReuse/Finder
end
- @projects = @projects.in_namespace(group.id) if group?
+ if group?
+ @projects = if params[:include_subgroups]
+ @projects.in_namespace(group.self_and_descendants.select(:id))
+ else
+ @projects.in_namespace(group.id)
+ end
+ end
+
@projects = @projects.where(id: params[:project_ids]) if projects?
@projects = @projects.reorder(nil)
diff --git a/app/finders/members_finder.rb b/app/finders/members_finder.rb
index ce9137f91bb..013ed03a789 100644
--- a/app/finders/members_finder.rb
+++ b/app/finders/members_finder.rb
@@ -63,7 +63,7 @@ class MembersFinder
def direct_group_members(include_descendants)
requested_relations = [:inherited, :direct]
requested_relations << :descendants if include_descendants
- GroupMembersFinder.new(group).execute(include_relations: requested_relations).non_invite # rubocop: disable CodeReuse/Finder
+ GroupMembersFinder.new(group).execute(include_relations: requested_relations).non_invite.non_minimal_access # rubocop: disable CodeReuse/Finder
end
def project_invited_groups_members
@@ -73,7 +73,7 @@ class MembersFinder
.public_or_visible_to_user(current_user)
.select(:id)
- GroupMember.with_source_id(invited_groups_ids_including_ancestors)
+ GroupMember.with_source_id(invited_groups_ids_including_ancestors).non_minimal_access
end
def distinct_union_of_members(union_members)
diff --git a/app/finders/merge_requests_finder.rb b/app/finders/merge_requests_finder.rb
index b70d0b7a06a..37da29b32ff 100644
--- a/app/finders/merge_requests_finder.rb
+++ b/app/finders/merge_requests_finder.rb
@@ -110,7 +110,9 @@ class MergeRequestsFinder < IssuableFinder
.or(table[:title].matches('WIP %'))
.or(table[:title].matches('[WIP]%'))
- return items unless Feature.enabled?(:merge_request_draft_filter)
+ # Let's keep this FF around until https://gitlab.com/gitlab-org/gitlab/-/issues/232999
+ # is implemented
+ return items unless Feature.enabled?(:merge_request_draft_filter, default_enabled: true)
items
.or(table[:title].matches('Draft - %'))
diff --git a/app/finders/packages/group_packages_finder.rb b/app/finders/packages/group_packages_finder.rb
index ffc8c35fbcc..8b948bb056d 100644
--- a/app/finders/packages/group_packages_finder.rb
+++ b/app/finders/packages/group_packages_finder.rb
@@ -22,6 +22,9 @@ module Packages
def packages_for_group_projects
packages = ::Packages::Package
+ .including_build_info
+ .including_project_route
+ .including_tags
.for_projects(group_projects_visible_to_current_user)
.processed
.has_version
diff --git a/app/finders/packages/package_finder.rb b/app/finders/packages/package_finder.rb
index 0e911491da2..f1874b77845 100644
--- a/app/finders/packages/package_finder.rb
+++ b/app/finders/packages/package_finder.rb
@@ -9,6 +9,9 @@ module Packages
def execute
@project
.packages
+ .including_build_info
+ .including_project_route
+ .including_tags
.processed
.find(@package_id)
end
diff --git a/app/finders/packages/packages_finder.rb b/app/finders/packages/packages_finder.rb
index c533cb266a2..519e8bf9c34 100644
--- a/app/finders/packages/packages_finder.rb
+++ b/app/finders/packages/packages_finder.rb
@@ -13,7 +13,12 @@ module Packages
end
def execute
- packages = project.packages.processed.has_version
+ packages = project.packages
+ .including_build_info
+ .including_project_route
+ .including_tags
+ .processed
+ .has_version
packages = filter_by_package_type(packages)
packages = filter_by_package_name(packages)
packages = order_packages(packages)
diff --git a/app/finders/projects_finder.rb b/app/finders/projects_finder.rb
index 7c7cd87a7c1..471029c1ef9 100644
--- a/app/finders/projects_finder.rb
+++ b/app/finders/projects_finder.rb
@@ -24,6 +24,7 @@
# last_activity_after: datetime
# last_activity_before: datetime
# repository_storage: string
+# without_deleted: boolean
#
class ProjectsFinder < UnionFinder
include CustomAttributesFilter
diff --git a/app/finders/user_group_notification_settings_finder.rb b/app/finders/user_group_notification_settings_finder.rb
new file mode 100644
index 00000000000..a6f6769116f
--- /dev/null
+++ b/app/finders/user_group_notification_settings_finder.rb
@@ -0,0 +1,48 @@
+# frozen_string_literal: true
+
+class UserGroupNotificationSettingsFinder
+ def initialize(user, groups)
+ @user = user
+ @groups = groups
+ end
+
+ def execute
+ # rubocop: disable CodeReuse/ActiveRecord
+ groups_with_ancestors = Gitlab::ObjectHierarchy.new(Group.where(id: groups.select(:id))).base_and_ancestors
+ # rubocop: enable CodeReuse/ActiveRecord
+
+ @loaded_groups_with_ancestors = groups_with_ancestors.index_by(&:id)
+ @loaded_notification_settings = user.notification_settings_for_groups(groups_with_ancestors).preload_source_route.index_by(&:source_id)
+
+ groups.map do |group|
+ find_notification_setting_for(group)
+ end
+ end
+
+ private
+
+ attr_reader :user, :groups, :loaded_groups_with_ancestors, :loaded_notification_settings
+
+ def find_notification_setting_for(group)
+ return loaded_notification_settings[group.id] if loaded_notification_settings[group.id]
+ return user.notification_settings.build(source: group) if group.parent_id.nil?
+
+ parent_setting = loaded_notification_settings[group.parent_id]
+
+ return user.notification_settings.build(source: group) unless parent_setting
+
+ if should_copy?(parent_setting)
+ user.notification_settings.build(source: group) do |ns|
+ ns.assign_attributes(parent_setting.slice(*NotificationSetting.allowed_fields))
+ end
+ else
+ find_notification_setting_for(loaded_groups_with_ancestors[group.parent_id])
+ end
+ end
+
+ def should_copy?(parent_setting)
+ return false unless parent_setting
+
+ parent_setting.level != NotificationSetting.levels[:global] || parent_setting.notification_email.present?
+ end
+end
diff --git a/app/finders/users_finder.rb b/app/finders/users_finder.rb
index f87e0c67604..cc94536bf79 100644
--- a/app/finders/users_finder.rb
+++ b/app/finders/users_finder.rb
@@ -17,6 +17,7 @@
# without_projects: boolean
# sort: string
# id: integer
+# non_internal: boolean
#
class UsersFinder
include CreatedAtFilter
@@ -42,6 +43,7 @@ class UsersFinder
users = by_created_at(users)
users = by_without_projects(users)
users = by_custom_attributes(users)
+ users = by_non_internal(users)
order(users)
end
@@ -112,6 +114,12 @@ class UsersFinder
users.without_projects
end
+ def by_non_internal(users)
+ return users unless params[:non_internal]
+
+ users.non_internal
+ end
+
# rubocop: disable CodeReuse/ActiveRecord
def order(users)
return users unless params[:sort]