diff --git a/app/controllers/topics_controller.rb b/app/controllers/topics_controller.rb index 9b453855b79..07a2a6b0397 100644 --- a/app/controllers/topics_controller.rb +++ b/app/controllers/topics_controller.rb @@ -453,6 +453,7 @@ class TopicsController < ApplicationController params.require(:duration) if based_on_last_post topic = Topic.find_by(id: params[:topic_id]) + guardian.ensure_can_see!(topic) guardian.ensure_can_moderate!(topic) options = { diff --git a/app/jobs/regular/publish_topic_to_category.rb b/app/jobs/regular/publish_topic_to_category.rb index 79df028007c..ca0010eae02 100644 --- a/app/jobs/regular/publish_topic_to_category.rb +++ b/app/jobs/regular/publish_topic_to_category.rb @@ -9,6 +9,8 @@ module Jobs topic = topic_timer.topic return if topic.blank? + return unless Guardian.new(topic_timer.user).can_see?(topic) + TopicTimer.transaction do TopicPublisher.new(topic, Discourse.system_user, topic_timer.category_id).publish! end diff --git a/spec/jobs/publish_topic_to_category_spec.rb b/spec/jobs/publish_topic_to_category_spec.rb index 559065f750e..7ec605e6e64 100644 --- a/spec/jobs/publish_topic_to_category_spec.rb +++ b/spec/jobs/publish_topic_to_category_spec.rb @@ -67,6 +67,8 @@ RSpec.describe Jobs::PublishTopicToCategory do .to change { topic.private_message? }.to(true) end + topic.allowed_users << topic.public_topic_timer.user + now = freeze_time message = MessageBus.track_publish do @@ -85,6 +87,35 @@ RSpec.describe Jobs::PublishTopicToCategory do expect(message.data[:reload_topic]).to be_present expect(message.data[:refresh_stream]).to be_present end + + it "does nothing if the user can't see the PM" do + non_participant_TL4_user = Fabricate(:trust_level_4) + topic.convert_to_private_message(Discourse.system_user) + timer = topic.public_topic_timer + timer.update!(user: non_participant_TL4_user) + + described_class.new.execute(topic_timer_id: topic.public_topic_timer.id) + + topic.reload + expect(topic.private_message?).to eq(true) + expect(topic.category).not_to eq(another_category) + end + + it "works if the user can see the PM" do + tl4_user = Fabricate(:trust_level_4) + topic.convert_to_private_message(Discourse.system_user) + + topic.allowed_users << tl4_user + + timer = topic.public_topic_timer + timer.update!(user: tl4_user) + + described_class.new.execute(topic_timer_id: topic.public_topic_timer.id) + + topic.reload + expect(topic.private_message?).to eq(false) + expect(topic.category).to eq(another_category) + end end describe 'when new category has a default auto-close' do diff --git a/spec/requests/topics_controller_spec.rb b/spec/requests/topics_controller_spec.rb index 6de7c1f7493..c9181814057 100644 --- a/spec/requests/topics_controller_spec.rb +++ b/spec/requests/topics_controller_spec.rb @@ -3028,6 +3028,23 @@ RSpec.describe TopicsController do end end end + + context 'when logged in as a TL4 user' do + it "raises an error if the user can't see the topic" do + user.update!(trust_level: TrustLevel[4]) + sign_in(user) + + pm_topic = Fabricate(:private_message_topic) + + post "/t/#{pm_topic.id}/timer.json", params: { + time: '24', + status_type: TopicTimer.types[1] + } + + expect(response.status).to eq(403) + expect(response.parsed_body["error_type"]).to eq('invalid_access') + end + end end describe '#invite' do