From 7387125915ba3f7d6d1b6791b0cf1034d8c4c3b4 Mon Sep 17 00:00:00 2001 From: KMY Date: Tue, 27 Feb 2024 08:28:57 +0900 Subject: [PATCH] =?UTF-8?q?Add:=20#605=20=E3=83=AA=E3=83=A2=E3=83=BC?= =?UTF-8?q?=E3=83=88=E6=8A=95=E7=A8=BF=E3=81=AB=E9=81=A9=E7=94=A8=E3=81=99?= =?UTF-8?q?=E3=82=8B=E3=82=BB=E3=83=B3=E3=82=B7=E3=83=86=E3=82=A3=E3=83=96?= =?UTF-8?q?=E3=83=AF=E3=83=BC=E3=83=89=E8=A8=AD=E5=AE=9A?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../admin/sensitive_words_controller.rb | 4 +- app/lib/activitypub/activity/create.rb | 9 +++++ app/models/admin/sensitive_word.rb | 19 ++++++++- app/models/form/admin_settings.rb | 5 +++ .../process_status_update_service.rb | 10 +++++ app/services/post_status_service.rb | 3 +- app/services/update_status_service.rb | 3 +- .../admin/sensitive_words/show.html.haml | 9 +++++ config/locales/en.yml | 8 +++- config/locales/ja.yml | 8 +++- spec/lib/activitypub/activity/create_spec.rb | 39 +++++++++++++++++++ .../process_status_update_service_spec.rb | 37 ++++++++++++++++++ 12 files changed, 146 insertions(+), 8 deletions(-) diff --git a/app/controllers/admin/sensitive_words_controller.rb b/app/controllers/admin/sensitive_words_controller.rb index eaa6ae802eb3b4..f98fc4202da4ee 100644 --- a/app/controllers/admin/sensitive_words_controller.rb +++ b/app/controllers/admin/sensitive_words_controller.rb @@ -34,7 +34,9 @@ def create def test_words sensitive_words = settings_params['sensitive_words'].split(/\r\n|\r|\n/) sensitive_words_for_full = settings_params['sensitive_words_for_full'].split(/\r\n|\r|\n/) - Admin::NgWord.reject_with_custom_words?('Sample text', sensitive_words + sensitive_words_for_full) + sensitive_words_all = settings_params['sensitive_words_all'].split(/\r\n|\r|\n/) + sensitive_words_all_for_full = settings_params['sensitive_words_all_for_full'].split(/\r\n|\r|\n/) + Admin::NgWord.reject_with_custom_words?('Sample text', sensitive_words + sensitive_words_for_full + sensitive_words_all + sensitive_words_all_for_full) end def after_update_redirect_path diff --git a/app/lib/activitypub/activity/create.rb b/app/lib/activitypub/activity/create.rb index 21646524ea8d4c..e7723a6958a05b 100644 --- a/app/lib/activitypub/activity/create.rb +++ b/app/lib/activitypub/activity/create.rb @@ -80,6 +80,7 @@ def process_status @raw_mention_uris = [] process_status_params + process_sensitive_words process_tags process_audience @@ -143,6 +144,14 @@ def process_status_params } end + def process_sensitive_words + return unless %i(public public_unlisted login).include?(@params[:visibility].to_sym) && Admin::SensitiveWord.sensitive?(@params[:text], @params[:spoiler_text], local: false) + + @params[:text] = Admin::SensitiveWord.modified_text(@params[:text], @params[:spoiler_text]) + @params[:spoiler_text] = Admin::SensitiveWord.alternative_text + @params[:sensitive] = true + end + def valid_status? 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, uri: @params[:uri], target_type: :status, public: @status_parser.distributable_visibility?, text: "#{@params[:spoiler_text]}\n#{@params[:text]}") if valid diff --git a/app/models/admin/sensitive_word.rb b/app/models/admin/sensitive_word.rb index ec905fe0759022..8f9421f5b909e1 100644 --- a/app/models/admin/sensitive_word.rb +++ b/app/models/admin/sensitive_word.rb @@ -2,8 +2,13 @@ class Admin::SensitiveWord class << self - def sensitive?(text, spoiler_text) + def sensitive?(text, spoiler_text, local: true) exposure_text = spoiler_text.presence || text + + sensitive = (spoiler_text.blank? && sensitive_words_all.any? { |word| include?(text, word) }) || + sensitive_words_all_for_full.any? { |word| include?(exposure_text, word) } + return sensitive if sensitive || !local + (spoiler_text.blank? && sensitive_words.any? { |word| include?(text, word) }) || sensitive_words_for_full.any? { |word| include?(exposure_text, word) } end @@ -12,6 +17,10 @@ def modified_text(text, spoiler_text) spoiler_text.present? ? "#{spoiler_text}\n\n#{text}" : text end + def alternative_text + Setting.auto_warning_text.presence || I18n.t('admin.sensitive_words.alert') || 'CW' + end + private def include?(text, word) @@ -29,5 +38,13 @@ def sensitive_words def sensitive_words_for_full Setting.sensitive_words_for_full || [] end + + def sensitive_words_all + Setting.sensitive_words_all || [] + end + + def sensitive_words_all_for_full + Setting.sensitive_words_all_for_full || [] + end end end diff --git a/app/models/form/admin_settings.rb b/app/models/form/admin_settings.rb index 99d738d348f62f..8a823fa1b75699 100644 --- a/app/models/form/admin_settings.rb +++ b/app/models/form/admin_settings.rb @@ -53,6 +53,9 @@ class Form::AdminSettings post_stranger_mentions_max sensitive_words sensitive_words_for_full + sensitive_words_all + sensitive_words_all_for_full + auto_warning_text authorized_fetch receive_other_servers_emoji_reaction streaming_other_servers_emoji_reaction @@ -127,6 +130,8 @@ class Form::AdminSettings ng_words_for_stranger_mention sensitive_words sensitive_words_for_full + sensitive_words_all + sensitive_words_all_for_full emoji_reaction_disallow_domains permit_new_account_domains ).freeze diff --git a/app/services/activitypub/process_status_update_service.rb b/app/services/activitypub/process_status_update_service.rb index 97896287ea03e4..892df91ec2e2dc 100644 --- a/app/services/activitypub/process_status_update_service.rb +++ b/app/services/activitypub/process_status_update_service.rb @@ -188,6 +188,8 @@ def update_immediate_attributes! @status.sensitive = @account.sensitized? || @status_parser.sensitive || false @status.language = @status_parser.language + process_sensitive_words + @significant_changes = text_significantly_changed? || @status.spoiler_text_changed? || @media_attachments_changed || @poll_changed @status.edited_at = @status_parser.edited_at if significant_changes? @@ -195,6 +197,14 @@ def update_immediate_attributes! @status.save! end + def process_sensitive_words + return unless %i(public public_unlisted login).include?(@status.visibility.to_sym) && Admin::SensitiveWord.sensitive?(@status.text, @status.spoiler_text, local: false) + + @status.text = Admin::SensitiveWord.modified_text(@status.text, @status.spoiler_text) + @status.spoiler_text = Admin::SensitiveWord.alternative_text + @status.sensitive = true + end + def read_metadata @raw_tags = [] @raw_mentions = [] diff --git a/app/services/post_status_service.rb b/app/services/post_status_service.rb index 3c4eb9c12f0c81..a20130255ea063 100644 --- a/app/services/post_status_service.rb +++ b/app/services/post_status_service.rb @@ -121,7 +121,8 @@ def overwrite_dtl_post def process_sensitive_words if [:public, :public_unlisted, :login].include?(@visibility&.to_sym) && Admin::SensitiveWord.sensitive?(@text, @options[:spoiler_text] || '') @text = Admin::SensitiveWord.modified_text(@text, @options[:spoiler_text]) - @options[:spoiler_text] = I18n.t('admin.sensitive_words.alert') + @options[:spoiler_text] = Admin::SensitiveWord.alternative_text + @sensitive = true end end diff --git a/app/services/update_status_service.rb b/app/services/update_status_service.rb index 1393e7eefaff74..0e454d6136e03c 100644 --- a/app/services/update_status_service.rb +++ b/app/services/update_status_service.rb @@ -170,7 +170,8 @@ def process_sensitive_words return unless [:public, :public_unlisted, :login].include?(@status.visibility&.to_sym) && Admin::SensitiveWord.sensitive?(@status.text, @status.spoiler_text || '') @status.text = Admin::SensitiveWord.modified_text(@status.text, @status.spoiler_text) - @status.spoiler_text = I18n.t('admin.sensitive_words.alert') + @status.spoiler_text = Admin::SensitiveWord.alternative_text + @status.sensitive = true end def update_expiration! diff --git a/app/views/admin/sensitive_words/show.html.haml b/app/views/admin/sensitive_words/show.html.haml index bb5447d3e1e9eb..a745d25f396717 100644 --- a/app/views/admin/sensitive_words/show.html.haml +++ b/app/views/admin/sensitive_words/show.html.haml @@ -15,5 +15,14 @@ .fields-group = f.input :sensitive_words, wrapper: :with_label, as: :text, input_html: { rows: 12 }, label: t('admin.sensitive_words.keywords'), hint: t('admin.sensitive_words.keywords_hint') + .fields-group + = f.input :sensitive_words_all_for_full, wrapper: :with_label, as: :text, input_html: { rows: 12 }, label: t('admin.sensitive_words.keywords_all_for_all'), hint: t('admin.sensitive_words.keywords_for_all_hint') + + .fields-group + = f.input :sensitive_words_all, wrapper: :with_label, as: :text, input_html: { rows: 12 }, label: t('admin.sensitive_words.keywords_all'), hint: t('admin.sensitive_words.keywords_hint') + + .fields-group + = f.input :auto_warning_text, wrapper: :with_label, input_html: { placeholder: t('admin.sensitive_words.alert') }, label: t('admin.sensitive_words.auto_warning_text'), hint: t('admin.sensitive_words.auto_warning_text_hint') + .actions = f.button :button, t('generic.save_changes'), type: :submit diff --git a/config/locales/en.yml b/config/locales/en.yml index c73cdeb827cede..99912c4c94c093 100644 --- a/config/locales/en.yml +++ b/config/locales/en.yml @@ -856,9 +856,13 @@ en: title: Server rules sensitive_words: alert: This post contains sensitive words, so alert added + auto_warning_text: Custom warning text + auto_warning_text_hint: If not specified, the default warning text is used. hint: This keywords is applied to public posts only.. - keywords: Sensitive keywords - keywords_for_all: Sensitive keywords (Contains CW alert) + keywords: Sensitive keywords for local only + keywords_all: Sensitive keywords for local+remote + keywords_all_for_all: Sensitive keywords for local+remote (Contains CW alert) + keywords_for_all: Sensitive keywords for local only (Contains CW alert) keywords_for_all_hint: The first character of the line is "?". to use regular expressions title: Sensitive words and moderation options settings: diff --git a/config/locales/ja.yml b/config/locales/ja.yml index e11eb52ce72197..8062e96c9999a1 100644 --- a/config/locales/ja.yml +++ b/config/locales/ja.yml @@ -846,9 +846,13 @@ ja: title: サーバーのルール sensitive_words: alert: この投稿にはセンシティブなキーワードが含まれるため、警告文が追加されました + auto_warning_text: カスタム警告文 + auto_warning_text_hint: 指定しなかった場合は、各言語のデフォルト警告文が使用されます hint: センシティブなキーワードの設定は、当サーバーのローカルユーザーによる公開範囲「公開」「ローカル公開」「ログインユーザーのみ」に対して適用されます。 - keywords: センシティブなキーワード(警告文は除外) - keywords_for_all: センシティブなキーワード(警告文にも適用) + keywords: ローカルの投稿に適用するセンシティブなキーワード(警告文は除外) + keywords_all: ローカル・リモートの投稿に適用するセンシティブなキーワード(警告文は除外) + keywords_all_for_all: ローカル・リモートの投稿に適用するセンシティブなキーワード(警告文にも適用) + keywords_for_all: ローカルの投稿に適用するセンシティブなキーワード(警告文にも適用) keywords_for_all_hint: ここで指定したキーワードを含む投稿は強制的にCWになります。警告文にも含まれていればCWになります。行が「?」で始まっていれば正規表現が使えます keywords_hint: ここで指定したキーワードを含む投稿は強制的にCWになります。ただし警告文に使用していた場合は無視されます title: センシティブ単語と設定 diff --git a/spec/lib/activitypub/activity/create_spec.rb b/spec/lib/activitypub/activity/create_spec.rb index e1103e33973ec5..465b6992efed02 100644 --- a/spec/lib/activitypub/activity/create_spec.rb +++ b/spec/lib/activitypub/activity/create_spec.rb @@ -2024,6 +2024,45 @@ def activity_for_object(json) end end + context 'when sensitive word is set' do + let(:custom_before) { true } + let(:content) { 'Lorem ipsum' } + let(:sensitive_words_all) { 'hello' } + let(:object_json) do + { + id: [ActivityPub::TagManager.instance.uri_for(sender), '#bar'].join, + type: 'Note', + content: content, + to: 'https://www.w3.org/ns/activitystreams#Public', + } + end + + before do + Form::AdminSettings.new(sensitive_words_all: sensitive_words_all, sensitive_words: 'ipsum').save + subject.perform + end + + context 'when not contains sensitive words' do + it 'creates status' do + status = sender.statuses.first + + expect(status).to_not be_nil + expect(status.spoiler_text).to eq '' + end + end + + context 'when contains sensitive words' do + let(:content) { 'hello world' } + + it 'creates status' do + status = sender.statuses.first + + expect(status).to_not be_nil + expect(status.spoiler_text).to_not eq '' + end + end + end + context 'when hashtags limit is set' do let(:post_hash_tags_max) { 2 } let(:custom_before) { true } diff --git a/spec/services/activitypub/process_status_update_service_spec.rb b/spec/services/activitypub/process_status_update_service_spec.rb index cfe3e3eb97a746..6a856fd29457b1 100644 --- a/spec/services/activitypub/process_status_update_service_spec.rb +++ b/spec/services/activitypub/process_status_update_service_spec.rb @@ -681,5 +681,42 @@ def poll_option_json(name, votes) end end end + + describe 'sensitive word is set' do + let(:payload) do + { + '@context': 'https://www.w3.org/ns/activitystreams', + id: 'foo', + type: 'Note', + content: content, + updated: '2021-09-08T22:39:25Z', + tag: json_tags, + } + end + + context 'when hit sensitive words' do + let(:content) { 'ng word aiueo' } + + it 'update status' do + Form::AdminSettings.new(sensitive_words_all: 'test').save + + subject.call(status, json, json) + expect(status.reload.text).to eq content + expect(status.spoiler_text).to eq '' + end + end + + context 'when not hit sensitive words' do + let(:content) { 'ng word test' } + + it 'update status' do + Form::AdminSettings.new(sensitive_words_all: 'test').save + + subject.call(status, json, json) + expect(status.reload.text).to eq content + expect(status.spoiler_text).to_not eq '' + end + end + end end end