summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDouwe Maan <douwe@selenight.nl>2017-02-27 16:16:39 -0600
committerDmitriy Zaporozhets <dmitriy.zaporozhets@gmail.com>2017-02-28 14:18:20 +0200
commit05f331f3ce17ec15377209bf4980b4c91954aa59 (patch)
tree4a589bead160d9777e355f877d872e1cc23c29a7
parent71fbbc9da428268411c5a3cef319f7537b63d199 (diff)
downloadgitlab-ce-dm-nested-group-shared-projects.tar.gz
Fix access to projects shared with a nested groupdm-nested-group-shared-projects
Signed-off-by: Dmitriy Zaporozhets <dmitriy.zaporozhets@gmail.com>
-rw-r--r--app/models/user.rb2
-rw-r--r--app/services/users/refresh_authorized_projects_service.rb16
-rw-r--r--spec/models/user_spec.rb4
-rw-r--r--spec/services/users/refresh_authorized_projects_service_spec.rb74
4 files changed, 91 insertions, 5 deletions
diff --git a/app/models/user.rb b/app/models/user.rb
index 40264401b53..6fb5ac4a4ef 100644
--- a/app/models/user.rb
+++ b/app/models/user.rb
@@ -474,7 +474,7 @@ class User < ActiveRecord::Base
Group.member_descendants(id)
end
- def nested_projects
+ def nested_groups_projects
Project.joins(:namespace).where('namespaces.parent_id IS NOT NULL').
member_descendants(id)
end
diff --git a/app/services/users/refresh_authorized_projects_service.rb b/app/services/users/refresh_authorized_projects_service.rb
index fad741531ea..d9370bbb598 100644
--- a/app/services/users/refresh_authorized_projects_service.rb
+++ b/app/services/users/refresh_authorized_projects_service.rb
@@ -115,11 +115,23 @@ module Users
# Returns a union query of projects that the user is authorized to access
def project_authorizations_union
relations = [
+ # Personal projects
user.personal_projects.select("#{user.id} AS user_id, projects.id AS project_id, #{Gitlab::Access::MASTER} AS access_level"),
- user.groups_projects.select_for_project_authorization,
+
+ # Projects the user is a member of
user.projects.select_for_project_authorization,
+
+ # Projects of groups the user is a member of
+ user.groups_projects.select_for_project_authorization,
+
+ # Projects of subgroups of groups the user is a member of
+ user.nested_groups_projects.select_for_project_authorization,
+
+ # Projects shared with groups the user is a member of
user.groups.joins(:shared_projects).select_for_project_authorization,
- user.nested_projects.select_for_project_authorization
+
+ # Projects shared with subgroups of groups the user is a member of
+ user.nested_groups.joins(:shared_projects).select_for_project_authorization
]
Gitlab::SQL::Union.new(relations)
diff --git a/spec/models/user_spec.rb b/spec/models/user_spec.rb
index 6356f8b6c92..e86b4a761d9 100644
--- a/spec/models/user_spec.rb
+++ b/spec/models/user_spec.rb
@@ -1429,7 +1429,7 @@ describe User, models: true do
it { expect(user.nested_groups).to eq([nested_group]) }
end
- describe '#nested_projects' do
+ describe '#nested_groups_projects' do
let!(:user) { create(:user) }
let!(:group) { create(:group) }
let!(:nested_group) { create(:group, parent: group) }
@@ -1444,7 +1444,7 @@ describe User, models: true do
other_project.add_developer(create(:user))
end
- it { expect(user.nested_projects).to eq([nested_project]) }
+ it { expect(user.nested_groups_projects).to eq([nested_project]) }
end
describe '#refresh_authorized_projects', redis: true do
diff --git a/spec/services/users/refresh_authorized_projects_service_spec.rb b/spec/services/users/refresh_authorized_projects_service_spec.rb
index 690fe979492..08733d6dcf1 100644
--- a/spec/services/users/refresh_authorized_projects_service_spec.rb
+++ b/spec/services/users/refresh_authorized_projects_service_spec.rb
@@ -131,6 +131,80 @@ describe Users::RefreshAuthorizedProjectsService do
it 'sets the values to the access levels' do
expect(hash.values).to eq([Gitlab::Access::MASTER])
end
+
+ context 'personal projects' do
+ it 'includes the project with the right access level' do
+ expect(hash[project.id]).to eq(Gitlab::Access::MASTER)
+ end
+ end
+
+ context 'projects the user is a member of' do
+ let!(:other_project) { create(:empty_project) }
+
+ before do
+ other_project.team.add_reporter(user)
+ end
+
+ it 'includes the project with the right access level' do
+ expect(hash[other_project.id]).to eq(Gitlab::Access::REPORTER)
+ end
+ end
+
+ context 'projects of groups the user is a member of' do
+ let(:group) { create(:group) }
+ let!(:other_project) { create(:project, group: group) }
+
+ before do
+ group.add_owner(user)
+ end
+
+ it 'includes the project with the right access level' do
+ expect(hash[other_project.id]).to eq(Gitlab::Access::OWNER)
+ end
+ end
+
+ context 'projects of subgroups of groups the user is a member of' do
+ let(:group) { create(:group) }
+ let(:nested_group) { create(:group, parent: group) }
+ let!(:other_project) { create(:project, group: nested_group) }
+
+ before do
+ group.add_master(user)
+ end
+
+ it 'includes the project with the right access level' do
+ expect(hash[other_project.id]).to eq(Gitlab::Access::MASTER)
+ end
+ end
+
+ context 'projects shared with groups the user is a member of' do
+ let(:group) { create(:group) }
+ let(:other_project) { create(:empty_project) }
+ let!(:project_group_link) { create(:project_group_link, project: other_project, group: group, group_access: Gitlab::Access::GUEST) }
+
+ before do
+ group.add_master(user)
+ end
+
+ it 'includes the project with the right access level' do
+ expect(hash[other_project.id]).to eq(Gitlab::Access::GUEST)
+ end
+ end
+
+ context 'projects shared with subgroups of groups the user is a member of' do
+ let(:group) { create(:group) }
+ let(:nested_group) { create(:group, parent: group) }
+ let(:other_project) { create(:empty_project) }
+ let!(:project_group_link) { create(:project_group_link, project: other_project, group: nested_group, group_access: Gitlab::Access::DEVELOPER) }
+
+ before do
+ group.add_master(user)
+ end
+
+ it 'includes the project with the right access level' do
+ expect(hash[other_project.id]).to eq(Gitlab::Access::DEVELOPER)
+ end
+ end
end
describe '#current_authorizations_per_project' do