summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMark Chao <mchao@gitlab.com>2019-10-22 21:05:33 +0800
committerDylan Griffith <dyl.griffith@gmail.com>2019-11-15 20:57:57 +1100
commit2cb2a771a4a4523d1aa0f65276dfb0863dd3158e (patch)
tree8a341f35b0a2dbbcb7d75ee19167a780b6a2a236
parentc484ba8db2cb2a4bde4299019d74634639220bb4 (diff)
downloadgitlab-ce-2cb2a771a4a4523d1aa0f65276dfb0863dd3158e.tar.gz
Fix scope to handle private guest permission
Guest are blocked to certain feature when project is private, therefore the scope would filter additionally with REPORTER level.
-rw-r--r--app/models/project.rb8
-rw-r--r--app/models/project_feature.rb7
-rw-r--r--spec/models/project_spec.rb74
3 files changed, 88 insertions, 1 deletions
diff --git a/app/models/project.rb b/app/models/project.rb
index e4341bcee6c..d16078b4fe0 100644
--- a/app/models/project.rb
+++ b/app/models/project.rb
@@ -498,7 +498,13 @@ class Project < ApplicationRecord
# This scope returns projects where user has access to both the project and the feature.
def self.filter_by_feature_visibility(feature, user)
- with_feature_available_for_user(feature, user).public_or_visible_to_user(user)
+ scope = with_feature_available_for_user(feature, user)
+
+ if ProjectFeature.guest_allowed_on_private_project?(feature)
+ scope.public_or_visible_to_user(user)
+ else
+ scope.public_or_visible_to_user(user, Gitlab::Access::REPORTER)
+ end
end
scope :active, -> { joins(:issues, :notes, :merge_requests).order('issues.created_at, notes.created_at, merge_requests.created_at DESC') }
diff --git a/app/models/project_feature.rb b/app/models/project_feature.rb
index 2013f620b5b..564e531c320 100644
--- a/app/models/project_feature.rb
+++ b/app/models/project_feature.rb
@@ -24,6 +24,7 @@ class ProjectFeature < ApplicationRecord
FEATURES = %i(issues merge_requests wiki snippets builds repository pages).freeze
PRIVATE_FEATURES_MIN_ACCESS_LEVEL = { merge_requests: Gitlab::Access::REPORTER }.freeze
+ FEATURES_ALLOWED_BY_GUEST_ON_PRIVATE_PROJECT = %i(issues wiki).freeze
STRING_OPTIONS = HashWithIndifferentAccess.new({
'disabled' => DISABLED,
'private' => PRIVATE,
@@ -45,6 +46,12 @@ class ProjectFeature < ApplicationRecord
"#{table}.#{attribute}"
end
+ def guest_allowed_on_private_project?(feature)
+ feature = ensure_feature!(feature)
+
+ FEATURES_ALLOWED_BY_GUEST_ON_PRIVATE_PROJECT.include?(feature)
+ end
+
def required_minimum_access_level(feature)
feature = ensure_feature!(feature)
diff --git a/spec/models/project_spec.rb b/spec/models/project_spec.rb
index 92648cddb24..46d7eefabf2 100644
--- a/spec/models/project_spec.rb
+++ b/spec/models/project_spec.rb
@@ -3339,6 +3339,20 @@ describe Project do
expect(projects).to eq([public_project])
end
end
+
+ context 'min_access_level' do
+ let!(:private_project) { create(:project, :private) }
+
+ before do
+ private_project.add_guest(user)
+ end
+
+ it 'excludes projects when user does not have required minimum access level' do
+ projects = described_class.all.public_or_visible_to_user(user, Gitlab::Access::REPORTER)
+
+ expect(projects).to contain_exactly(public_project)
+ end
+ end
end
describe '.ids_with_issuables_available_for' do
@@ -3490,6 +3504,66 @@ describe Project do
end
end
end
+
+ context 'issues' do
+ let(:feature) { Issue }
+
+ where(:project_level, :feature_access_level, :membership, :expected_count) do
+ permission_table_for_guest_feature_access
+ end
+
+ with_them do
+ it "respects visibility" do
+ update_feature_access_level(project, feature_access_level)
+
+ expected_objects = expected_count == 1 ? [project] : []
+
+ expect(
+ described_class.filter_by_feature_visibility(feature, user)
+ ).to eq(expected_objects)
+ end
+ end
+ end
+
+ context 'wiki' do
+ let(:feature) { :wiki }
+
+ where(:project_level, :feature_access_level, :membership, :expected_count) do
+ permission_table_for_guest_feature_access
+ end
+
+ with_them do
+ it "respects visibility" do
+ update_feature_access_level(project, feature_access_level)
+
+ expected_objects = expected_count == 1 ? [project] : []
+
+ expect(
+ described_class.filter_by_feature_visibility(feature, user)
+ ).to eq(expected_objects)
+ end
+ end
+ end
+
+ context 'code' do
+ let(:feature) { :repository }
+
+ where(:project_level, :feature_access_level, :membership, :expected_count) do
+ permission_table_for_guest_feature_access_and_non_private_project_only
+ end
+
+ with_them do
+ it "respects visibility" do
+ update_feature_access_level(project, feature_access_level)
+
+ expected_objects = expected_count == 1 ? [project] : []
+
+ expect(
+ described_class.filter_by_feature_visibility(feature, user)
+ ).to eq(expected_objects)
+ end
+ end
+ end
end
describe '#pages_available?' do