FEATURE: Silence watched word (#13160)

This is a new type of watched word to replace auto_silence_first_post_
regex site setting.
This commit is contained in:
Bianca Nenciu 2021-05-27 19:19:58 +03:00 committed by GitHub
parent 157f10db4c
commit 571ee4537a
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
6 changed files with 36 additions and 2 deletions

View File

@ -10,6 +10,7 @@ class WatchedWord < ActiveRecord::Base
flag: 4, flag: 4,
replace: 5, replace: 5,
tag: 6, tag: 6,
silence: 7
) )
end end

View File

@ -88,6 +88,10 @@ class WordWatcher
word_matches_for_action?(:block, all_matches: true) word_matches_for_action?(:block, all_matches: true)
end end
def should_silence?
word_matches_for_action?(:silence)
end
def word_matches_for_action?(action, all_matches: false) def word_matches_for_action?(action, all_matches: false)
regexp = self.class.word_matcher_regexp(action) regexp = self.class.word_matcher_regexp(action)
if regexp if regexp

View File

@ -4708,6 +4708,7 @@ en:
flag: "Flag" flag: "Flag"
replace: "Replace" replace: "Replace"
tag: "Tag" tag: "Tag"
silence: "Silence"
action_descriptions: action_descriptions:
block: "Prevent posts containing these words from being posted. The user will see an error message when they try to submit their post." block: "Prevent posts containing these words from being posted. The user will see an error message when they try to submit their post."
censor: "Allow posts containing these words, but replace them with characters that hide the censored words." censor: "Allow posts containing these words, but replace them with characters that hide the censored words."
@ -4715,6 +4716,7 @@ en:
flag: "Allow posts containing these words, but flag them as inappropriate so moderators can review them." flag: "Allow posts containing these words, but flag them as inappropriate so moderators can review them."
replace: "Replace words in posts with other words or links" replace: "Replace words in posts with other words or links"
tag: "Automatically tag topics based on first post" tag: "Automatically tag topics based on first post"
silence: "First posts of users containing these words will require approval by staff before they can be seen and the user will be automatically silenced."
form: form:
label: "Has word or phrase" label: "Has word or phrase"
placeholder: "Enter word or phrase (* is a wildcard)" placeholder: "Enter word or phrase (* is a wildcard)"

View File

@ -2562,6 +2562,7 @@ en:
other: "Automatically deactivated after %{count} days of inactivity" other: "Automatically deactivated after %{count} days of inactivity"
activated_by_staff: "Activated by staff" activated_by_staff: "Activated by staff"
new_user_typed_too_fast: "New user typed too fast" new_user_typed_too_fast: "New user typed too fast"
content_matches_auto_silence_regex: "Content matches auto silence regex"
content_matches_auto_block_regex: "Content matches auto block regex" content_matches_auto_block_regex: "Content matches auto block regex"
username: username:
short: "must be at least %{min} characters" short: "must be at least %{min} characters"

View File

@ -54,6 +54,10 @@ class NewPostManager
manager.user.trust_level <= SiteSetting.auto_silence_fast_typers_max_trust_level manager.user.trust_level <= SiteSetting.auto_silence_fast_typers_max_trust_level
end end
def self.auto_silence?(manager)
is_first_post?(manager) && WordWatcher.new("#{manager.args[:title]} #{manager.args[:raw]}").should_silence?
end
def self.matches_auto_silence_regex?(manager) def self.matches_auto_silence_regex?(manager)
args = manager.args args = manager.args
@ -102,7 +106,7 @@ class NewPostManager
return :fast_typer if is_fast_typer?(manager) return :fast_typer if is_fast_typer?(manager)
return :auto_silence_regex if matches_auto_silence_regex?(manager) return :auto_silence_regex if auto_silence?(manager) || matches_auto_silence_regex?(manager)
return :staged if SiteSetting.approve_unless_staged? && user.staged? return :staged if SiteSetting.approve_unless_staged? && user.staged?
@ -168,7 +172,7 @@ class NewPostManager
I18n.with_locale(SiteSetting.default_locale) do I18n.with_locale(SiteSetting.default_locale) do
if is_fast_typer?(manager) if is_fast_typer?(manager)
UserSilencer.silence(manager.user, Discourse.system_user, keep_posts: true, reason: I18n.t("user.new_user_typed_too_fast")) UserSilencer.silence(manager.user, Discourse.system_user, keep_posts: true, reason: I18n.t("user.new_user_typed_too_fast"))
elsif matches_auto_silence_regex?(manager) elsif auto_silence?(manager) || matches_auto_silence_regex?(manager)
UserSilencer.silence(manager.user, Discourse.system_user, keep_posts: true, reason: I18n.t("user.content_matches_auto_silence_regex")) UserSilencer.silence(manager.user, Discourse.system_user, keep_posts: true, reason: I18n.t("user.content_matches_auto_silence_regex"))
elsif reason == :email_spam && is_first_post?(manager) elsif reason == :email_spam && is_first_post?(manager)
UserSilencer.silence(manager.user, Discourse.system_user, keep_posts: true, reason: I18n.t("user.email_in_spam_header")) UserSilencer.silence(manager.user, Discourse.system_user, keep_posts: true, reason: I18n.t("user.email_in_spam_header"))

View File

@ -907,6 +907,28 @@ describe PostsController do
expect(user).to be_silenced expect(user).to be_silenced
end end
it 'silences correctly based on silence watched words' do
SiteSetting.watched_words_regular_expressions = true
WatchedWord.create!(action: WatchedWord.actions[:silence], word: 'I love candy')
WatchedWord.create!(action: WatchedWord.actions[:silence], word: 'i eat s[1-5]')
post "/posts.json", params: {
raw: 'this is the test content',
title: 'when I eat s3 sometimes when not looking'
}
expect(response.status).to eq(200)
parsed = response.parsed_body
expect(parsed["action"]).to eq("enqueued")
reviewable = ReviewableQueuedPost.find_by(created_by: user)
score = reviewable.reviewable_scores.first
expect(score.reason).to eq('auto_silence_regex')
user.reload
expect(user).to be_silenced
end
it "can send a message to a group" do it "can send a message to a group" do
group = Group.create(name: 'test_group', messageable_level: Group::ALIAS_LEVELS[:nobody]) group = Group.create(name: 'test_group', messageable_level: Group::ALIAS_LEVELS[:nobody])
user1 = user user1 = user