FIX: whispers should not be revealed in reply to, or reply expansion

FEATURE: mark whisper as experimental
FIX: badges should never apply to whispers
This commit is contained in:
Sam 2015-09-25 10:15:58 +10:00
parent 6b07575632
commit 2422289c8b
6 changed files with 40 additions and 14 deletions

View File

@ -181,7 +181,7 @@ class PostsController < ApplicationController
def reply_history def reply_history
post = find_post_from_params post = find_post_from_params
render_serialized(post.reply_history(params[:max_replies].to_i), PostSerializer) render_serialized(post.reply_history(params[:max_replies].to_i, guardian), PostSerializer)
end end
def destroy def destroy
@ -237,7 +237,8 @@ class PostsController < ApplicationController
# Direct replies to this post # Direct replies to this post
def replies def replies
post = find_post_from_params post = find_post_from_params
render_serialized(post.replies, PostSerializer) replies = post.replies.secured(guardian)
render_serialized(replies, PostSerializer)
end end
def revisions def revisions

View File

@ -61,6 +61,7 @@ class Post < ActiveRecord::Base
scope :private_posts, -> { joins(:topic).where('topics.archetype = ?', Archetype.private_message) } scope :private_posts, -> { joins(:topic).where('topics.archetype = ?', Archetype.private_message) }
scope :with_topic_subtype, ->(subtype) { joins(:topic).where('topics.subtype = ?', subtype) } scope :with_topic_subtype, ->(subtype) { joins(:topic).where('topics.subtype = ?', subtype) }
scope :visible, -> { joins(:topic).where('topics.visible = true').where(hidden: false) } scope :visible, -> { joins(:topic).where('topics.visible = true').where(hidden: false) }
scope :secured, lambda { |guardian| where('posts.post_type in (?)', Topic.visible_post_types(guardian && guardian.user))}
delegate :username, to: :user delegate :username, to: :user
@ -108,12 +109,11 @@ class Post < ActiveRecord::Base
type: type type: type
} }
# Whispers should not be published to everyone if Topic.visible_post_types.include?(post_type)
if post_type == Post.types[:whisper] MessageBus.publish(channel, msg, group_ids: topic.secure_group_ids)
else
user_ids = User.where('admin or moderator or id = ?', user_id).pluck(:id) user_ids = User.where('admin or moderator or id = ?', user_id).pluck(:id)
MessageBus.publish(channel, msg, user_ids: user_ids) MessageBus.publish(channel, msg, user_ids: user_ids)
else
MessageBus.publish(channel, msg, group_ids: topic.secure_group_ids)
end end
end end
@ -521,7 +521,7 @@ class Post < ActiveRecord::Base
private_posts.with_topic_subtype(topic_subtype).where('posts.created_at > ?', since_days_ago.days.ago).group('date(posts.created_at)').order('date(posts.created_at)').count private_posts.with_topic_subtype(topic_subtype).where('posts.created_at > ?', since_days_ago.days.ago).group('date(posts.created_at)').order('date(posts.created_at)').count
end end
def reply_history(max_replies=100) def reply_history(max_replies=100, guardian=nil)
post_ids = Post.exec_sql("WITH RECURSIVE breadcrumb(id, reply_to_post_number) AS ( post_ids = Post.exec_sql("WITH RECURSIVE breadcrumb(id, reply_to_post_number) AS (
SELECT p.id, p.reply_to_post_number FROM posts AS p SELECT p.id, p.reply_to_post_number FROM posts AS p
WHERE p.id = :post_id WHERE p.id = :post_id
@ -537,7 +537,7 @@ class Post < ActiveRecord::Base
# [1,2,3][-10,-1] => nil # [1,2,3][-10,-1] => nil
post_ids = (post_ids[(0-max_replies)..-1] || post_ids) post_ids = (post_ids[(0-max_replies)..-1] || post_ids)
Post.where(id: post_ids).includes(:user, :topic).order(:id).to_a Post.secured(guardian).where(id: post_ids).includes(:user, :topic).order(:id).to_a
end end
def revert_to(number) def revert_to(number)
@ -586,7 +586,9 @@ class Post < ActiveRecord::Base
return if post.nil? return if post.nil?
post_reply = post.post_replies.new(reply_id: id) post_reply = post.post_replies.new(reply_id: id)
if post_reply.save if post_reply.save
Post.where(id: post.id).update_all ['reply_count = reply_count + 1'] if Topic.visible_post_types.include?(self.post_type)
Post.where(id: post.id).update_all ['reply_count = reply_count + 1']
end
end end
end end

View File

@ -38,7 +38,7 @@ WITH cte as (
JOIN posts p ON p.topic_id = t.id JOIN posts p ON p.topic_id = t.id
WHERE p.deleted_at IS NULL AND WHERE p.deleted_at IS NULL AND
NOT p.hidden AND NOT p.hidden AND
p.post_type <> #{Post.types[:whisper]} AND p.post_type in (#{Topic.visible_post_types.join(",")}) AND
p.user_id <> t.user_id AND p.user_id <> t.user_id AND
p.user_id <> t.last_post_user_id p.user_id <> t.last_post_user_id
#{filter} #{filter}
@ -82,7 +82,7 @@ SQL
private private
def update_participant_count def update_participant_count
count = topic.posts.where('NOT hidden AND post_type <> ?', Post.types[:whisper]).count('distinct user_id') count = topic.posts.where('NOT hidden AND post_type in (?)', Topic.visible_post_types).count('distinct user_id')
topic.update_columns(participant_count: count) topic.update_columns(participant_count: count)
end end
end end

View File

@ -897,7 +897,7 @@ en:
email_token_grace_period_hours: "Forgot password / activate account tokens are still valid for a grace period of (n) hours after being redeemed." email_token_grace_period_hours: "Forgot password / activate account tokens are still valid for a grace period of (n) hours after being redeemed."
enable_badges: "Enable the badge system" enable_badges: "Enable the badge system"
enable_whispers: "Allow users to whisper to staff" enable_whispers: "Allow staff private communication within topic. (experimental)"
allow_index_in_robots_txt: "Specify in robots.txt that this site is allowed to be indexed by web search engines." allow_index_in_robots_txt: "Specify in robots.txt that this site is allowed to be indexed by web search engines."
email_domains_blacklist: "A pipe-delimited list of email domains that users are not allowed to register accounts with. Example: mailinator.com|trashmail.net" email_domains_blacklist: "A pipe-delimited list of email domains that users are not allowed to register accounts with. Example: mailinator.com|trashmail.net"

View File

@ -0,0 +1,22 @@
class ExcludeWhispersFromBadges < ActiveRecord::Migration
def up
execute "DROP VIEW badge_posts"
execute "CREATE VIEW badge_posts AS
SELECT p.*
FROM posts p
JOIN topics t ON t.id = p.topic_id
JOIN categories c ON c.id = t.category_id
WHERE c.allow_badges AND
p.deleted_at IS NULL AND
t.deleted_at IS NULL AND
NOT c.read_restricted AND
t.visible AND
p.post_type IN (1,2,3)
"
end
def down
# nada, nothing to do just keep good view
end
end

View File

@ -141,8 +141,9 @@ describe PostsController do
end end
it 'asks post for replies' do it 'asks post for replies' do
Post.any_instance.expects(:replies) p1 = Fabricate(:post)
xhr :get, :replies, post_id: post.id xhr :get, :replies, post_id: p1.id
expect(response.status).to eq(200)
end end
end end