Commit 747959a8 authored by Ahmad Sherif's avatar Ahmad Sherif

Update ProjectTeam#max_member_access_for_user_ids to use project authorizations

parent 0f3c3a1c
...@@ -126,6 +126,7 @@ class Project < ActiveRecord::Base ...@@ -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 ...@@ -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 ...@@ -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: ...@@ -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 ...@@ -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 ...@@ -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 ...@@ -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 ...@@ -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)
......
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