From 66ffd6a82b0e14763fa0e938ee0ccd0329e971a7 Mon Sep 17 00:00:00 2001 From: noellabo Date: Fri, 16 Feb 2024 16:14:23 +0900 Subject: [PATCH] Add reject pattern to Admin setting --- app/lib/activitypub/activity/create.rb | 6 +++++- app/models/form/admin_settings.rb | 2 ++ app/validators/regexp_syntax_validator.rb | 13 +++++++++++++ app/views/admin/settings/other/show.html.haml | 17 +++++++++++++++++ .../admin/settings/shared/_links.html.haml | 1 + config/locales/en.yml | 8 ++++++++ config/routes/admin.rb | 1 + config/settings.yml | 1 + 8 files changed, 48 insertions(+), 1 deletion(-) create mode 100644 app/validators/regexp_syntax_validator.rb create mode 100644 app/views/admin/settings/other/show.html.haml diff --git a/app/lib/activitypub/activity/create.rb b/app/lib/activitypub/activity/create.rb index 85195f4c395e44..bfb3ce7e8bd0c6 100644 --- a/app/lib/activitypub/activity/create.rb +++ b/app/lib/activitypub/activity/create.rb @@ -46,8 +46,12 @@ def message_franking ) end + def reject_pattern? + Setting.reject_pattern.present? && @object['content']&.match?(Setting.reject_pattern) + end + def create_status - return reject_payload! if unsupported_object_type? || non_matching_uri_hosts?(@account.uri, object_uri) || tombstone_exists? || !related_to_local_activity? + return reject_payload! if unsupported_object_type? || non_matching_uri_hosts?(@account.uri, object_uri) || tombstone_exists? || !related_to_local_activity? || reject_pattern? with_redis_lock("create:#{object_uri}") do return if delete_arrived_first?(object_uri) || poll_vote? diff --git a/app/models/form/admin_settings.rb b/app/models/form/admin_settings.rb index cb37a522174d43..e6c5ad44a45470 100644 --- a/app/models/form/admin_settings.rb +++ b/app/models/form/admin_settings.rb @@ -37,6 +37,7 @@ class Form::AdminSettings status_page_url captcha_enabled authorized_fetch + reject_pattern ).freeze INTEGER_KEYS = %i( @@ -81,6 +82,7 @@ class Form::AdminSettings validates :site_short_description, length: { maximum: 200 }, if: -> { defined?(@site_short_description) } validates :status_page_url, url: true, allow_blank: true validate :validate_site_uploads + validates :reject_pattern, regexp_syntax: true KEYS.each do |key| define_method(key) do diff --git a/app/validators/regexp_syntax_validator.rb b/app/validators/regexp_syntax_validator.rb new file mode 100644 index 00000000000000..afb46c15ba9fec --- /dev/null +++ b/app/validators/regexp_syntax_validator.rb @@ -0,0 +1,13 @@ +# frozen_string_literal: true + +class RegexpSyntaxValidator < ActiveModel::EachValidator + def validate_each(record, attribute, value) + return if value.blank? + + begin + Regexp.compile(value) + rescue RegexpError => exception + record.errors.add(attribute, I18n.t('applications.invalid_regexp', message: exception.message)) + end + end +end diff --git a/app/views/admin/settings/other/show.html.haml b/app/views/admin/settings/other/show.html.haml new file mode 100644 index 00000000000000..0a7eaf080af55a --- /dev/null +++ b/app/views/admin/settings/other/show.html.haml @@ -0,0 +1,17 @@ +- content_for :page_title do + = t('admin.settings.others.title') + +- content_for :heading do + %h2= t('admin.settings.title') + = render partial: 'admin/settings/shared/links' + += simple_form_for @admin_settings, url: admin_settings_others_path, html: { method: :patch } do |f| + = render 'shared/error_messages', object: @admin_settings + + %p.lead= t('admin.settings.others.preamble') + + %h4= t('admin.settings.others.activitypub') + + .fields-group + = f.input :reject_pattern, wrapper: :with_block_label, as: :text, label: t('admin.settings.reject_pattern.title'), hint: t('admin.settings.reject_pattern.desc_html'), input_html: { rows: 8 } + diff --git a/app/views/admin/settings/shared/_links.html.haml b/app/views/admin/settings/shared/_links.html.haml index d8b697592a57ed..aa48b62cf6891d 100644 --- a/app/views/admin/settings/shared/_links.html.haml +++ b/app/views/admin/settings/shared/_links.html.haml @@ -7,3 +7,4 @@ primary.item :discovery, safe_join([fa_icon('search fw'), t('admin.settings.discovery.title')]), admin_settings_discovery_path primary.item :content_retention, safe_join([fa_icon('history fw'), t('admin.settings.content_retention.title')]), admin_settings_content_retention_path primary.item :appearance, safe_join([fa_icon('desktop fw'), t('admin.settings.appearance.title')]), admin_settings_appearance_path + primary.item :others, safe_join([fa_icon('cogs fw'), t('admin.settings.others.title')]), admin_settings_others_path diff --git a/config/locales/en.yml b/config/locales/en.yml index 9d739be07f8a4e..4389793663995d 100644 --- a/config/locales/en.yml +++ b/config/locales/en.yml @@ -766,6 +766,10 @@ en: all: To everyone disabled: To no one users: To logged-in local users + others: + activitypub: ActivityPub + preamble: Other settings, including customizing behavior + title: Other settings registrations: preamble: Control who can create an account on your server. title: Registrations @@ -774,6 +778,9 @@ en: approved: Approval required for sign up none: Nobody can sign up open: Anyone can sign up + reject_pattern: + desc_html: Set a regular expression pattern to inspect Create Activity content, and refuse Activity if you match + title: Reject Pattern security: authorized_fetch: Require authentication from federated servers authorized_fetch_hint: Requiring authentication from federated servers enables stricter enforcement of both user-level and server-level blocks. However, this comes at the cost of a performance penalty, reduces the reach of your replies, and may introduce compatibility issues with some federated services. In addition, this will not prevent dedicated actors from fetching your public posts and accounts. @@ -1029,6 +1036,7 @@ en: applications: created: Application successfully created destroyed: Application successfully deleted + invalid_regexp: "The provided Regexp is invalid: %{message}" logout: Logout regenerate_token: Regenerate access token token_regenerated: Access token successfully regenerated diff --git a/config/routes/admin.rb b/config/routes/admin.rb index 207cb0580dcaaf..6b1f0e1a1668f5 100644 --- a/config/routes/admin.rb +++ b/config/routes/admin.rb @@ -50,6 +50,7 @@ resource :about, only: [:show, :update], controller: 'about' resource :appearance, only: [:show, :update], controller: 'appearance' resource :discovery, only: [:show, :update], controller: 'discovery' + resource :others, only: [:show, :update], controller: 'others' end resources :site_uploads, only: [:destroy] diff --git a/config/settings.yml b/config/settings.yml index 67297c26ceafcf..188b37f3f104fd 100644 --- a/config/settings.yml +++ b/config/settings.yml @@ -38,6 +38,7 @@ defaults: &defaults require_invite_text: false backups_retention_period: 7 captcha_enabled: false + reject_pattern: '' development: <<: *defaults