Fix: Don't show non-members as readers when the post is a whisper

Fix: Don’t show non-members as readers when the post is a whisper

diff --git a/app/controllers/post_readers_controller.rb b/app/controllers/post_readers_controller.rb
index e70d49b..fdba060 100644
--- a/app/controllers/post_readers_controller.rb
+++ b/app/controllers/post_readers_controller.rb
@@ -4,16 +4,20 @@ class PostReadersController < ApplicationController
   requires_login
 
   def index
-    post = Post.includes(topic: %i[allowed_groups]).find(params[:id])
-    read_state = post.topic.allowed_groups.any? { |g| g.publish_read_state? && g.users.include?(current_user) }
-    raise Discourse::InvalidAccess unless read_state
+    post = Post.includes(topic: %i[topic_allowed_groups topic_allowed_users]).find(params[:id])
+    ensure_can_see_readers!(post)
 
     readers = User
-      .joins(:topic_users)
       .where(staged: false)
+      .where.not(id: post.user_id)
+      .joins(:topic_users)
       .where.not(topic_users: { last_read_post_number: nil })
       .where('topic_users.topic_id = ? AND topic_users.last_read_post_number >= ?', post.topic_id, post.post_number)
-      .where.not(id: post.user_id)
+
+    if post.whisper?
+      non_group_members = post.topic.topic_allowed_users.map(&:user_id)
+      readers = readers.where.not(id: non_group_members)
+    end
 
     readers = readers.map do |r|
       {
@@ -25,4 +29,15 @@ class PostReadersController < ApplicationController
 
     render_json_dump(post_readers: readers)
   end
+
+  private
+
+  def ensure_can_see_readers!(post)
+    show_readers = GroupUser
+      .where(user: current_user)
+      .joins(:group)
+      .where(groups: { id: post.topic.topic_allowed_groups.map(&:group_id), publish_read_state: true }).exists?
+
+    raise Discourse::InvalidAccess unless show_readers
+  end
 end
diff --git a/spec/requests/post_readers_controller_spec.rb b/spec/requests/post_readers_controller_spec.rb
index 954e14b..1c4fbce 100644
--- a/spec/requests/post_readers_controller_spec.rb
+++ b/spec/requests/post_readers_controller_spec.rb
@@ -76,6 +76,18 @@ describe PostReadersController do
 
         expect(readers).to be_empty
       end
+
+      it 'xxxxx' do
+        @post.update(post_type: Post.types[:whisper])
+        non_member_reader = Fabricate(:user)
+        @group_message.allowed_users << non_member_reader
+        TopicUser.create!(user: non_member_reader, topic: @group_message, last_read_post_number: 4)
+
+        get '/post_readers.json', params: { id: @post.id }
+        readers = JSON.parse(response.body)['post_readers']
+
+        expect(readers).to be_empty
+      end
     end
 
     def assert_reader_is_correctly_serialized(reader_data, reader, post)

GitHub sha: 08b7a3fd

1 Like

I don’t think we should leave x-rated comments in the Discourse codebase.

1 Like

^^^ this needs your attention @SamSaffron

I already fixed it here.

2 Likes