Show members of parent groups on project members page

Signed-off-by: Dmitriy Zaporozhets <dmitriy.zaporozhets@gmail.com>
This commit is contained in:
Dmitriy Zaporozhets 2017-03-07 13:58:14 +02:00
parent 72e940df2c
commit 26f28f9654
5 changed files with 62 additions and 43 deletions

View file

@ -7,47 +7,18 @@ module Projects
@sort = params[:sort].presence || sort_value_name @sort = params[:sort].presence || sort_value_name
@group_links = @project.project_group_links @group_links = @project.project_group_links
@project_members = @project.project_members
@project_members = @project_members.non_invite unless can?(current_user, :admin_project, @project)
group = @project.group
# group links
@group_links = @project.project_group_links.all
@skip_groups = @group_links.pluck(:group_id) @skip_groups = @group_links.pluck(:group_id)
@skip_groups << @project.namespace_id unless @project.personal? @skip_groups << @project.namespace_id unless @project.personal?
if group @project_members = MembersFinder.new(@project, current_user).execute
# We need `.where.not(user_id: nil)` here otherwise when a group has an
# invitee, it would make the following query return 0 rows since a NULL
# user_id would be present in the subquery
# See http://stackoverflow.com/questions/129077/not-in-clause-and-null-values
group_members = MembersFinder.new(@project_members, group).execute(current_user)
end
if params[:search].present? if params[:search].present?
user_ids = @project.users.search(params[:search]).select(:id) @project_members = @project_members.joins(:user).merge(User.search(params[:search]))
@project_members = @project_members.where(user_id: user_ids) @group_links = @group_links.where(group_id: @project.invited_groups.search(params[:search]).select(:id))
if group_members
user_ids = group.users.search(params[:search]).select(:id)
group_members = group_members.where(user_id: user_ids)
end
@group_links = @project.project_group_links.where(group_id: @project.invited_groups.search(params[:search]).select(:id))
end end
wheres = ["members.id IN (#{@project_members.select(:id).to_sql})"] @project_members = @project_members.sort(@sort).page(params[:page])
wheres << "members.id IN (#{group_members.select(:id).to_sql})" if group_members
@project_members = Member.
where(wheres.join(' OR ')).
sort(@sort).
page(params[:page])
@requesters = AccessRequestsFinder.new(@project).execute(current_user) @requesters = AccessRequestsFinder.new(@project).execute(current_user)
@project_member = @project.project_members.new @project_member = @project.project_members.new
end end
end end

View file

@ -1,4 +1,4 @@
class GroupMembersFinder < Projects::ApplicationController class GroupMembersFinder
def initialize(group) def initialize(group)
@group = group @group = group
end end

View file

@ -1,13 +1,35 @@
class MembersFinder < Projects::ApplicationController class MembersFinder
def initialize(project_members, project_group) attr_reader :project, :current_user, :group
@project_members = project_members
@project_group = project_group def initialize(project, current_user)
@project = project
@current_user = current_user
@group = project.group
end end
def execute(current_user) def execute
non_null_user_ids = @project_members.where.not(user_id: nil).select(:user_id) project_members = project.project_members
group_members = @project_group.group_members.where.not(user_id: non_null_user_ids) project_members = project_members.non_invite unless can?(current_user, :admin_project, project)
group_members = group_members.non_invite unless can?(current_user, :admin_group, @project_group) wheres = ["members.id IN (#{project_members.select(:id).to_sql})"]
group_members
if group
# We need `.where.not(user_id: nil)` here otherwise when a group has an
# invitee, it would make the following query return 0 rows since a NULL
# user_id would be present in the subquery
# See http://stackoverflow.com/questions/129077/not-in-clause-and-null-values
non_null_user_ids = project_members.where.not(user_id: nil).select(:user_id)
group_members = GroupMembersFinder.new(group).execute
group_members = group_members.where.not(user_id: non_null_user_ids)
group_members = group_members.non_invite unless can?(current_user, :admin_group, group)
wheres << "members.id IN (#{group_members.select(:id).to_sql})"
end
Member.where(wheres.join(' OR '))
end
def can?(*args)
Ability.allowed?(*args)
end end
end end

View file

@ -0,0 +1,4 @@
---
title: Show members of parent groups on project members page
merge_request:
author:

View file

@ -0,0 +1,22 @@
require 'spec_helper'
describe MembersFinder, '#execute' do
let(:group) { create(:group) }
let(:nested_group) { create(:group, :access_requestable, parent: group) }
let(:project) { create(:project, namespace: nested_group) }
let(:user1) { create(:user) }
let(:user2) { create(:user) }
let(:user3) { create(:user) }
let(:user4) { create(:user) }
it 'returns members for project and parent groups' do
nested_group.request_access(user1)
member1 = group.add_master(user2)
member2 = nested_group.add_master(user3)
member3 = project.add_master(user4)
result = described_class.new(project, user2).execute
expect(result.to_a).to eq([member3, member2, member1])
end
end