FIX: hide rss feed & json if a user profile is hidden.

FIX: hide rss feed & json if a user profile is hidden.

diff --git a/app/controllers/list_controller.rb b/app/controllers/list_controller.rb
index 5eadbbc..069768c 100644
--- a/app/controllers/list_controller.rb
+++ b/app/controllers/list_controller.rb
@@ -121,6 +121,8 @@ class ListController < ApplicationController
   def topics_by
     list_opts = build_topic_list_options
     target_user = fetch_user_from_params({ include_inactive: current_user.try(:staff?) || (current_user && SiteSetting.show_inactive_accounts) }, [:user_stat, :user_option])
+    ensure_can_see_profile!(target_user)
+
     list = generate_list_for("topics_by", target_user, list_opts)
     list.more_topics_url = construct_url_with(:next, list_opts)
     list.prev_topics_url = construct_url_with(:prev, list_opts)
@@ -205,6 +207,7 @@ class ListController < ApplicationController
   def user_topics_feed
     discourse_expires_in 1.minute
     target_user = fetch_user_from_params
+    ensure_can_see_profile!(target_user)
 
     @title = "#{SiteSetting.title} - #{I18n.t("rss_description.user_topics", username: target_user.username)}"
     @link = "#{Discourse.base_url}/u/#{target_user.username}/activity/topics"
@@ -385,6 +388,10 @@ class ListController < ApplicationController
     public_send(method, opts.merge(page_params)).sub('.json?', '?')
   end
 
+  def ensure_can_see_profile!(target_user = nil)
+    raise Discourse::NotFound unless guardian.can_see_profile?(target_user)
+  end
+
   def self.best_period_for(previous_visit_at, category_id = nil)
     default_period = ((category_id && Category.where(id: category_id).pluck_first(:default_top_period)) ||
           SiteSetting.top_page_default_timeframe).to_sym
diff --git a/app/controllers/posts_controller.rb b/app/controllers/posts_controller.rb
index 4ee3b29..63ef5bb 100644
--- a/app/controllers/posts_controller.rb
+++ b/app/controllers/posts_controller.rb
@@ -106,6 +106,7 @@ class PostsController < ApplicationController
   def user_posts_feed
     params.require(:username)
     user = fetch_user_from_params
+    raise Discourse::NotFound unless guardian.can_see_profile?(user)
 
     posts = Post.public_posts
       .where(user_id: user.id)
diff --git a/app/controllers/user_badges_controller.rb b/app/controllers/user_badges_controller.rb
index ddb5a3e..0abbfec 100644
--- a/app/controllers/user_badges_controller.rb
+++ b/app/controllers/user_badges_controller.rb
@@ -33,6 +33,7 @@ class UserBadgesController < ApplicationController
     params.permit [:grouped]
 
     user = fetch_user_from_params(include_inactive: current_user.try(:staff?) || (current_user && SiteSetting.show_inactive_accounts))
+    raise Discourse::NotFound unless guardian.can_see_profile?(user)
     user_badges = user.user_badges
 
     if params[:grouped]
diff --git a/spec/requests/list_controller_spec.rb b/spec/requests/list_controller_spec.rb
index bc913c5..710b044 100644
--- a/spec/requests/list_controller_spec.rb
+++ b/spec/requests/list_controller_spec.rb
@@ -524,6 +524,12 @@ RSpec.describe ListController do
       json = response.parsed_body
       expect(json["topic_list"]["topics"].size).to eq(2)
     end
+
+    it "returns 404 if `hide_profile_and_presence` user option is checked" do
+      user.user_option.update_columns(hide_profile_and_presence: true)
+      get "/topics/created-by/#{user.username}.json"
+      expect(response.status).to eq(404)
+    end
   end
 
   describe "private_messages" do
@@ -622,4 +628,12 @@ RSpec.describe ListController do
       expect(ListController.best_periods_for(nil, :daily)).to eq([:daily, :all])
     end
   end
+
+  describe "user_topics_feed" do
+    it "returns 404 if `hide_profile_and_presence` user option is checked" do
+      user.user_option.update_columns(hide_profile_and_presence: true)
+      get "/u/#{user.username}/activity/topics.rss"
+      expect(response.status).to eq(404)
+    end
+  end
 end
diff --git a/spec/requests/posts_controller_spec.rb b/spec/requests/posts_controller_spec.rb
index e9ed6c4..f5ef93c 100644
--- a/spec/requests/posts_controller_spec.rb
+++ b/spec/requests/posts_controller_spec.rb
@@ -1644,6 +1644,16 @@ describe PostsController do
       expect(body).to_not include(private_post.topic.slug)
       expect(body).to include(public_post.topic.slug)
     end
+
+    it "returns 404 if `hide_profile_and_presence` user option is checked" do
+      user.user_option.update_columns(hide_profile_and_presence: true)
+
+      get "/u/#{user.username}/activity.rss"
+      expect(response.status).to eq(404)
+
+      get "/u/#{user.username}/activity.json"
+      expect(response.status).to eq(404)
+    end
   end
 
   describe '#latest' do
diff --git a/spec/requests/user_badges_controller_spec.rb b/spec/requests/user_badges_controller_spec.rb
index 1c19e01..0adf411 100644
--- a/spec/requests/user_badges_controller_spec.rb
+++ b/spec/requests/user_badges_controller_spec.rb
@@ -44,6 +44,13 @@ describe UserBadgesController do
       expect(parsed["user_badges"].length).to eq(1)
     end
 
+    it "returns 404 if `hide_profile_and_presence` user option is checked" do
+      user.user_option.update_columns(hide_profile_and_presence: true)
+
+      get "/user-badges/#{user.username}.json"
+      expect(response.status).to eq(404)
+    end
+
     it 'returns user_badges for a user with period in username' do
       user.update!(username: "myname.test")
       get "/user-badges/#{user.username}", xhr: true

GitHub sha: 7fe414d3

1 Like

This commit has been mentioned on Discourse Meta. There might be relevant details there:

https://meta.discourse.org/t/data-privacy-concern/153787/2