diff --git a/lib/guardian/topic_guardian.rb b/lib/guardian/topic_guardian.rb index 05fb6ad041d..0846a9feb45 100644 --- a/lib/guardian/topic_guardian.rb +++ b/lib/guardian/topic_guardian.rb @@ -277,6 +277,10 @@ module TopicGuardian ) end + def can_see_unlisted_topics? + is_staff? || @user.has_trust_level?(TrustLevel[4]) + end + def can_get_access_to_topic?(topic) topic&.access_topic_via_group.present? && authenticated? end diff --git a/lib/topic_query.rb b/lib/topic_query.rb index cd3ce275080..37c3120f491 100644 --- a/lib/topic_query.rb +++ b/lib/topic_query.rb @@ -642,9 +642,13 @@ class TopicQuery options.reverse_merge!(@options) options.reverse_merge!(per_page: per_page_setting) unless options[:limit] == false - # Whether to return visible topics - options[:visible] = true if @user.nil? || @user.regular? - options[:visible] = false if @user && @user.id == options[:filtered_to_user] + # Whether to include unlisted (visible = false) topics + viewing_own_topics = @user && @user.id == options[:filtered_to_user] + + if options[:visible].nil? + options[:visible] = true if @user.nil? || @user.regular? + options[:visible] = false if @guardian.can_see_unlisted_topics? || viewing_own_topics + end # Start with a list of all topics result = Topic.unscoped.includes(:category) diff --git a/spec/fabricators/user_fabricator.rb b/spec/fabricators/user_fabricator.rb index 1a0fcca19a6..ffbc5a9f4d3 100644 --- a/spec/fabricators/user_fabricator.rb +++ b/spec/fabricators/user_fabricator.rb @@ -100,6 +100,8 @@ Fabricator(:trust_level_0, from: :user) { trust_level TrustLevel[0] } Fabricator(:trust_level_1, from: :user) { trust_level TrustLevel[1] } +Fabricator(:trust_level_3, from: :user) { trust_level TrustLevel[3] } + Fabricator(:trust_level_4, from: :user) do name "Leader McElderson" username { sequence(:username) { |i| "tl4#{i}" } } diff --git a/spec/lib/guardian/topic_guardian_spec.rb b/spec/lib/guardian/topic_guardian_spec.rb index 94ff370848f..fc7678efe5b 100644 --- a/spec/lib/guardian/topic_guardian_spec.rb +++ b/spec/lib/guardian/topic_guardian_spec.rb @@ -3,7 +3,8 @@ RSpec.describe TopicGuardian do fab!(:user) { Fabricate(:user) } fab!(:admin) { Fabricate(:admin) } - fab!(:tl3_user) { Fabricate(:leader) } + fab!(:tl3_user) { Fabricate(:trust_level_3) } + fab!(:tl4_user) { Fabricate(:trust_level_4) } fab!(:moderator) { Fabricate(:moderator) } fab!(:category) { Fabricate(:category) } fab!(:group) { Fabricate(:group) } @@ -121,7 +122,6 @@ RSpec.describe TopicGuardian do describe "#can_review_topic?" do it "returns false for TL4 users" do - tl4_user = Fabricate(:user, trust_level: TrustLevel[4]) topic = Fabricate(:topic) expect(Guardian.new(tl4_user).can_review_topic?(topic)).to eq(false) @@ -134,8 +134,6 @@ RSpec.describe TopicGuardian do end it "returns true for TL4 users" do - tl4_user = Fabricate(:user, trust_level: TrustLevel[4]) - expect(Guardian.new(tl4_user).can_create_unlisted_topic?(topic)).to eq(true) end @@ -144,6 +142,20 @@ RSpec.describe TopicGuardian do end end + describe "#can_see_unlisted_topics?" do + it "is allowed for staff users" do + expect(Guardian.new(moderator).can_see_unlisted_topics?).to eq(true) + end + + it "is allowed for TL4 users" do + expect(Guardian.new(tl4_user).can_see_unlisted_topics?).to eq(true) + end + + it "is not allowed for lower level users" do + expect(Guardian.new(tl3_user).can_see_unlisted_topics?).to eq(false) + end + end + # The test cases here are intentionally kept brief because majority of the cases are already handled by # `TopicGuardianCanSeeConsistencyCheck` which we run to ensure that the implementation between `TopicGuardian#can_see_topic_ids` # and `TopicGuardian#can_see_topic?` is consistent. diff --git a/spec/lib/topic_query_spec.rb b/spec/lib/topic_query_spec.rb index ffd62eaa1d0..8ba558a353e 100644 --- a/spec/lib/topic_query_spec.rb +++ b/spec/lib/topic_query_spec.rb @@ -16,6 +16,7 @@ RSpec.describe TopicQuery do fab!(:creator) { Fabricate(:user) } let(:topic_query) { TopicQuery.new(user) } + fab!(:tl4_user) { Fabricate(:trust_level_4) } fab!(:moderator) { Fabricate(:moderator) } fab!(:admin) { Fabricate(:admin) } @@ -795,8 +796,11 @@ RSpec.describe TopicQuery do # includes the invisible topic if you're a moderator expect(TopicQuery.new(moderator).list_latest.topics.include?(invisible_topic)).to eq(true) - # includes the invisible topic if you're an admin" do + # includes the invisible topic if you're an admin expect(TopicQuery.new(admin).list_latest.topics.include?(invisible_topic)).to eq(true) + + # includes the invisible topic if you're a TL4 user + expect(TopicQuery.new(tl4_user).list_latest.topics.include?(invisible_topic)).to eq(true) end context "with sort_order" do