This commit is contained in:
parent
9a3c8c5bda
commit
a6b5e64e15
11 changed files with 163 additions and 8 deletions
|
@ -146,6 +146,7 @@ class ActivityPub::Activity::Create < ActivityPub::Activity
|
||||||
valid = !Admin::NgWord.reject?("#{@params[:spoiler_text]}\n#{@params[:text]}", uri: @params[:uri], target_type: :status, public: @status_parser.distributable_visibility?)
|
valid = !Admin::NgWord.reject?("#{@params[:spoiler_text]}\n#{@params[:text]}", uri: @params[:uri], target_type: :status, public: @status_parser.distributable_visibility?)
|
||||||
valid = !Admin::NgWord.hashtag_reject?(@tags.size) if valid
|
valid = !Admin::NgWord.hashtag_reject?(@tags.size) if valid
|
||||||
valid = !Admin::NgWord.mention_reject?(@mentions.count { |m| !m.silent }) if valid
|
valid = !Admin::NgWord.mention_reject?(@mentions.count { |m| !m.silent }) if valid
|
||||||
|
valid = !Admin::NgWord.stranger_mention_reject_with_count?(@mentions.count { |m| !m.silent }) if valid && (mention_to_local_stranger? || reference_to_local_stranger?)
|
||||||
valid = !Admin::NgWord.stranger_mention_reject?("#{@params[:spoiler_text]}\n#{@params[:text]}", uri: @params[:uri], target_type: :status, public: @status_parser.distributable_visibility?) if valid && (mention_to_local_stranger? || reference_to_local_stranger?)
|
valid = !Admin::NgWord.stranger_mention_reject?("#{@params[:spoiler_text]}\n#{@params[:text]}", uri: @params[:uri], target_type: :status, public: @status_parser.distributable_visibility?) if valid && (mention_to_local_stranger? || reference_to_local_stranger?)
|
||||||
|
|
||||||
valid
|
valid
|
||||||
|
|
|
@ -34,6 +34,14 @@ class Admin::NgWord
|
||||||
mention_reject?(text.gsub(Account::MENTION_RE)&.count || 0)
|
mention_reject?(text.gsub(Account::MENTION_RE)&.count || 0)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def stranger_mention_reject_with_count?(mention_count)
|
||||||
|
post_stranger_mentions_max.positive? && post_stranger_mentions_max < mention_count
|
||||||
|
end
|
||||||
|
|
||||||
|
def stranger_mention_reject_with_extractor?(text)
|
||||||
|
stranger_mention_reject_with_count?(text.gsub(Account::MENTION_RE)&.count || 0)
|
||||||
|
end
|
||||||
|
|
||||||
private
|
private
|
||||||
|
|
||||||
def include?(text, word)
|
def include?(text, word)
|
||||||
|
@ -62,6 +70,11 @@ class Admin::NgWord
|
||||||
value.is_a?(Integer) && value.positive? ? value : 0
|
value.is_a?(Integer) && value.positive? ? value : 0
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def post_stranger_mentions_max
|
||||||
|
value = Setting.post_stranger_mentions_max
|
||||||
|
value.is_a?(Integer) && value.positive? ? value : 0
|
||||||
|
end
|
||||||
|
|
||||||
def record!(type, text, keyword, options)
|
def record!(type, text, keyword, options)
|
||||||
return unless options[:uri] && options[:target_type]
|
return unless options[:uri] && options[:target_type]
|
||||||
return if options.key?(:public) && !options.delete(:public)
|
return if options.key?(:public) && !options.delete(:public)
|
||||||
|
|
|
@ -50,6 +50,7 @@ class Form::AdminSettings
|
||||||
hide_local_users_for_anonymous
|
hide_local_users_for_anonymous
|
||||||
post_hash_tags_max
|
post_hash_tags_max
|
||||||
post_mentions_max
|
post_mentions_max
|
||||||
|
post_stranger_mentions_max
|
||||||
sensitive_words
|
sensitive_words
|
||||||
sensitive_words_for_full
|
sensitive_words_for_full
|
||||||
authorized_fetch
|
authorized_fetch
|
||||||
|
@ -71,6 +72,7 @@ class Form::AdminSettings
|
||||||
backups_retention_period
|
backups_retention_period
|
||||||
post_hash_tags_max
|
post_hash_tags_max
|
||||||
post_mentions_max
|
post_mentions_max
|
||||||
|
post_stranger_mentions_max
|
||||||
registrations_limit
|
registrations_limit
|
||||||
registrations_limit_per_day
|
registrations_limit_per_day
|
||||||
registrations_start_hour
|
registrations_start_hour
|
||||||
|
|
|
@ -161,11 +161,16 @@ class ActivityPub::ProcessStatusUpdateService < BaseService
|
||||||
end
|
end
|
||||||
|
|
||||||
def valid_status?
|
def valid_status?
|
||||||
!Admin::NgWord.reject?("#{@status_parser.spoiler_text}\n#{@status_parser.text}", uri: @status.uri, target_type: :status) && !Admin::NgWord.hashtag_reject?(@raw_tags.size) && !Admin::NgWord.mention_reject?(@raw_mentions.size)
|
valid = !Admin::NgWord.reject?("#{@status_parser.spoiler_text}\n#{@status_parser.text}", uri: @status.uri, target_type: :status)
|
||||||
|
valid = !Admin::NgWord.hashtag_reject?(@raw_tags.size) if valid
|
||||||
|
|
||||||
|
valid
|
||||||
end
|
end
|
||||||
|
|
||||||
def validate_status_mentions!
|
def validate_status_mentions!
|
||||||
raise AbortError if (mention_to_stranger? || reference_to_stranger?) && Admin::NgWord.stranger_mention_reject?("#{@status.spoiler_text}\n#{@status.text}", uri: @status.uri, target_type: :status)
|
raise AbortError if (mention_to_stranger? || reference_to_stranger?) && Admin::NgWord.stranger_mention_reject?("#{@status.spoiler_text}\n#{@status.text}", uri: @status.uri, target_type: :status)
|
||||||
|
raise AbortError if Admin::NgWord.mention_reject?(@raw_mentions.size)
|
||||||
|
raise AbortError if (mention_to_stranger? || reference_to_stranger?) && Admin::NgWord.stranger_mention_reject_with_count?(@raw_mentions.size)
|
||||||
end
|
end
|
||||||
|
|
||||||
def mention_to_stranger?
|
def mention_to_stranger?
|
||||||
|
|
|
@ -210,10 +210,11 @@ class PostStatusService < BaseService
|
||||||
def validate_status!
|
def validate_status!
|
||||||
raise Mastodon::ValidationError, I18n.t('statuses.contains_ng_words') if Admin::NgWord.reject?("#{@options[:spoiler_text]}\n#{@options[:text]}")
|
raise Mastodon::ValidationError, I18n.t('statuses.contains_ng_words') if Admin::NgWord.reject?("#{@options[:spoiler_text]}\n#{@options[:text]}")
|
||||||
raise Mastodon::ValidationError, I18n.t('statuses.too_many_hashtags') if Admin::NgWord.hashtag_reject_with_extractor?(@text)
|
raise Mastodon::ValidationError, I18n.t('statuses.too_many_hashtags') if Admin::NgWord.hashtag_reject_with_extractor?(@text)
|
||||||
raise Mastodon::ValidationError, I18n.t('statuses.too_many_mentions') if Admin::NgWord.mention_reject_with_extractor?(@text)
|
|
||||||
end
|
end
|
||||||
|
|
||||||
def validate_status_mentions!
|
def validate_status_mentions!
|
||||||
|
raise Mastodon::ValidationError, I18n.t('statuses.too_many_mentions') if Admin::NgWord.mention_reject_with_extractor?(@text)
|
||||||
|
raise Mastodon::ValidationError, I18n.t('statuses.too_many_mentions') if (mention_to_stranger? || reference_to_stranger?) && Admin::NgWord.stranger_mention_reject_with_extractor?(@text)
|
||||||
raise Mastodon::ValidationError, I18n.t('statuses.contains_ng_words') if (mention_to_stranger? || reference_to_stranger?) && Setting.stranger_mention_from_local_ng && Admin::NgWord.stranger_mention_reject?("#{@options[:spoiler_text]}\n#{@options[:text]}")
|
raise Mastodon::ValidationError, I18n.t('statuses.contains_ng_words') if (mention_to_stranger? || reference_to_stranger?) && Setting.stranger_mention_from_local_ng && Admin::NgWord.stranger_mention_reject?("#{@options[:spoiler_text]}\n#{@options[:text]}")
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
|
@ -84,6 +84,7 @@ class UpdateStatusService < BaseService
|
||||||
raise Mastodon::ValidationError, I18n.t('statuses.contains_ng_words') if Admin::NgWord.reject?("#{@options[:spoiler_text]}\n#{@options[:text]}")
|
raise Mastodon::ValidationError, I18n.t('statuses.contains_ng_words') if Admin::NgWord.reject?("#{@options[:spoiler_text]}\n#{@options[:text]}")
|
||||||
raise Mastodon::ValidationError, I18n.t('statuses.too_many_hashtags') if Admin::NgWord.hashtag_reject_with_extractor?(@options[:text] || '')
|
raise Mastodon::ValidationError, I18n.t('statuses.too_many_hashtags') if Admin::NgWord.hashtag_reject_with_extractor?(@options[:text] || '')
|
||||||
raise Mastodon::ValidationError, I18n.t('statuses.too_many_mentions') if Admin::NgWord.mention_reject_with_extractor?(@options[:text] || '')
|
raise Mastodon::ValidationError, I18n.t('statuses.too_many_mentions') if Admin::NgWord.mention_reject_with_extractor?(@options[:text] || '')
|
||||||
|
raise Mastodon::ValidationError, I18n.t('statuses.too_many_mentions') if (mention_to_stranger? || reference_to_stranger?) && Admin::NgWord.stranger_mention_reject_with_extractor?(@options[:text] || '')
|
||||||
end
|
end
|
||||||
|
|
||||||
def validate_status_mentions!
|
def validate_status_mentions!
|
||||||
|
|
|
@ -23,6 +23,9 @@
|
||||||
.fields-group
|
.fields-group
|
||||||
= f.input :post_hash_tags_max, wrapper: :with_label, as: :integer, label: t('admin.ng_words.post_hash_tags_max')
|
= f.input :post_hash_tags_max, wrapper: :with_label, as: :integer, label: t('admin.ng_words.post_hash_tags_max')
|
||||||
|
|
||||||
|
.fields-group
|
||||||
|
= f.input :post_stranger_mentions_max, wrapper: :with_label, as: :integer, label: t('admin.ng_words.post_stranger_mentions_max')
|
||||||
|
|
||||||
.fields-group
|
.fields-group
|
||||||
= f.input :post_mentions_max, wrapper: :with_label, as: :integer, label: t('admin.ng_words.post_mentions_max')
|
= f.input :post_mentions_max, wrapper: :with_label, as: :integer, label: t('admin.ng_words.post_mentions_max')
|
||||||
|
|
||||||
|
|
|
@ -649,6 +649,7 @@ en:
|
||||||
keywords_hint: The first character of the line is "?". to use regular expressions
|
keywords_hint: The first character of the line is "?". to use regular expressions
|
||||||
post_hash_tags_max: Hash tags max for posts
|
post_hash_tags_max: Hash tags max for posts
|
||||||
post_mentions_max: Mentions max for posts
|
post_mentions_max: Mentions max for posts
|
||||||
|
post_stranger_mentions_max: 投稿に設定可能なメンションの最大数 (If the mentions include at least one person who is not a follower of yours)
|
||||||
stranger_mention_from_local_ng: フォローしていないアカウントへのメンションのNGワードを、ローカルユーザーによる投稿にも適用する
|
stranger_mention_from_local_ng: フォローしていないアカウントへのメンションのNGワードを、ローカルユーザーによる投稿にも適用する
|
||||||
stranger_mention_from_local_ng_hint: サーバーの登録が承認制でない場合、あなたのサーバーにもスパムが入り込む可能性があります
|
stranger_mention_from_local_ng_hint: サーバーの登録が承認制でない場合、あなたのサーバーにもスパムが入り込む可能性があります
|
||||||
test_error: Testing is returned any errors
|
test_error: Testing is returned any errors
|
||||||
|
|
|
@ -642,6 +642,7 @@ ja:
|
||||||
keywords_hint: 行を「?」で始めると、正規表現が使えます
|
keywords_hint: 行を「?」で始めると、正規表現が使えます
|
||||||
post_hash_tags_max: 投稿に設定可能なハッシュタグの最大数
|
post_hash_tags_max: 投稿に設定可能なハッシュタグの最大数
|
||||||
post_mentions_max: 投稿に設定可能なメンションの最大数
|
post_mentions_max: 投稿に設定可能なメンションの最大数
|
||||||
|
post_stranger_mentions_max: 投稿に設定可能なメンションの最大数 (メンション先にフォロワー以外を1人でも含む場合)
|
||||||
stranger_mention_from_local_ng: フォローしていないアカウントへのメンションのNGワードを、ローカルユーザーによる投稿にも適用する
|
stranger_mention_from_local_ng: フォローしていないアカウントへのメンションのNGワードを、ローカルユーザーによる投稿にも適用する
|
||||||
stranger_mention_from_local_ng_hint: サーバーの登録が承認制でない場合、あなたのサーバーにもスパムが入り込む可能性があります
|
stranger_mention_from_local_ng_hint: サーバーの登録が承認制でない場合、あなたのサーバーにもスパムが入り込む可能性があります
|
||||||
test_error: NGワードのテストに失敗しました。正規表現のミスが含まれているかもしれません
|
test_error: NGワードのテストに失敗しました。正規表現のミスが含まれているかもしれません
|
||||||
|
|
|
@ -2068,7 +2068,79 @@ RSpec.describe ActivityPub::Activity::Create do
|
||||||
end
|
end
|
||||||
|
|
||||||
context 'when mentions limit is set' do
|
context 'when mentions limit is set' do
|
||||||
let(:post_mentions_max) { 2 }
|
let(:post_mentions_max) { 3 }
|
||||||
|
let(:post_stranger_mentions_max) { 0 }
|
||||||
|
let(:custom_before) { true }
|
||||||
|
let(:mention_recipient_alice) { Fabricate(:account) }
|
||||||
|
let(:mention_recipient_bob) { Fabricate(:account) }
|
||||||
|
let(:mention_recipient_ohagi) { Fabricate(:account) }
|
||||||
|
let(:mention_recipient_ohagi_follow) { true }
|
||||||
|
let(:object_json) do
|
||||||
|
{
|
||||||
|
id: [ActivityPub::TagManager.instance.uri_for(sender), '#bar'].join,
|
||||||
|
type: 'Note',
|
||||||
|
content: 'Lorem ipsum',
|
||||||
|
tag: [
|
||||||
|
{
|
||||||
|
type: 'Mention',
|
||||||
|
href: ActivityPub::TagManager.instance.uri_for(mention_recipient_alice),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
type: 'Mention',
|
||||||
|
href: ActivityPub::TagManager.instance.uri_for(mention_recipient_bob),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
type: 'Mention',
|
||||||
|
href: ActivityPub::TagManager.instance.uri_for(mention_recipient_ohagi),
|
||||||
|
},
|
||||||
|
],
|
||||||
|
}
|
||||||
|
end
|
||||||
|
|
||||||
|
before do
|
||||||
|
Form::AdminSettings.new(post_mentions_max: post_mentions_max, post_stranger_mentions_max: post_stranger_mentions_max).save
|
||||||
|
|
||||||
|
mention_recipient_alice.follow!(sender)
|
||||||
|
mention_recipient_bob.follow!(sender)
|
||||||
|
mention_recipient_ohagi.follow!(sender) if mention_recipient_ohagi_follow
|
||||||
|
|
||||||
|
subject.perform
|
||||||
|
end
|
||||||
|
|
||||||
|
context 'when limit is enough' do
|
||||||
|
it 'creates status' do
|
||||||
|
expect(sender.statuses.first).to_not be_nil
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
context 'when limit is over' do
|
||||||
|
let(:post_mentions_max) { 1 }
|
||||||
|
|
||||||
|
it 'creates status' do
|
||||||
|
expect(sender.statuses.first).to be_nil
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
context 'when limit for stranger is over but normal limit is not reach' do
|
||||||
|
let(:post_stranger_mentions_max) { 1 }
|
||||||
|
|
||||||
|
it 'creates status' do
|
||||||
|
expect(sender.statuses.first).to_not be_nil
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
context 'when limit for stranger is over and following partically' do
|
||||||
|
let(:post_stranger_mentions_max) { 1 }
|
||||||
|
let(:mention_recipient_ohagi_follow) { false }
|
||||||
|
|
||||||
|
it 'creates status' do
|
||||||
|
expect(sender.statuses.first).to be_nil
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
context 'when mentions limit for stranger is set' do
|
||||||
|
let(:post_stranger_mentions_max) { 2 }
|
||||||
let(:custom_before) { true }
|
let(:custom_before) { true }
|
||||||
let(:object_json) do
|
let(:object_json) do
|
||||||
{
|
{
|
||||||
|
@ -2089,7 +2161,7 @@ RSpec.describe ActivityPub::Activity::Create do
|
||||||
end
|
end
|
||||||
|
|
||||||
before do
|
before do
|
||||||
Form::AdminSettings.new(post_mentions_max: post_mentions_max).save
|
Form::AdminSettings.new(post_stranger_mentions_max: post_stranger_mentions_max).save
|
||||||
subject.perform
|
subject.perform
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -2100,7 +2172,7 @@ RSpec.describe ActivityPub::Activity::Create do
|
||||||
end
|
end
|
||||||
|
|
||||||
context 'when limit is over' do
|
context 'when limit is over' do
|
||||||
let(:post_mentions_max) { 1 }
|
let(:post_stranger_mentions_max) { 1 }
|
||||||
|
|
||||||
it 'creates status' do
|
it 'creates status' do
|
||||||
expect(sender.statuses.first).to be_nil
|
expect(sender.statuses.first).to be_nil
|
||||||
|
|
|
@ -742,9 +742,11 @@ RSpec.describe PostStatusService, type: :service do
|
||||||
end
|
end
|
||||||
|
|
||||||
it 'using mentions under limit' do
|
it 'using mentions under limit' do
|
||||||
Fabricate(:account, username: 'a')
|
a = Fabricate(:account, username: 'a')
|
||||||
Fabricate(:account, username: 'b')
|
b = Fabricate(:account, username: 'b')
|
||||||
account = Fabricate(:account)
|
account = Fabricate(:account)
|
||||||
|
a.follow!(account)
|
||||||
|
b.follow!(account)
|
||||||
text = '@a @b'
|
text = '@a @b'
|
||||||
Form::AdminSettings.new(post_mentions_max: 2).save
|
Form::AdminSettings.new(post_mentions_max: 2).save
|
||||||
|
|
||||||
|
@ -755,11 +757,64 @@ RSpec.describe PostStatusService, type: :service do
|
||||||
end
|
end
|
||||||
|
|
||||||
it 'using mentions over limit' do
|
it 'using mentions over limit' do
|
||||||
|
a = Fabricate(:account, username: 'a')
|
||||||
|
b = Fabricate(:account, username: 'b')
|
||||||
|
account = Fabricate(:account)
|
||||||
|
a.follow!(account)
|
||||||
|
b.follow!(account)
|
||||||
|
text = '@a @b'
|
||||||
|
Form::AdminSettings.new(post_mentions_max: 1).save
|
||||||
|
|
||||||
|
expect { subject.call(account, text: text) }.to raise_error Mastodon::ValidationError
|
||||||
|
end
|
||||||
|
|
||||||
|
it 'using mentions for stranger under limit' do
|
||||||
Fabricate(:account, username: 'a')
|
Fabricate(:account, username: 'a')
|
||||||
Fabricate(:account, username: 'b')
|
Fabricate(:account, username: 'b')
|
||||||
account = Fabricate(:account)
|
account = Fabricate(:account)
|
||||||
text = '@a @b'
|
text = '@a @b'
|
||||||
Form::AdminSettings.new(post_mentions_max: 1).save
|
Form::AdminSettings.new(post_stranger_mentions_max: 2).save
|
||||||
|
|
||||||
|
status = subject.call(account, text: text)
|
||||||
|
|
||||||
|
expect(status).to be_persisted
|
||||||
|
expect(status.text).to eq text
|
||||||
|
end
|
||||||
|
|
||||||
|
it 'using mentions for stranger over limit' do
|
||||||
|
Fabricate(:account, username: 'a')
|
||||||
|
Fabricate(:account, username: 'b')
|
||||||
|
account = Fabricate(:account)
|
||||||
|
text = '@a @b'
|
||||||
|
Form::AdminSettings.new(post_stranger_mentions_max: 1).save
|
||||||
|
|
||||||
|
expect { subject.call(account, text: text) }.to raise_error Mastodon::ValidationError
|
||||||
|
end
|
||||||
|
|
||||||
|
it 'using mentions for stranger over limit but normal setting is under limit' do
|
||||||
|
a = Fabricate(:account, username: 'a')
|
||||||
|
b = Fabricate(:account, username: 'b')
|
||||||
|
account = Fabricate(:account)
|
||||||
|
a.follow!(account)
|
||||||
|
b.follow!(account)
|
||||||
|
text = '@a @b'
|
||||||
|
Form::AdminSettings.new(post_mentions_max: 2, post_stranger_mentions_max: 1).save
|
||||||
|
|
||||||
|
status = subject.call(account, text: text)
|
||||||
|
|
||||||
|
expect(status).to be_persisted
|
||||||
|
expect(status.text).to eq text
|
||||||
|
end
|
||||||
|
|
||||||
|
it 'using mentions for stranger over limit but normal setting is under limit when following one only' do
|
||||||
|
a = Fabricate(:account, username: 'a')
|
||||||
|
b = Fabricate(:account, username: 'b')
|
||||||
|
Fabricate(:account, username: 'c')
|
||||||
|
account = Fabricate(:account)
|
||||||
|
a.follow!(account)
|
||||||
|
b.follow!(account)
|
||||||
|
text = '@a @b @c'
|
||||||
|
Form::AdminSettings.new(post_mentions_max: 3, post_stranger_mentions_max: 2).save
|
||||||
|
|
||||||
expect { subject.call(account, text: text) }.to raise_error Mastodon::ValidationError
|
expect { subject.call(account, text: text) }.to raise_error Mastodon::ValidationError
|
||||||
end
|
end
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue