Commit 0de1bfea authored by Mark Chao's avatar Mark Chao

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.
parent d5bfeee5
...@@ -517,7 +517,13 @@ class Project < ApplicationRecord ...@@ -517,7 +517,13 @@ class Project < ApplicationRecord
# This scope returns projects where user has access to both the project and the feature. # This scope returns projects where user has access to both the project and the feature.
def self.filter_by_feature_visibility(feature, user) 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 end
scope :active, -> { joins(:issues, :notes, :merge_requests).order('issues.created_at, notes.created_at, merge_requests.created_at DESC') } scope :active, -> { joins(:issues, :notes, :merge_requests).order('issues.created_at, notes.created_at, merge_requests.created_at DESC') }
......
...@@ -24,6 +24,7 @@ class ProjectFeature < ApplicationRecord ...@@ -24,6 +24,7 @@ class ProjectFeature < ApplicationRecord
FEATURES = %i(issues merge_requests wiki snippets builds repository pages).freeze FEATURES = %i(issues merge_requests wiki snippets builds repository pages).freeze
PRIVATE_FEATURES_MIN_ACCESS_LEVEL = { merge_requests: Gitlab::Access::REPORTER }.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({ STRING_OPTIONS = HashWithIndifferentAccess.new({
'disabled' => DISABLED, 'disabled' => DISABLED,
'private' => PRIVATE, 'private' => PRIVATE,
...@@ -45,6 +46,12 @@ class ProjectFeature < ApplicationRecord ...@@ -45,6 +46,12 @@ class ProjectFeature < ApplicationRecord
"#{table}.#{attribute}" "#{table}.#{attribute}"
end 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) def required_minimum_access_level(feature)
feature = ensure_feature!(feature) feature = ensure_feature!(feature)
......
...@@ -3411,6 +3411,20 @@ describe Project do ...@@ -3411,6 +3411,20 @@ describe Project do
expect(projects).to eq([public_project]) expect(projects).to eq([public_project])
end end
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 end
describe '.ids_with_issuables_available_for' do describe '.ids_with_issuables_available_for' do
...@@ -3562,6 +3576,66 @@ describe Project do ...@@ -3562,6 +3576,66 @@ describe Project do
end end
end 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 end
describe '#pages_available?' do describe '#pages_available?' do
......
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