Add sensitive words setting

This commit is contained in:
KMY 2023-07-27 12:47:33 +09:00
parent 0dbc070037
commit cd00d7f533
12 changed files with 128 additions and 1 deletions

View file

@ -0,0 +1,34 @@
# frozen_string_literal: true
module Admin
class SensitiveWordsController < BaseController
def show
authorize :sensitive_words, :show?
@admin_settings = Form::AdminSettings.new
end
def create
authorize :sensitive_words, :create?
@admin_settings = Form::AdminSettings.new(settings_params)
if @admin_settings.save
flash[:notice] = I18n.t('generic.changes_saved_msg')
redirect_to after_update_redirect_path
else
render :index
end
end
private
def after_update_redirect_path
admin_sensitive_words_path
end
def settings_params
params.require(:form_admin_settings).permit(*Form::AdminSettings::KEYS)
end
end
end

View file

@ -0,0 +1,25 @@
# frozen_string_literal: true
class Admin::SensitiveWord
class << self
def sensitive?(text, spoiler_text)
exposure_text = (spoiler_text.presence || text)
(spoiler_text.blank? && sensitive_words.any? { |word| text.include?(word) }) ||
sensitive_words_for_full.any? { |word| exposure_text.include?(word) }
end
def modified_text(text, spoiler_text)
spoiler_text.present? ? "#{spoiler_text}\n\n#{text}" : text
end
private
def sensitive_words
Setting.sensitive_words || []
end
def sensitive_words_for_full
Setting.sensitive_words_for_full || []
end
end
end

View file

@ -38,6 +38,8 @@ class Form::AdminSettings
enable_block_emoji_reaction_settings
hide_local_users_for_anonymous
post_hash_tags_max
sensitive_words
sensitive_words_for_full
).freeze
INTEGER_KEYS = %i(
@ -70,6 +72,8 @@ class Form::AdminSettings
STRING_ARRAY_KEYS = %i(
ng_words
sensitive_words
sensitive_words_for_full
).freeze
attr_accessor(*KEYS)

View file

@ -36,6 +36,7 @@ class UserRole < ApplicationRecord
manage_roles: (1 << 17),
manage_user_access: (1 << 18),
delete_user_data: (1 << 19),
manage_sensitive_words: (1 << 29),
manage_ng_words: (1 << 30),
}.freeze
@ -63,6 +64,7 @@ class UserRole < ApplicationRecord
manage_taxonomies
manage_invites
manage_ng_words
manage_sensitive_words
).freeze,
administration: %w(

View file

@ -0,0 +1,11 @@
# frozen_string_literal: true
class SensitiveWordsPolicy < ApplicationPolicy
def show?
role.can?(:manage_sensitive_words)
end
def create?
role.can?(:manage_sensitive_words)
end
end

View file

@ -82,10 +82,18 @@ class PostStatusService < BaseService
@scheduled_at = @options[:scheduled_at]&.to_datetime
@scheduled_at = nil if scheduled_in_the_past?
@reference_ids = (@options[:status_reference_ids] || []).map(&:to_i).filter(&:positive?)
process_sensitive_words
rescue ArgumentError
raise ActiveRecord::RecordInvalid
end
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')
end
end
def searchability
return :private if @options[:searchability]&.to_sym == :public && @visibility&.to_sym == :unlisted && @account.user&.setting_disallow_unlisted_public_searchability

View file

@ -127,6 +127,7 @@ class UpdateStatusService < BaseService
@status.markdown = @options[:markdown] || false
@status.sensitive = @options[:sensitive] || @options[:spoiler_text].present? if @options.key?(:sensitive) || @options.key?(:spoiler_text)
@status.language = valid_locale_cascade(@options[:language], @status.language, @status.account.user&.preferred_posting_language, I18n.default_locale)
process_sensitive_words
# We raise here to rollback the entire transaction
raise NoChangesSubmittedError unless significant_changes?
@ -137,6 +138,13 @@ class UpdateStatusService < BaseService
@status.save!
end
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')
end
def update_expiration!
UpdateStatusExpirationService.new.call(@status)
end

View file

@ -0,0 +1,19 @@
- content_for :page_title do
= t('admin.sensitive_words.title')
- content_for :header_tags do
= javascript_pack_tag 'admin', async: true, crossorigin: 'anonymous'
%p.hint= t 'admin.sensitive_words.hint'
= simple_form_for @admin_settings, url: admin_sensitive_words_path, html: { method: :post } do |f|
= render 'shared/error_messages', object: @admin_settings
.fields-group
= f.input :sensitive_words_for_full, wrapper: :with_label, as: :text, input_html: { rows: 12 }, label: t('admin.sensitive_words.keywords_for_all'), hint: t('admin.sensitive_words.keywords_for_all_hint')
.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')
.actions
= f.button :button, t('generic.save_changes'), type: :submit