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:
Diffstat (limited to 'app/finders/group_members_finder.rb')
-rw-r--r--app/finders/group_members_finder.rb61
1 files changed, 54 insertions, 7 deletions
diff --git a/app/finders/group_members_finder.rb b/app/finders/group_members_finder.rb
index 47ed623b252..1025e0ebc9b 100644
--- a/app/finders/group_members_finder.rb
+++ b/app/finders/group_members_finder.rb
@@ -30,7 +30,11 @@ class GroupMembersFinder < UnionFinder
def execute(include_relations: DEFAULT_RELATIONS)
groups = groups_by_relations(include_relations)
- members = all_group_members(groups).distinct_on_user_with_max_access_level
+ shared_from_groups = if include_relations&.include?(:shared_from_groups)
+ Group.shared_into_ancestors(group).public_or_visible_to_user(user)
+ end
+
+ members = all_group_members(groups, shared_from_groups).distinct_on_user_with_max_access_level
filter_members(members)
end
@@ -47,9 +51,8 @@ class GroupMembersFinder < UnionFinder
related_groups << Group.by_id(group.id) if include_relations&.include?(:direct)
related_groups << group.ancestors if include_relations&.include?(:inherited)
related_groups << group.descendants if include_relations&.include?(:descendants)
- related_groups << Group.shared_into_ancestors(group).public_or_visible_to_user(user) if include_relations&.include?(:shared_from_groups)
- find_union(related_groups, Group)
+ related_groups
end
def filter_members(members)
@@ -64,6 +67,7 @@ class GroupMembersFinder < UnionFinder
members = members.by_access_level(params[:access_levels])
end
+ members = filter_by_user_type(members)
members = apply_additional_filters(members)
by_created_at(members)
@@ -77,12 +81,49 @@ class GroupMembersFinder < UnionFinder
group.members
end
- def all_group_members(groups)
- members_of_groups(groups).non_minimal_access
+ def all_group_members(groups, shared_from_groups)
+ members_of_groups(groups, shared_from_groups).non_minimal_access
+ 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?
+
+ shared_members = GroupMember.non_request.of_groups(shared_from_groups)
+ select_attributes = GroupMember.attribute_names
+ members_shared_with_group_access = members_shared_with_group_access(shared_members, select_attributes)
+
+ # `members` and `members_shared_with_group_access` should have even select values
+ find_union([members.select(select_attributes), members_shared_with_group_access], GroupMember)
+ end
+
+ def members_shared_with_group_access(shared_members, select_attributes)
+ group_group_link_table = GroupGroupLink.arel_table
+ group_member_table = GroupMember.arel_table
+
+ member_columns = select_attributes.map do |column_name|
+ if column_name == 'access_level'
+ args = [group_group_link_table[:group_access], group_member_table[:access_level]]
+ smallest_value_arel(args, 'access_level')
+ else
+ group_member_table[column_name]
+ end
+ end
+
+ # rubocop:disable CodeReuse/ActiveRecord
+ shared_members
+ .joins("LEFT OUTER JOIN group_group_links ON members.source_id = group_group_links.shared_with_group_id")
+ .select(member_columns)
+ # rubocop:enable CodeReuse/ActiveRecord
end
- def members_of_groups(groups)
- GroupMember.non_request.of_groups(groups)
+ def smallest_value_arel(args, column_alias)
+ Arel::Nodes::As.new(Arel::Nodes::NamedFunction.new('LEAST', args), Arel::Nodes::SqlLiteral.new(column_alias))
end
def check_relation_arguments!(include_relations)
@@ -91,6 +132,12 @@ class GroupMembersFinder < UnionFinder
end
end
+ def filter_by_user_type(members)
+ return members unless params[:user_type] && can_manage_members
+
+ members.filter_by_user_type(params[:user_type])
+ end
+
def apply_additional_filters(members)
# overridden in EE to include additional filtering conditions.
members