mirror of
https://github.com/discourse/discourse.git
synced 2026-08-05 17:25:34 +08:00
## Summary Prevent the exposure of unlisted topic metadata in the categories response by enforcing live visibility checks on featured topics. Additionally, the UserSilencer service now correctly removes featured topic records when bulk-hiding topics from new users, ensuring stale records do not bypass visibility constraints. ## Source - Patch Triage: https://patch.discourse.org/patch-triage/1427 Co-authored-by: discourse-patch-triage <272280883+discourse-patch-triage[bot]@users.noreply.github.com>
128 lines
3.4 KiB
Ruby
Vendored
128 lines
3.4 KiB
Ruby
Vendored
# frozen_string_literal: true
|
|
|
|
class UserSilencer
|
|
attr_reader :user_history
|
|
|
|
def initialize(user, by_user = nil, opts = {})
|
|
@user, @by_user, @opts = user, by_user, opts
|
|
end
|
|
|
|
def self.silence(user, by_user = nil, opts = {})
|
|
UserSilencer.new(user, by_user, opts).silence
|
|
end
|
|
|
|
def self.auto_silence(user, by_user = nil, opts = {})
|
|
UserSilencer.new(user, by_user, opts).auto_silence
|
|
end
|
|
|
|
def self.unsilence(user, by_user = nil, opts = {})
|
|
UserSilencer.new(user, by_user, opts).unsilence
|
|
end
|
|
|
|
def self.was_silenced_for?(post)
|
|
return false if post.blank?
|
|
|
|
UserHistory.where(action: UserHistory.actions[:silence_user], post: post).exists?
|
|
end
|
|
|
|
def silence
|
|
return false if @user.staff?
|
|
hide_posts unless @opts[:keep_posts]
|
|
return false if @user.silenced_till.present?
|
|
@user.silenced_till = @opts[:silenced_till] || 1000.years.from_now
|
|
if @user.save
|
|
message_type = @opts[:message] || :silenced_by_staff
|
|
|
|
details = StaffMessageFormat.new(:silence, @opts[:reason], @opts[:message_body]).format
|
|
|
|
context = "#{message_type}: #{@opts[:reason]}"
|
|
|
|
if @by_user
|
|
log_params = { context: context, details: details, reviewable_id: @opts[:reviewable_id] }
|
|
log_params[:post_id] = @opts[:post_id].to_i if @opts[:post_id]
|
|
|
|
@user_history = StaffActionLogger.new(@by_user).log_silence_user(@user, log_params)
|
|
end
|
|
|
|
silence_message_params = {}
|
|
DiscourseEvent.trigger(
|
|
:user_silenced,
|
|
user: @user,
|
|
silenced_by: @by_user,
|
|
reason: @opts[:reason],
|
|
message: @opts[:message_body],
|
|
user_history: @user_history,
|
|
post_id: @opts[:post_id],
|
|
silenced_till: @user.silenced_till,
|
|
silenced_at: DateTime.now,
|
|
silence_message_params: silence_message_params,
|
|
)
|
|
|
|
silence_message_params.merge!(post_alert_options: { skip_send_email: true })
|
|
SystemMessage.create(@user, message_type, silence_message_params)
|
|
true
|
|
end
|
|
end
|
|
|
|
def auto_silence
|
|
if silence
|
|
notify_moderators
|
|
true
|
|
else
|
|
false
|
|
end
|
|
end
|
|
|
|
def hide_posts
|
|
return unless @user.trust_level == TrustLevel[0]
|
|
|
|
Post
|
|
.where(user_id: @user.id)
|
|
.where("created_at > ?", 24.hours.ago)
|
|
.update_all(
|
|
[
|
|
"hidden = true, hidden_reason_id = COALESCE(hidden_reason_id, ?)",
|
|
Post.hidden_reasons[:new_user_spam_threshold_reached],
|
|
],
|
|
)
|
|
topic_ids =
|
|
Post
|
|
.where(user_id: @user.id, post_number: 1)
|
|
.where("created_at > ?", 24.hours.ago)
|
|
.pluck(:topic_id)
|
|
unless topic_ids.empty?
|
|
Topic.where(id: topic_ids).update_all(visible: false)
|
|
CategoryFeaturedTopic.where(topic_id: topic_ids).delete_all
|
|
end
|
|
end
|
|
|
|
def unsilence
|
|
@user.silenced_till = nil
|
|
if @user.save
|
|
DiscourseEvent.trigger(:user_unsilenced, user: @user, by_user: @by_user)
|
|
SystemMessage.create(@user, :unsilenced)
|
|
if @by_user
|
|
StaffActionLogger.new(@by_user).log_unsilence_user(
|
|
@user,
|
|
reviewable_id: @opts[:reviewable_id],
|
|
)
|
|
end
|
|
end
|
|
end
|
|
|
|
private
|
|
|
|
def notify_moderators
|
|
return if !SiteSetting.notify_mods_when_user_silenced
|
|
|
|
GroupMessage.create(
|
|
Group[:moderators].name,
|
|
@opts[:reason] ? :user_automatically_silenced_with_reason : :user_automatically_silenced,
|
|
user: @user,
|
|
limit_once_per: false,
|
|
message_params: {
|
|
reason: @opts[:reason],
|
|
},
|
|
)
|
|
end
|
|
end
|