Commit 1b14bc59 authored by James Lopez's avatar James Lopez

refactored permissions and added update_project_member ability logic. Also...

refactored permissions and added update_project_member ability logic. Also refactored owner methods to a concern.
parent 6aa9c21a
...@@ -15,6 +15,7 @@ class Ability ...@@ -15,6 +15,7 @@ class Ability
when "Group" then group_abilities(user, subject) when "Group" then group_abilities(user, subject)
when "Namespace" then namespace_abilities(user, subject) when "Namespace" then namespace_abilities(user, subject)
when "GroupMember" then group_member_abilities(user, subject) when "GroupMember" then group_member_abilities(user, subject)
when "ProjectMember" then project_member_abilities(user, subject)
else [] else []
end.concat(global_abilities(user)) end.concat(global_abilities(user))
end end
...@@ -316,6 +317,23 @@ class Ability ...@@ -316,6 +317,23 @@ class Ability
rules rules
end end
def project_member_abilities(user, subject)
rules = []
target_user = subject.user
project = subject.project
can_manage = project_abilities(user, project).include?(:admin_project_member)
if can_manage && (user != target_user)
rules << :update_project_member
rules << :destroy_project_member
end
if !project.last_owner?(user) && (can_manage || (user == target_user))
rules << :destroy_project_member
end
rules
end
def abilities def abilities
@abilities ||= begin @abilities ||= begin
abilities = Six.new abilities = Six.new
......
# == Owners concern
#
# Contains owners functionality for groups
#
module HasOwners
extend ActiveSupport::Concern
def owners
@owners ||= my_members.owners.includes(:user).map(&:user)
end
def my_members
raise NotImplementedError, "Expected my_members to be defined in #{self.class.name}"
end
def add_owner(user, current_user = nil)
add_user(user, Gitlab::Access::OWNER, current_user)
end
def has_owner?(user)
owners.include?(user)
end
def has_master?(user)
members.masters.where(user_id: user).any?
end
def last_owner?(user)
has_owner?(user) && owners.size == 1
end
end
...@@ -19,8 +19,10 @@ require 'file_size_validator' ...@@ -19,8 +19,10 @@ require 'file_size_validator'
class Group < Namespace class Group < Namespace
include Gitlab::ConfigHelper include Gitlab::ConfigHelper
include Referable include Referable
include HasOwners
has_many :group_members, dependent: :destroy, as: :source, class_name: 'GroupMember' has_many :group_members, dependent: :destroy, as: :source, class_name: 'GroupMember'
alias_method :my_members, :group_members
has_many :users, through: :group_members has_many :users, through: :group_members
validate :avatar_type, if: ->(user) { user.avatar.present? && user.avatar_changed? } validate :avatar_type, if: ->(user) { user.avatar.present? && user.avatar_changed? }
...@@ -63,10 +65,6 @@ class Group < Namespace ...@@ -63,10 +65,6 @@ class Group < Namespace
end end
end end
def owners
@owners ||= group_members.owners.includes(:user).map(&:user)
end
def add_users(user_ids, access_level, current_user = nil) def add_users(user_ids, access_level, current_user = nil)
user_ids.each do |user_id| user_ids.each do |user_id|
Member.add_user(self.group_members, user_id, access_level, current_user) Member.add_user(self.group_members, user_id, access_level, current_user)
...@@ -93,22 +91,6 @@ class Group < Namespace ...@@ -93,22 +91,6 @@ class Group < Namespace
add_user(user, Gitlab::Access::MASTER, current_user) add_user(user, Gitlab::Access::MASTER, current_user)
end end
def add_owner(user, current_user = nil)
add_user(user, Gitlab::Access::OWNER, current_user)
end
def has_owner?(user)
owners.include?(user)
end
def has_master?(user)
members.masters.where(user_id: user).any?
end
def last_owner?(user)
has_owner?(user) && owners.size == 1
end
def members def members
group_members group_members
end end
......
...@@ -82,8 +82,7 @@ class Member < ActiveRecord::Base ...@@ -82,8 +82,7 @@ class Member < ActiveRecord::Base
member.invite_email = user member.invite_email = user
end end
project = members.first.respond_to?(:project)? members.first.project : nil if can_update_member?(current_user, member)
if can_update_member?(current_user, member, project)
member.created_by ||= current_user member.created_by ||= current_user
member.access_level = access_level member.access_level = access_level
...@@ -93,9 +92,10 @@ class Member < ActiveRecord::Base ...@@ -93,9 +92,10 @@ class Member < ActiveRecord::Base
private private
def can_update_member?(current_user, member, project) def can_update_member?(current_user, member)
!current_user || current_user.can?(:update_group_member, member) || !current_user || current_user.can?(:update_group_member, member) ||
(project && current_user.can?(:admin_project_member, project)) (member.respond_to?(:project) &&
current_user.can?(:update_project_member, member))
end end
end end
......
...@@ -41,6 +41,7 @@ class Project < ActiveRecord::Base ...@@ -41,6 +41,7 @@ class Project < ActiveRecord::Base
include Sortable include Sortable
include AfterCommitQueue include AfterCommitQueue
include CaseSensitivity include CaseSensitivity
include HasOwners
extend Gitlab::ConfigHelper extend Gitlab::ConfigHelper
extend Enumerize extend Enumerize
...@@ -114,6 +115,7 @@ class Project < ActiveRecord::Base ...@@ -114,6 +115,7 @@ class Project < ActiveRecord::Base
has_many :hooks, dependent: :destroy, class_name: 'ProjectHook' has_many :hooks, dependent: :destroy, class_name: 'ProjectHook'
has_many :protected_branches, dependent: :destroy has_many :protected_branches, dependent: :destroy
has_many :project_members, dependent: :destroy, as: :source, class_name: 'ProjectMember' has_many :project_members, dependent: :destroy, as: :source, class_name: 'ProjectMember'
alias_method :my_members, :project_members
has_many :users, through: :project_members has_many :users, through: :project_members
has_many :deploy_keys_projects, dependent: :destroy has_many :deploy_keys_projects, dependent: :destroy
has_many :deploy_keys, through: :deploy_keys_projects has_many :deploy_keys, through: :deploy_keys_projects
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment