diff --git a/app/models/project.rb b/app/models/project.rb index 4408c29a54d..5d475c25e4a 100644 --- a/app/models/project.rb +++ b/app/models/project.rb @@ -126,6 +126,7 @@ class Project < ActiveRecord::Base has_many :hooks, dependent: :destroy, class_name: 'ProjectHook' has_many :protected_branches, dependent: :destroy + has_many :project_authorizations, dependent: :destroy has_many :project_members, -> { where(requested_at: nil) }, dependent: :destroy, as: :source alias_method :members, :project_members has_many :users, through: :project_members diff --git a/app/models/project_team.rb b/app/models/project_team.rb index 5845203055a..1d0e97396f3 100644 --- a/app/models/project_team.rb +++ b/app/models/project_team.rb @@ -169,54 +169,21 @@ class ProjectTeam # Lookup only the IDs we need 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? - 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.merge!(users_access) access end 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 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) project_members = project.members group_members = group ? group.members : [] @@ -240,10 +207,6 @@ class ProjectTeam project.group 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? project.invited_groups.any? && project.allowed_to_share_with_group? end diff --git a/spec/lib/gitlab/import_export/all_models.yml b/spec/lib/gitlab/import_export/all_models.yml index fe3c39e38db..7e00e214c6e 100644 --- a/spec/lib/gitlab/import_export/all_models.yml +++ b/spec/lib/gitlab/import_export/all_models.yml @@ -186,6 +186,8 @@ project: - environments - deployments - project_feature +- authorized_users +- project_authorizations award_emoji: - awardable - user diff --git a/spec/models/project_team_spec.rb b/spec/models/project_team_spec.rb index 573da5e50d4..700776be931 100644 --- a/spec/models/project_team_spec.rb +++ b/spec/models/project_team_spec.rb @@ -37,7 +37,7 @@ describe ProjectTeam, models: true do context 'group project' do let(:group) { create(:group) } - let(:project) { create(:empty_project, group: group) } + let!(:project) { create(:empty_project, group: group) } before do group.add_master(master) @@ -178,9 +178,9 @@ describe ProjectTeam, models: true do it 'returns Master role' do user = create(:user) 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' end @@ -188,9 +188,9 @@ describe ProjectTeam, models: true do it 'returns Owner role' do user = create(:user) 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' end @@ -244,7 +244,7 @@ describe ProjectTeam, models: true do context 'group project' do let(:group) { create(:group, :access_requestable) } - let(:project) { create(:empty_project, group: group) } + let!(:project) { create(:empty_project, group: group) } before do group.add_master(master)