Update ProjectTeam#max_member_access_for_user_ids to use project authorizations
This commit is contained in:
parent
0f3c3a1c57
commit
747959a832
|
@ -126,6 +126,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_authorizations, dependent: :destroy
|
||||||
has_many :project_members, -> { where(requested_at: nil) }, dependent: :destroy, as: :source
|
has_many :project_members, -> { where(requested_at: nil) }, dependent: :destroy, as: :source
|
||||||
alias_method :members, :project_members
|
alias_method :members, :project_members
|
||||||
has_many :users, through: :project_members
|
has_many :users, through: :project_members
|
||||||
|
|
|
@ -169,54 +169,21 @@ class ProjectTeam
|
||||||
|
|
||||||
# Lookup only the IDs we need
|
# Lookup only the IDs we need
|
||||||
user_ids = user_ids - access.keys
|
user_ids = user_ids - access.keys
|
||||||
|
users_access = project.project_authorizations.
|
||||||
|
where(user: user_ids).
|
||||||
|
group(:user_id).
|
||||||
|
maximum(:access_level)
|
||||||
|
|
||||||
if user_ids.present?
|
access.merge!(users_access)
|
||||||
user_ids.each { |id| access[id] = Gitlab::Access::NO_ACCESS }
|
|
||||||
|
|
||||||
member_access = project.members.access_for_user_ids(user_ids)
|
|
||||||
merge_max!(access, member_access)
|
|
||||||
|
|
||||||
if group
|
|
||||||
group_access = group.members.access_for_user_ids(user_ids)
|
|
||||||
merge_max!(access, group_access)
|
|
||||||
end
|
|
||||||
|
|
||||||
# Each group produces a list of maximum access level per user. We take the
|
|
||||||
# max of the values produced by each group.
|
|
||||||
if project_shared_with_group?
|
|
||||||
project.project_group_links.each do |group_link|
|
|
||||||
invited_access = max_invited_level_for_users(group_link, user_ids)
|
|
||||||
merge_max!(access, invited_access)
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
access
|
access
|
||||||
end
|
end
|
||||||
|
|
||||||
def max_member_access(user_id)
|
def max_member_access(user_id)
|
||||||
max_member_access_for_user_ids([user_id])[user_id]
|
max_member_access_for_user_ids([user_id])[user_id] || Gitlab::Access::NO_ACCESS
|
||||||
end
|
end
|
||||||
|
|
||||||
private
|
private
|
||||||
|
|
||||||
# For a given group, return the maximum access level for the user. This is the min of
|
|
||||||
# the invited access level of the group and the access level of the user within the group.
|
|
||||||
# For example, if the group has been given DEVELOPER access but the member has MASTER access,
|
|
||||||
# the user should receive only DEVELOPER access.
|
|
||||||
def max_invited_level_for_users(group_link, user_ids)
|
|
||||||
invited_group = group_link.group
|
|
||||||
capped_access_level = group_link.group_access
|
|
||||||
access = invited_group.group_members.access_for_user_ids(user_ids)
|
|
||||||
|
|
||||||
# If the user is not in the list, assume he/she does not have access
|
|
||||||
missing_users = user_ids - access.keys
|
|
||||||
missing_users.each { |id| access[id] = Gitlab::Access::NO_ACCESS }
|
|
||||||
|
|
||||||
# Cap the maximum access by the invited level access
|
|
||||||
access.each { |key, value| access[key] = [value, capped_access_level].min }
|
|
||||||
end
|
|
||||||
|
|
||||||
def fetch_members(level = nil)
|
def fetch_members(level = nil)
|
||||||
project_members = project.members
|
project_members = project.members
|
||||||
group_members = group ? group.members : []
|
group_members = group ? group.members : []
|
||||||
|
@ -240,10 +207,6 @@ class ProjectTeam
|
||||||
project.group
|
project.group
|
||||||
end
|
end
|
||||||
|
|
||||||
def merge_max!(first_hash, second_hash)
|
|
||||||
first_hash.merge!(second_hash) { |_key, old, new| old > new ? old : new }
|
|
||||||
end
|
|
||||||
|
|
||||||
def project_shared_with_group?
|
def project_shared_with_group?
|
||||||
project.invited_groups.any? && project.allowed_to_share_with_group?
|
project.invited_groups.any? && project.allowed_to_share_with_group?
|
||||||
end
|
end
|
||||||
|
|
|
@ -186,6 +186,8 @@ project:
|
||||||
- environments
|
- environments
|
||||||
- deployments
|
- deployments
|
||||||
- project_feature
|
- project_feature
|
||||||
|
- authorized_users
|
||||||
|
- project_authorizations
|
||||||
award_emoji:
|
award_emoji:
|
||||||
- awardable
|
- awardable
|
||||||
- user
|
- user
|
||||||
|
|
|
@ -37,7 +37,7 @@ describe ProjectTeam, models: true do
|
||||||
|
|
||||||
context 'group project' do
|
context 'group project' do
|
||||||
let(:group) { create(:group) }
|
let(:group) { create(:group) }
|
||||||
let(:project) { create(:empty_project, group: group) }
|
let!(:project) { create(:empty_project, group: group) }
|
||||||
|
|
||||||
before do
|
before do
|
||||||
group.add_master(master)
|
group.add_master(master)
|
||||||
|
@ -178,9 +178,9 @@ describe ProjectTeam, models: true do
|
||||||
it 'returns Master role' do
|
it 'returns Master role' do
|
||||||
user = create(:user)
|
user = create(:user)
|
||||||
group = create(:group)
|
group = create(:group)
|
||||||
group.add_master(user)
|
project = create(:empty_project, namespace: group)
|
||||||
|
|
||||||
project = build_stubbed(:empty_project, namespace: group)
|
group.add_master(user)
|
||||||
|
|
||||||
expect(project.team.human_max_access(user.id)).to eq 'Master'
|
expect(project.team.human_max_access(user.id)).to eq 'Master'
|
||||||
end
|
end
|
||||||
|
@ -188,9 +188,9 @@ describe ProjectTeam, models: true do
|
||||||
it 'returns Owner role' do
|
it 'returns Owner role' do
|
||||||
user = create(:user)
|
user = create(:user)
|
||||||
group = create(:group)
|
group = create(:group)
|
||||||
group.add_owner(user)
|
project = create(:empty_project, namespace: group)
|
||||||
|
|
||||||
project = build_stubbed(:empty_project, namespace: group)
|
group.add_owner(user)
|
||||||
|
|
||||||
expect(project.team.human_max_access(user.id)).to eq 'Owner'
|
expect(project.team.human_max_access(user.id)).to eq 'Owner'
|
||||||
end
|
end
|
||||||
|
@ -244,7 +244,7 @@ describe ProjectTeam, models: true do
|
||||||
|
|
||||||
context 'group project' do
|
context 'group project' do
|
||||||
let(:group) { create(:group, :access_requestable) }
|
let(:group) { create(:group, :access_requestable) }
|
||||||
let(:project) { create(:empty_project, group: group) }
|
let!(:project) { create(:empty_project, group: group) }
|
||||||
|
|
||||||
before do
|
before do
|
||||||
group.add_master(master)
|
group.add_master(master)
|
||||||
|
|
Loading…
Reference in New Issue