mirror of
https://github.com/discourse/discourse.git
synced 2025-02-16 21:12:46 +08:00
![Sam Saffron](/assets/img/avatar_default.png)
This reduces chances of errors where consumers of strings mutate inputs and reduces memory usage of the app. Test suite passes now, but there may be some stuff left, so we will run a few sites on a branch prior to merging
82 lines
2.1 KiB
Ruby
82 lines
2.1 KiB
Ruby
# frozen_string_literal: true
|
|
|
|
class SpamRule::AutoSilence
|
|
|
|
attr_reader :group_message
|
|
|
|
def initialize(user, post = nil)
|
|
@user = user
|
|
@post = post
|
|
end
|
|
|
|
def perform
|
|
I18n.with_locale(SiteSetting.default_locale) do
|
|
silence_user if should_autosilence?
|
|
end
|
|
end
|
|
|
|
def self.prevent_posting?(user)
|
|
user.blank? || user.silenced? || new(user).should_autosilence?
|
|
end
|
|
|
|
def should_autosilence?
|
|
return false if @user.blank?
|
|
return false if @user.staged?
|
|
return false if @user.has_trust_level?(TrustLevel[1])
|
|
|
|
if SiteSetting.spam_score_to_silence_new_user > 0 &&
|
|
SiteSetting.num_users_to_silence_new_user > 0 &&
|
|
user_spam_stats.total_spam_score >= SiteSetting.spam_score_to_silence_new_user &&
|
|
user_spam_stats.spam_user_count >= SiteSetting.num_users_to_silence_new_user
|
|
return true
|
|
end
|
|
|
|
false
|
|
end
|
|
|
|
def user_spam_stats
|
|
return @user_spam_stats if @user_spam_stats
|
|
|
|
params = {
|
|
user_id: @user.id,
|
|
spam_type: PostActionType.types[:spam],
|
|
pending: ReviewableScore.statuses[:pending],
|
|
agreed: ReviewableScore.statuses[:agreed]
|
|
}
|
|
|
|
result = DB.query(<<~SQL, params)
|
|
SELECT COALESCE(SUM(rs.score), 0) AS total_spam_score,
|
|
COUNT(DISTINCT rs.user_id) AS spam_user_count
|
|
FROM reviewables AS r
|
|
INNER JOIN reviewable_scores AS rs ON rs.reviewable_id = r.id
|
|
WHERE r.target_created_by_id = :user_id
|
|
AND rs.reviewable_score_type = :spam_type
|
|
AND rs.status IN (:pending, :agreed)
|
|
SQL
|
|
|
|
@user_spam_stats = result[0]
|
|
end
|
|
|
|
def flagged_post_ids
|
|
Post.where(user_id: @user.id)
|
|
.where('spam_count > 0 OR off_topic_count > 0 OR inappropriate_count > 0')
|
|
.pluck(:id)
|
|
end
|
|
|
|
def silence_user
|
|
Post.transaction do
|
|
|
|
silencer = UserSilencer.new(
|
|
@user,
|
|
Discourse.system_user,
|
|
message: :too_many_spam_flags,
|
|
post_id: @post&.id
|
|
)
|
|
|
|
if silencer.silence && SiteSetting.notify_mods_when_user_silenced
|
|
@group_message = GroupMessage.create(Group[:moderators].name, :user_automatically_silenced, user: @user, limit_once_per: false)
|
|
end
|
|
end
|
|
end
|
|
end
|