diff options
Diffstat (limited to 'app/finders')
-rw-r--r-- | app/finders/group_labels_finder.rb | 29 | ||||
-rw-r--r-- | app/finders/group_members_finder.rb | 28 | ||||
-rw-r--r-- | app/finders/groups_finder.rb | 12 | ||||
-rw-r--r-- | app/finders/merge_requests/by_approvals_finder.rb | 93 | ||||
-rw-r--r-- | app/finders/merge_requests_finder.rb | 16 | ||||
-rw-r--r-- | app/finders/packages/generic/package_finder.rb | 22 |
6 files changed, 160 insertions, 40 deletions
diff --git a/app/finders/group_labels_finder.rb b/app/finders/group_labels_finder.rb deleted file mode 100644 index a668a0f0fae..00000000000 --- a/app/finders/group_labels_finder.rb +++ /dev/null @@ -1,29 +0,0 @@ -# frozen_string_literal: true - -class GroupLabelsFinder - attr_reader :current_user, :group, :params - - def initialize(current_user, group, params = {}) - @current_user = current_user - @group = group - @params = params - end - - def execute - group.labels - .optionally_subscribed_by(subscriber_id) - .optionally_search(params[:search]) - .order_by(params[:sort]) - .page(params[:page]) - end - - private - - def subscriber_id - current_user&.id if subscribed? - end - - def subscribed? - params[:subscribed] == 'true' - end -end diff --git a/app/finders/group_members_finder.rb b/app/finders/group_members_finder.rb index ce0d52ad97a..09283f061c0 100644 --- a/app/finders/group_members_finder.rb +++ b/app/finders/group_members_finder.rb @@ -17,9 +17,8 @@ class GroupMembersFinder < UnionFinder @params = params end - # rubocop: disable CodeReuse/ActiveRecord def execute(include_relations: [:inherited, :direct]) - group_members = group.members + group_members = group_members_list relations = [] return group_members if include_relations == [:direct] @@ -27,17 +26,13 @@ class GroupMembersFinder < UnionFinder relations << group_members if include_relations.include?(:direct) if include_relations.include?(:inherited) && group.parent - parents_members = GroupMember.non_request.non_minimal_access - .where(source_id: group.ancestors.select(:id)) - .where.not(user_id: group.users.select(:id)) + parents_members = relation_group_members(group.ancestors) relations << parents_members end if include_relations.include?(:descendants) - descendant_members = GroupMember.non_request.non_minimal_access - .where(source_id: group.descendants.select(:id)) - .where.not(user_id: group.users.select(:id)) + descendant_members = relation_group_members(group.descendants) relations << descendant_members end @@ -47,7 +42,6 @@ class GroupMembersFinder < UnionFinder members = find_union(relations, GroupMember) filter_members(members) end - # rubocop: enable CodeReuse/ActiveRecord private @@ -67,6 +61,22 @@ class GroupMembersFinder < UnionFinder def can_manage_members Ability.allowed?(user, :admin_group_member, group) end + + def group_members_list + group.members + end + + def relation_group_members(relation) + all_group_members(relation).non_minimal_access + end + + # rubocop: disable CodeReuse/ActiveRecord + def all_group_members(relation) + GroupMember.non_request + .where(source_id: relation.select(:id)) + .where.not(user_id: group.users.select(:id)) + end + # rubocop: enable CodeReuse/ActiveRecord end GroupMembersFinder.prepend_if_ee('EE::GroupMembersFinder') diff --git a/app/finders/groups_finder.rb b/app/finders/groups_finder.rb index 54715557399..4b6b2716c64 100644 --- a/app/finders/groups_finder.rb +++ b/app/finders/groups_finder.rb @@ -12,6 +12,8 @@ # all_available: boolean (defaults to true) # min_access_level: integer # exclude_group_ids: array of integers +# include_parent_descendants: boolean (defaults to false) - includes descendant groups when +# filtering by parent. The parent param must be present. # # Users with full private access can see all groups. The `owned` and `parent` # params can be used to restrict the groups that are returned. @@ -84,7 +86,11 @@ class GroupsFinder < UnionFinder def by_parent(groups) return groups unless params[:parent] - groups.where(parent: params[:parent]) + if include_parent_descendants? + groups.id_in(params[:parent].descendants) + else + groups.where(parent: params[:parent]) + end end # rubocop: enable CodeReuse/ActiveRecord @@ -100,6 +106,10 @@ class GroupsFinder < UnionFinder params.fetch(:all_available, true) end + def include_parent_descendants? + params.fetch(:include_parent_descendants, false) + end + def min_access_level? current_user && params[:min_access_level].present? end diff --git a/app/finders/merge_requests/by_approvals_finder.rb b/app/finders/merge_requests/by_approvals_finder.rb new file mode 100644 index 00000000000..e6ab1467f06 --- /dev/null +++ b/app/finders/merge_requests/by_approvals_finder.rb @@ -0,0 +1,93 @@ +# frozen_string_literal: true + +module MergeRequests + # Used to filter MergeRequest collections by approvers + class ByApprovalsFinder + attr_reader :usernames, :ids + + # We apply a limitation to the amount of elements that can be part of the filter condition + MAX_FILTER_ELEMENTS = 5 + + # Initialize the finder + # + # @param [Array<String>] usernames + # @param [Array<Integers>] ids + def initialize(usernames, ids) + # rubocop:disable CodeReuse/ActiveRecord + @usernames = Array(usernames).map(&:to_s).uniq.take(MAX_FILTER_ELEMENTS) + @ids = Array(ids).uniq.take(MAX_FILTER_ELEMENTS) + # rubocop:enable CodeReuse/ActiveRecord + end + + # Filter MergeRequest collections by approvers + # + # @param [ActiveRecord::Relation] items the activerecord relation + def execute(items) + if by_no_approvals? + without_approvals(items) + elsif by_any_approvals? + with_any_approvals(items) + elsif ids.present? + find_approved_by_ids(items) + elsif usernames.present? + find_approved_by_names(items) + else + items + end + end + + private + + # Is param using special condition: "None" ? + # + # @return [Boolean] whether special condition "None" is being used + def by_no_approvals? + includes_special_label?(IssuableFinder::Params::FILTER_NONE) + end + + # Is param using special condition: "Any" ? + # + # @return [Boolean] whether special condition "Any" is being used + def by_any_approvals? + includes_special_label?(IssuableFinder::Params::FILTER_ANY) + end + + # Check if we have the special label in ids or usernames field + # + # @param [String] label the special label + # @return [Boolean] whether ids or usernames includes the special label + def includes_special_label?(label) + ids.first.to_s.downcase == label || usernames.map(&:downcase).include?(label) + end + + # Merge Requests without any approval + # + # @param [ActiveRecord::Relation] items + def without_approvals(items) + items.without_approvals + end + + # Merge Requests with any number of approvals + # + # @param [ActiveRecord::Relation] items the activerecord relation + def with_any_approvals(items) + items.select_from_union([ + items.with_approvals + ]) + end + + # Merge Requests approved by given usernames + # + # @param [ActiveRecord::Relation] items the activerecord relation + def find_approved_by_names(items) + items.approved_by_users_with_usernames(*usernames) + end + + # Merge Requests approved by given user IDs + # + # @param [ActiveRecord::Relation] items the activerecord relation + def find_approved_by_ids(items) + items.approved_by_users_with_ids(*ids) + end + end +end diff --git a/app/finders/merge_requests_finder.rb b/app/finders/merge_requests_finder.rb index 37da29b32ff..7bdc98d2e3d 100644 --- a/app/finders/merge_requests_finder.rb +++ b/app/finders/merge_requests_finder.rb @@ -33,7 +33,11 @@ class MergeRequestsFinder < IssuableFinder include MergedAtFilter def self.scalar_params - @scalar_params ||= super + [:wip, :draft, :target_branch, :merged_after, :merged_before] + @scalar_params ||= super + [:wip, :draft, :target_branch, :merged_after, :merged_before, :approved_by_ids] + end + + def self.array_params + @array_params ||= super.merge(approved_by_usernames: []) end def klass @@ -47,6 +51,7 @@ class MergeRequestsFinder < IssuableFinder items = by_draft(items) items = by_target_branch(items) items = by_merged_at(items) + items = by_approvals(items) by_source_project_id(items) end @@ -131,6 +136,15 @@ class MergeRequestsFinder < IssuableFinder def deployment_id @deployment_id ||= params[:deployment_id].presence end + + # Filter by merge requests that had been approved by specific users + # rubocop: disable CodeReuse/Finder + def by_approvals(items) + MergeRequests::ByApprovalsFinder + .new(params[:approved_by_usernames], params[:approved_by_ids]) + .execute(items) + end + # rubocop: enable CodeReuse/Finder end MergeRequestsFinder.prepend_if_ee('EE::MergeRequestsFinder') diff --git a/app/finders/packages/generic/package_finder.rb b/app/finders/packages/generic/package_finder.rb new file mode 100644 index 00000000000..3a260e11fa3 --- /dev/null +++ b/app/finders/packages/generic/package_finder.rb @@ -0,0 +1,22 @@ +# frozen_string_literal: true + +module Packages + module Generic + class PackageFinder + def initialize(project) + @project = project + end + + def execute!(package_name, package_version) + project + .packages + .generic + .by_name_and_version!(package_name, package_version) + end + + private + + attr_reader :project + end + end +end |