diff options
author | GitLab Bot <gitlab-bot@gitlab.com> | 2020-09-19 01:45:44 +0000 |
---|---|---|
committer | GitLab Bot <gitlab-bot@gitlab.com> | 2020-09-19 01:45:44 +0000 |
commit | 85dc423f7090da0a52c73eb66faf22ddb20efff9 (patch) | |
tree | 9160f299afd8c80c038f08e1545be119f5e3f1e1 /app/finders | |
parent | 15c2c8c66dbe422588e5411eee7e68f1fa440bb8 (diff) | |
download | gitlab-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.rb | 55 | ||||
-rw-r--r-- | app/finders/concerns/finder_methods.rb | 11 | ||||
-rw-r--r-- | app/finders/concerns/merged_at_filter.rb | 12 | ||||
-rw-r--r-- | app/finders/design_management/designs_finder.rb | 6 | ||||
-rw-r--r-- | app/finders/feature_flags_finder.rb | 44 | ||||
-rw-r--r-- | app/finders/fork_targets_finder.rb | 6 | ||||
-rw-r--r-- | app/finders/group_members_finder.rb | 4 | ||||
-rw-r--r-- | app/finders/issuable_finder.rb | 30 | ||||
-rw-r--r-- | app/finders/issues_finder.rb | 4 | ||||
-rw-r--r-- | app/finders/labels_finder.rb | 9 | ||||
-rw-r--r-- | app/finders/members_finder.rb | 4 | ||||
-rw-r--r-- | app/finders/merge_requests_finder.rb | 4 | ||||
-rw-r--r-- | app/finders/packages/group_packages_finder.rb | 3 | ||||
-rw-r--r-- | app/finders/packages/package_finder.rb | 3 | ||||
-rw-r--r-- | app/finders/packages/packages_finder.rb | 7 | ||||
-rw-r--r-- | app/finders/projects_finder.rb | 1 | ||||
-rw-r--r-- | app/finders/user_group_notification_settings_finder.rb | 48 | ||||
-rw-r--r-- | app/finders/users_finder.rb | 8 |
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] |