diff --git a/app/controllers/topics_controller.rb b/app/controllers/topics_controller.rb index 0d1681c9a..1b58942ab 100644 --- a/app/controllers/topics_controller.rb +++ b/app/controllers/topics_controller.rb @@ -65,7 +65,7 @@ class TopicsController < ApplicationController rescue Discourse::NotFound if params[:id] topic = Topic.find_by(slug: params[:id].downcase) - return redirect_to_correct_topic(topic, opts[:post_number]) if topic + return redirect_to_correct_topic(topic, opts[:post_number]) if topic && topic.visible end raise Discourse::NotFound end @@ -77,7 +77,14 @@ class TopicsController < ApplicationController discourse_expires_in 1.minute - redirect_to_correct_topic(@topic_view.topic, opts[:post_number]) && return if slugs_do_not_match || (!request.format.json? && params[:slug].nil?) + if !@topic_view.topic.visible && @topic_view.topic.slug != params[:slug] + raise Discourse::NotFound + end + + if slugs_do_not_match || (!request.format.json? && params[:slug].nil?) + redirect_to_correct_topic(@topic_view.topic, opts[:post_number]) + return + end track_visit_to_topic diff --git a/spec/controllers/topics_controller_spec.rb b/spec/controllers/topics_controller_spec.rb index 780e6f4a4..e66a8085c 100644 --- a/spec/controllers/topics_controller_spec.rb +++ b/spec/controllers/topics_controller_spec.rb @@ -532,6 +532,22 @@ describe TopicsController do end end + describe 'show unlisted' do + it 'returns 404 unless exact correct URL' do + topic = Fabricate(:topic, visible: false) + Fabricate(:post, topic: topic) + + xhr :get, :show, topic_id: topic.id, slug: topic.slug + expect(response).to be_success + + xhr :get, :show, topic_id: topic.id, slug: "just-guessing" + expect(response.code).to eq("404") + + xhr :get, :show, id: topic.slug + expect(response.code).to eq("404") + end + end + describe 'show' do let(:topic) { Fabricate(:post).topic }