Skip to content
Snippets Groups Projects
Commit bd78f573 authored by Rémy Coutable's avatar Rémy Coutable
Browse files

Exclude requesters from Project#members, Group#members and User#members


And create new Project#requesters, Group#requesters scopes.

Signed-off-by: default avatarRémy Coutable <remy@rymai.me>
parent 557ca2b3
No related branches found
No related tags found
No related merge requests found
Showing
with 78 additions and 60 deletions
Loading
Loading
@@ -10,6 +10,7 @@ class Admin::GroupsController < Admin::ApplicationController
 
def show
@members = @group.members.order("access_level DESC").page(params[:members_page])
@requesters = @group.requesters
@projects = @group.projects.page(params[:projects_page])
end
 
Loading
Loading
Loading
Loading
@@ -20,7 +20,8 @@ class Admin::ProjectsController < Admin::ApplicationController
@group_members = @group.members.order("access_level DESC").page(params[:group_members_page])
end
 
@project_members = @project.project_members.page(params[:project_members_page])
@project_members = @project.members.page(params[:project_members_page])
@requesters = @project.requesters
end
 
def transfer
Loading
Loading
Loading
Loading
@@ -10,7 +10,7 @@ module MembershipActions
end
 
def approve_access_request
@member = membershipable.members.request.find(params[:id])
@member = membershipable.requesters.find(params[:id])
 
return render_403 unless can?(current_user, action_member_permission(:update, @member), @member)
 
Loading
Loading
@@ -20,7 +20,8 @@ module MembershipActions
end
 
def leave
@member = membershipable.members.find_by(user_id: current_user)
@member = membershipable.members.find_by(user_id: current_user) ||
membershipable.requesters.find_by(user_id: current_user)
Members::DestroyService.new(@member, current_user).execute
 
source_type = @member.real_source_type.humanize(capitalize: false)
Loading
Loading
Loading
Loading
@@ -7,7 +7,7 @@ class Groups::GroupMembersController < Groups::ApplicationController
def index
@project = @group.projects.find(params[:project_id]) if params[:project_id]
@members = @group.group_members
@members = @members.non_pending unless can?(current_user, :admin_group, @group)
@members = @members.non_invite unless can?(current_user, :admin_group, @group)
 
if params[:search].present?
users = @group.users.search(params[:search]).to_a
Loading
Loading
@@ -15,6 +15,7 @@ class Groups::GroupMembersController < Groups::ApplicationController
end
 
@members = @members.order('access_level DESC').page(params[:page]).per(50)
@requesters = @group.requesters if can?(current_user, :admin_group, @group)
 
@group_member = @group.group_members.new
end
Loading
Loading
@@ -34,7 +35,8 @@ class Groups::GroupMembersController < Groups::ApplicationController
end
 
def destroy
@group_member = @group.group_members.find(params[:id])
@group_member = @group.members.find_by(id: params[:id]) ||
@group.requesters.find_by(id: params[:id])
 
Members::DestroyService.new(@group_member, current_user).execute
 
Loading
Loading
Loading
Loading
@@ -6,7 +6,7 @@ class Projects::ProjectMembersController < Projects::ApplicationController
 
def index
@project_members = @project.project_members
@project_members = @project_members.non_pending unless can?(current_user, :admin_project, @project)
@project_members = @project_members.non_invite unless can?(current_user, :admin_project, @project)
 
if params[:search].present?
users = @project.users.search(params[:search]).to_a
Loading
Loading
@@ -19,7 +19,7 @@ class Projects::ProjectMembersController < Projects::ApplicationController
 
if @group
@group_members = @group.group_members
@group_members = @group_members.non_pending unless can?(current_user, :admin_group, @group)
@group_members = @group_members.non_invite unless can?(current_user, :admin_group, @group)
 
if params[:search].present?
users = @group.users.search(params[:search]).to_a
Loading
Loading
@@ -29,6 +29,8 @@ class Projects::ProjectMembersController < Projects::ApplicationController
@group_members = @group_members.order('access_level DESC')
end
 
@requesters = @project.requesters if can?(current_user, :admin_project, @project)
@project_member = @project.project_members.new
@project_group_links = @project.project_group_links
end
Loading
Loading
@@ -48,7 +50,8 @@ class Projects::ProjectMembersController < Projects::ApplicationController
end
 
def destroy
@project_member = @project.project_members.find(params[:id])
@project_member = @project.members.find_by(id: params[:id]) ||
@project.requesters.find_by(id: params[:id])
 
Members::DestroyService.new(@project_member, current_user).execute
 
Loading
Loading
Loading
Loading
@@ -12,6 +12,17 @@ module MembersHelper
can?(current_user, action_member_permission(:admin, member), member.source)
end
 
def can_see_request_access_button?(source)
source_parent = source.respond_to?(:group) && source.group
return false if source_parent && source.group.members.exists?(user_id: current_user.id)
return false if source_parent && source.group.requesters.exists?(user_id: current_user.id)
return false if source.members.exists?(user_id: current_user.id)
return true if source.requesters.exists?(user_id: current_user.id)
true
end
def remove_member_message(member, user: nil)
user = current_user if defined?(current_user)
 
Loading
Loading
Loading
Loading
@@ -6,15 +6,16 @@ class Group < Namespace
include AccessRequestable
include Referable
 
has_many :group_members, dependent: :destroy, as: :source, class_name: 'GroupMember'
has_many :group_members, -> { where(requested_at: nil) }, dependent: :destroy, as: :source, class_name: 'GroupMember'
alias_method :members, :group_members
has_many :users, -> { where(members: { requested_at: nil }) }, through: :group_members
has_many :users, through: :group_members
has_many :owners,
-> { where(members: { requested_at: nil, access_level: Gitlab::Access::OWNER }) },
-> { where(members: { access_level: Gitlab::Access::OWNER }) },
through: :group_members,
source: :user
 
has_many :requesters, -> { where.not(requested_at: nil) }, dependent: :destroy, as: :source, class_name: 'GroupMember'
has_many :project_group_links, dependent: :destroy
has_many :shared_projects, through: :project_group_links, source: :project
has_many :notification_settings, dependent: :destroy, as: :source
Loading
Loading
Loading
Loading
@@ -30,8 +30,6 @@ class Member < ActiveRecord::Base
scope :invite, -> { where.not(invite_token: nil) }
scope :non_invite, -> { where(invite_token: nil) }
scope :request, -> { where.not(requested_at: nil) }
scope :non_request, -> { where(requested_at: nil) }
scope :non_pending, -> { non_request.non_invite }
scope :has_access, -> { where('access_level > 0') }
 
scope :guests, -> { where(access_level: GUEST) }
Loading
Loading
Loading
Loading
@@ -108,9 +108,13 @@ class Project < ActiveRecord::Base
has_many :snippets, dependent: :destroy, class_name: 'ProjectSnippet'
has_many :hooks, dependent: :destroy, class_name: 'ProjectHook'
has_many :protected_branches, dependent: :destroy
has_many :project_members, dependent: :destroy, as: :source, class_name: 'ProjectMember'
has_many :project_members, -> { where(requested_at: nil) }, dependent: :destroy, as: :source, class_name: 'ProjectMember'
alias_method :members, :project_members
has_many :users, -> { where(members: { requested_at: nil }) }, through: :project_members
has_many :users, through: :project_members
has_many :requesters, -> { where.not(requested_at: nil) }, dependent: :destroy, as: :source, class_name: 'ProjectMember'
has_many :deploy_keys_projects, dependent: :destroy
has_many :deploy_keys, through: :deploy_keys_projects
has_many :users_star_projects, dependent: :destroy
Loading
Loading
Loading
Loading
@@ -22,12 +22,12 @@ class ProjectTeam
end
 
def find_member(user_id)
member = project.members.non_request.find_by(user_id: user_id)
member = project.members.find_by(user_id: user_id)
 
# If user is not in project members
# we should check for group membership
if group && !member
member = group.members.non_request.find_by(user_id: user_id)
member = group.members.find_by(user_id: user_id)
end
 
member
Loading
Loading
@@ -137,10 +137,10 @@ class ProjectTeam
def max_member_access(user_id)
access = []
 
access += project.members.non_request.where(user_id: user_id).has_access.pluck(:access_level)
access += project.members.where(user_id: user_id).has_access.pluck(:access_level)
 
if group
access += group.members.non_request.where(user_id: user_id).has_access.pluck(:access_level)
access += group.members.where(user_id: user_id).has_access.pluck(:access_level)
end
 
if project.invited_groups.any? && project.allowed_to_share_with_group?
Loading
Loading
@@ -168,14 +168,14 @@ class ProjectTeam
end
 
def fetch_members(level = nil)
project_members = project.members.non_request
group_members = group ? group.members.non_request : []
project_members = project.members
group_members = group ? group.members : []
invited_members = []
 
if project.invited_groups.any? && project.allowed_to_share_with_group?
project.project_group_links.each do |group_link|
invited_group = group_link.group
im = invited_group.members.non_request
im = invited_group.members
 
if level
int_level = GroupMember.access_level_roles[level.to_s.singularize.titleize]
Loading
Loading
Loading
Loading
@@ -89,16 +89,16 @@
%hr
= button_tag 'Add users to group', class: "btn btn-create"
 
= render 'shared/members/requests', membership_source: @group, members: @members.request
= render 'shared/members/requests', membership_source: @group, requesters: @requesters
 
.panel.panel-default
.panel-heading
%strong= @group.name
group members
%span.badge= @group.members.non_request.size
%span.badge= @group.members.size
.pull-right
= link_to icon('pencil-square-o', text: 'Manage Access'), polymorphic_url([@group, :members]), class: "btn btn-xs"
%ul.well-list.group-users-list.content-list
= render partial: 'shared/members/member', collection: @members.non_request, as: :member, locals: { show_controls: false }
= render partial: 'shared/members/member', collection: @members, as: :member, locals: { show_controls: false }
.panel-footer
= paginate @members.non_request, param_name: 'members_page', theme: 'gitlab'
= paginate @members, param_name: 'members_page', theme: 'gitlab'
Loading
Loading
@@ -137,16 +137,16 @@
.panel-heading
%strong= @group.name
group members
%span.badge= @group_members.non_request.size
%span.badge= @group_members.size
.pull-right
= link_to admin_group_path(@group), class: 'btn btn-xs' do
= icon('pencil-square-o', text: 'Manage Access')
%ul.well-list.content-list
= render partial: 'shared/members/member', collection: @group_members.non_request, as: :member, locals: { show_controls: false }
= render partial: 'shared/members/member', collection: @group_members, as: :member, locals: { show_controls: false }
.panel-footer
= paginate @group_members.non_request, param_name: 'group_members_page', theme: 'gitlab'
= paginate @group_members, param_name: 'group_members_page', theme: 'gitlab'
 
= render 'shared/members/requests', membership_source: @project, members: @project_members.request
= render 'shared/members/requests', membership_source: @project, requesters: @requesters
 
.panel.panel-default
.panel-heading
Loading
Loading
@@ -156,6 +156,6 @@
.pull-right
= link_to icon('pencil-square-o', text: 'Manage Access'), polymorphic_url([@project, :members]), class: "btn btn-xs"
%ul.well-list.project_members.content-list
= render partial: 'shared/members/member', collection: @project_members.non_request, as: :member, locals: { show_controls: false }
= render partial: 'shared/members/member', collection: @project_members, as: :member, locals: { show_controls: false }
.panel-footer
= paginate @project_members.non_request, param_name: 'project_members_page', theme: 'gitlab'
= paginate @project_members, param_name: 'project_members_page', theme: 'gitlab'
- page_title "Members"
 
.group-members-page.prepend-top-default
- if current_user && current_user.can?(:admin_group_member, @group)
- if can?(current_user, :admin_group_member, @group)
.panel.panel-default
.panel-heading
Add new user to group
Loading
Loading
@@ -11,13 +11,13 @@
.new-group-member-holder
= render "new_group_member"
 
= render 'shared/members/requests', membership_source: @group, members: @members.request
= render 'shared/members/requests', membership_source: @group, requesters: @requesters
 
.panel.panel-default
.panel-heading
%strong #{@group.name}
group members
%span.badge= @members.non_request.size
%span.badge= @members.size
.controls
= form_tag group_group_members_path(@group), method: :get, class: 'form-inline member-search-form' do
.form-group
Loading
Loading
@@ -25,8 +25,8 @@
= button_tag class: 'btn', title: 'Search' do
= icon("search")
%ul.content-list
= render partial: 'shared/members/member', collection: @members.non_request, as: :member
= paginate @members.non_request, theme: 'gitlab'
= render partial: 'shared/members/member', collection: @members, as: :member
= paginate @members, theme: 'gitlab'
 
:javascript
$('form.member-search-form').on('submit', function(event) {
Loading
Loading
- if current_user
- can_edit = can?(current_user, :admin_group, @group)
- member = @group.members.non_request.find_by(user_id: current_user.id)
- member = @group.members.find_by(user_id: current_user.id)
- can_leave = member && can?(current_user, :destroy_group_member, member)
 
.controls
Loading
Loading
Loading
Loading
@@ -7,7 +7,7 @@
%ul.dropdown-menu.dropdown-menu-align-right
- can_edit = can?(current_user, :admin_project, @project)
-# We don't use @project.team.find_member because it searches for group members too...
- member = @project.members.non_request.find_by(user_id: current_user.id)
- member = @project.members.find_by(user_id: current_user.id)
- can_leave = member && can?(current_user, :destroy_project_member, member)
 
= render 'layouts/nav/project_settings', can_edit: can_edit
Loading
Loading
- @project_group_links.each do |group_links|
- shared_group = group_links.group
- shared_group_members = shared_group.members.non_request
- shared_group_members = shared_group.members
- shared_group_users_count = shared_group_members.size
.panel.panel-default
.panel-heading
Loading
Loading
Loading
Loading
@@ -13,12 +13,12 @@
Users with access to this project are listed below.
= render "new_project_member"
 
= render 'shared/members/requests', membership_source: @project, members: @project_members.request
= render 'shared/members/requests', membership_source: @project, requesters: @requesters
 
= render 'team', members: @project_members.non_request
= render 'team', members: @project_members
 
- if @group
= render "group_members", members: @group_members.non_request
= render "group_members", members: @group_members
 
- if @project_group_links.any? && @project.allowed_to_share_with_group?
= render "shared_group_members"
- member = source.members.find_by(user_id: current_user.id)
- group_member = source.group.members.find_by(user_id: current_user.id) if source.respond_to?(:group) && source.group
- unless group_member
- if member
- if member.request?
= link_to 'Withdraw Access Request', polymorphic_path([:leave, source, :members]),
method: :delete,
data: { confirm: remove_member_message(member) },
class: 'btn'
- if can_see_request_access_button?(source)
- if requester = source.requesters.find_by(user_id: current_user.id)
= link_to 'Withdraw Access Request', polymorphic_path([:leave, source, :members]),
method: :delete,
data: { confirm: remove_member_message(requester) },
class: 'btn'
- else
= link_to 'Request Access', polymorphic_path([:request_access, source, :members]),
method: :post,
Loading
Loading
- if members.any?
- if requesters.any?
.panel.panel-default
.panel-heading
%strong= membership_source.name
access requests
%span.badge= members.size
%span.badge= requesters.size
%ul.content-list
= render partial: 'shared/members/member', collection: members, as: :member
= render partial: 'shared/members/member', collection: requesters, as: :member
Loading
Loading
@@ -133,7 +133,7 @@ describe Groups::GroupMembersController do
 
expect(response).to set_flash.to 'Your access request to the group has been withdrawn.'
expect(response).to redirect_to(group_path(group))
expect(group.members.request).to be_empty
expect(group.requesters).to be_empty
expect(group.users).not_to include user
end
end
Loading
Loading
@@ -153,7 +153,7 @@ describe Groups::GroupMembersController do
 
expect(response).to set_flash.to 'Your request for access has been queued for review.'
expect(response).to redirect_to(group_path(group))
expect(group.members.request.exists?(user_id: user)).to be_truthy
expect(group.requesters.exists?(user_id: user)).to be_truthy
expect(group.users).not_to include user
end
end
Loading
Loading
@@ -175,7 +175,7 @@ describe Groups::GroupMembersController do
let(:group_requester) { create(:user) }
let(:member) do
group.request_access(group_requester)
group.members.request.find_by(user_id: group_requester)
group.requesters.find_by(user_id: group_requester)
end
 
context 'when user does not have enough rights' do
Loading
Loading
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment