refactored permissions and added update_project_member ability logic. Also refactored owner methods to a concern.
This commit is contained in:
parent
6aa9c21ac0
commit
1b14bc5957
|
@ -15,6 +15,7 @@ class Ability
|
|||
when "Group" then group_abilities(user, subject)
|
||||
when "Namespace" then namespace_abilities(user, subject)
|
||||
when "GroupMember" then group_member_abilities(user, subject)
|
||||
when "ProjectMember" then project_member_abilities(user, subject)
|
||||
else []
|
||||
end.concat(global_abilities(user))
|
||||
end
|
||||
|
@ -316,6 +317,23 @@ class Ability
|
|||
rules
|
||||
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
|
||||
@abilities ||= begin
|
||||
abilities = Six.new
|
||||
|
|
|
@ -0,0 +1,31 @@
|
|||
# == 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'
|
|||
class Group < Namespace
|
||||
include Gitlab::ConfigHelper
|
||||
include Referable
|
||||
include HasOwners
|
||||
|
||||
has_many :group_members, dependent: :destroy, as: :source, class_name: 'GroupMember'
|
||||
alias_method :my_members, :group_members
|
||||
has_many :users, through: :group_members
|
||||
|
||||
validate :avatar_type, if: ->(user) { user.avatar.present? && user.avatar_changed? }
|
||||
|
@ -63,10 +65,6 @@ class Group < Namespace
|
|||
end
|
||||
end
|
||||
|
||||
def owners
|
||||
@owners ||= group_members.owners.includes(:user).map(&:user)
|
||||
end
|
||||
|
||||
def add_users(user_ids, access_level, current_user = nil)
|
||||
user_ids.each do |user_id|
|
||||
Member.add_user(self.group_members, user_id, access_level, current_user)
|
||||
|
@ -93,22 +91,6 @@ class Group < Namespace
|
|||
add_user(user, Gitlab::Access::MASTER, current_user)
|
||||
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
|
||||
group_members
|
||||
end
|
||||
|
|
|
@ -82,8 +82,7 @@ class Member < ActiveRecord::Base
|
|||
member.invite_email = user
|
||||
end
|
||||
|
||||
project = members.first.respond_to?(:project)? members.first.project : nil
|
||||
if can_update_member?(current_user, member, project)
|
||||
if can_update_member?(current_user, member)
|
||||
member.created_by ||= current_user
|
||||
member.access_level = access_level
|
||||
|
||||
|
@ -93,9 +92,10 @@ class Member < ActiveRecord::Base
|
|||
|
||||
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) ||
|
||||
(project && current_user.can?(:admin_project_member, project))
|
||||
(member.respond_to?(:project) &&
|
||||
current_user.can?(:update_project_member, member))
|
||||
end
|
||||
end
|
||||
|
||||
|
|
|
@ -41,6 +41,7 @@ class Project < ActiveRecord::Base
|
|||
include Sortable
|
||||
include AfterCommitQueue
|
||||
include CaseSensitivity
|
||||
include HasOwners
|
||||
|
||||
extend Gitlab::ConfigHelper
|
||||
extend Enumerize
|
||||
|
@ -114,6 +115,7 @@ class Project < ActiveRecord::Base
|
|||
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'
|
||||
alias_method :my_members, :project_members
|
||||
has_many :users, through: :project_members
|
||||
has_many :deploy_keys_projects, dependent: :destroy
|
||||
has_many :deploy_keys, through: :deploy_keys_projects
|
||||
|
|
Loading…
Reference in New Issue