From 0048a8368e8568f70e9f29dfc614bdda4c6c3097 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?KMY=EF=BC=88=E9=9B=AA=E3=81=82=E3=81=99=E3=81=8B=EF=BC=89?= Date: Sat, 17 Feb 2024 16:48:13 +0900 Subject: [PATCH] =?UTF-8?q?Add:=20#573=20=E6=96=B0=E8=A6=8F=E3=81=AE?= =?UTF-8?q?=E3=82=A2=E3=82=AB=E3=82=A6=E3=83=B3=E3=83=88=E8=AA=8D=E8=AD=98?= =?UTF-8?q?=E3=82=92=E5=85=A8=E3=81=A6=E5=81=9C=E6=AD=A2=E3=81=99=E3=82=8B?= =?UTF-8?q?=E3=82=AA=E3=83=97=E3=82=B7=E3=83=A7=E3=83=B3=20(#583)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/models/form/admin_settings.rb | 2 + .../activitypub/process_account_service.rb | 14 ++++- app/views/admin/ng_words/show.html.haml | 3 ++ config/locales/en.yml | 2 + config/locales/ja.yml | 2 + .../process_account_service_spec.rb | 52 +++++++++++++++++++ 6 files changed, 74 insertions(+), 1 deletion(-) diff --git a/app/models/form/admin_settings.rb b/app/models/form/admin_settings.rb index 2513023b6e9821..f0dec6967eded0 100644 --- a/app/models/form/admin_settings.rb +++ b/app/models/form/admin_settings.rb @@ -64,6 +64,7 @@ class Form::AdminSettings unlocked_friend enable_local_timeline emoji_reaction_disallow_domains + permit_new_account_domains ).freeze INTEGER_KEYS = %i( @@ -123,6 +124,7 @@ class Form::AdminSettings sensitive_words sensitive_words_for_full emoji_reaction_disallow_domains + permit_new_account_domains ).freeze attr_accessor(*KEYS) diff --git a/app/services/activitypub/process_account_service.rb b/app/services/activitypub/process_account_service.rb index 5b1cfe2f59383c..8c45fd2d5da50c 100644 --- a/app/services/activitypub/process_account_service.rb +++ b/app/services/activitypub/process_account_service.rb @@ -13,7 +13,7 @@ class ActivityPub::ProcessAccountService < BaseService # Should be called with confirmed valid JSON # and WebFinger-resolved username and domain - def call(username, domain, json, options = {}) + def call(username, domain, json, options = {}) # rubocop:disable Metrics/PerceivedComplexity return if json['inbox'].blank? || unsupported_uri_scheme?(json['id']) || domain_not_allowed?(domain) @options = options @@ -37,6 +37,8 @@ def call(username, domain, json, options = {}) @suspension_changed = false if @account.nil? + return nil if blocking_new_account?(@domain) + with_redis do |redis| return nil if redis.pfcount("unique_subdomains_for:#{PublicSuffix.domain(@domain, ignore_private: true)}") >= SUBDOMAINS_RATELIMIT @@ -130,6 +132,16 @@ def set_immediate_attributes! @account.memorial = @json['memorial'] || false end + def blocking_new_account?(domain) + return false if permit_new_account_domains.blank? + + permit_new_account_domains.exclude?(domain) + end + + def permit_new_account_domains + (Setting.permit_new_account_domains || []).compact_blank + end + def valid_account? display_name = @json['name'] || '' note = @json['summary'] || '' diff --git a/app/views/admin/ng_words/show.html.haml b/app/views/admin/ng_words/show.html.haml index d188a179c0f5ad..18d57d3468b01b 100644 --- a/app/views/admin/ng_words/show.html.haml +++ b/app/views/admin/ng_words/show.html.haml @@ -32,5 +32,8 @@ .fields-group = f.input :hide_local_users_for_anonymous, wrapper: :with_label, as: :boolean, label: t('admin.ng_words.hide_local_users_for_anonymous') + .fields-group + = f.input :permit_new_account_domains, wrapper: :with_label, as: :text, kmyblue: true, input_html: { rows: 6 }, label: t('admin.special_instances.permit_new_account_domains'), hint: t('admin.special_instances.permit_new_account_domains_hint') + .actions = f.button :button, t('generic.save_changes'), type: :submit diff --git a/config/locales/en.yml b/config/locales/en.yml index ddb7b0386957f7..a7387e29aa3d44 100644 --- a/config/locales/en.yml +++ b/config/locales/en.yml @@ -918,6 +918,8 @@ en: special_instances: emoji_reaction_disallow_domains: Domains we are not permitted emoji reaction emoji_reaction_disallow_domains_hint: If you need to be considerate to your coalition partners, set the domain with a new line separator. It is not possible to put an emoji reaction on a post from a set domain. + permit_new_account_domains: Domain to allow recognition of new accounts + permit_new_account_domains_hint: Only new account information sent from the domain specified here will be saved if more than one is specified, title: Special servers statuses: account: Author diff --git a/config/locales/ja.yml b/config/locales/ja.yml index 2b87a1379805b6..b4bb14f0cc40ed 100644 --- a/config/locales/ja.yml +++ b/config/locales/ja.yml @@ -909,6 +909,8 @@ ja: special_instances: emoji_reaction_disallow_domains: 自分のサーバーが絵文字リアクションをすることを許可しないドメイン emoji_reaction_disallow_domains_hint: 連合先に配慮する必要がある場合、ドメインを改行区切りで設定します。設定されたドメインの投稿に絵文字リアクションを付けることはできません。 + permit_new_account_domains: 新規アカウントの認知を許可するドメイン + permit_new_account_domains_hint: 1つ以上指定した場合、ここで指定されたドメインから送られてくる新規アカウント情報だけが保存されるようになります title: 特殊なサーバー statuses: account: 作成者 diff --git a/spec/services/activitypub/process_account_service_spec.rb b/spec/services/activitypub/process_account_service_spec.rb index 2763805f6dc1c6..95cf92a46ce524 100644 --- a/spec/services/activitypub/process_account_service_spec.rb +++ b/spec/services/activitypub/process_account_service_spec.rb @@ -9,6 +9,58 @@ stub_request(:get, 'https://example.com/.well-known/nodeinfo').to_return(status: 404) end + describe 'about blocking new remote account' do + subject { described_class.new.call('alice', 'example.com', payload) } + + let(:permit_new_account_domains) { nil } + let(:payload) do + { + id: 'https://foo.test', + type: 'Actor', + inbox: 'https://foo.test/inbox', + actor_type: 'Person', + summary: 'new bio', + }.with_indifferent_access + end + + before do + Setting.permit_new_account_domains = permit_new_account_domains + end + + it 'created account in a simple case' do + expect(subject).to_not be_nil + expect(subject.uri).to eq 'https://foo.test' + end + + context 'when is blocked' do + let(:permit_new_account_domains) { ['foo.bar'] } + + it 'does not create account' do + expect(subject).to be_nil + end + + context 'with has existing account' do + before do + Fabricate(:account, uri: 'https://foo.test', domain: 'example.com', username: 'alice', note: 'old bio') + end + + it 'updated account' do + expect(subject).to_not be_nil + expect(subject.note).to eq 'new bio' + end + end + end + + context 'when is in whitelist' do + let(:permit_new_account_domains) { ['example.com'] } + + it 'does not create account' do + expect(subject).to_not be_nil + expect(subject.uri).to eq 'https://foo.test' + end + end + end + context 'with searchability' do subject { described_class.new.call('alice', 'example.com', payload) }