From 3219a99deab4b631c8b0ccb42b959066ce4022f4 Mon Sep 17 00:00:00 2001 From: "KMY (Yuki Asuka)" Date: Fri, 19 Sep 2025 08:43:34 +0000 Subject: [PATCH] =?UTF-8?q?Fix:=20=E3=83=AD=E3=83=BC=E3=82=AB=E3=83=AB?= =?UTF-8?q?=E6=8A=95=E7=A8=BF=E3=82=92=E5=BC=95=E7=94=A8=E3=81=97=E3=81=9F?= =?UTF-8?q?=E3=82=82=E3=81=AE=E3=81=8C=E4=BB=96=E3=81=AEMastodon=E3=81=A7?= =?UTF-8?q?=E6=AD=A3=E5=B8=B8=E3=81=AB=E8=AA=8D=E8=AD=98=E3=81=95=E3=82=8C?= =?UTF-8?q?=E3=81=AA=E3=81=84=E5=95=8F=E9=A1=8C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/lib/activitypub/tag_manager.rb | 2 +- app/models/quote.rb | 6 -- .../activitypub/note_serializer.rb | 2 +- .../activitypub/note_serializer_spec.rb | 76 +++++++++++++++++++ 4 files changed, 78 insertions(+), 8 deletions(-) diff --git a/app/lib/activitypub/tag_manager.rb b/app/lib/activitypub/tag_manager.rb index f9066b3b12f5a5..fbf595df85b314 100644 --- a/app/lib/activitypub/tag_manager.rb +++ b/app/lib/activitypub/tag_manager.rb @@ -59,7 +59,7 @@ def uri_for(target, group: false) def approval_uri_for(quote, check_approval: true) unless quote.quoted_account&.local? - return 'http://kmy.blue/ns#LegacyQuote' if Setting.auto_accept_legacy_quotes && !quote.approval_uri && quote.quoted_account&.domain && InstanceInfo.legacy_quote_software?(quote.quoted_account.domain) + return 'http://kmy.blue/ns#LegacyQuote' if Setting.auto_accept_legacy_quotes && quote.approval_uri.nil? && InstanceInfo.legacy_quote_software?(quote.quoted_account.domain) return quote.approval_uri end diff --git a/app/models/quote.rb b/app/models/quote.rb index 7b860820a5516f..dcfcd3b353cf6e 100644 --- a/app/models/quote.rb +++ b/app/models/quote.rb @@ -44,12 +44,6 @@ class Quote < ApplicationRecord after_destroy_commit :decrement_counter_caches! after_update_commit :update_counter_caches! - def legacy_accepted? - return false if !accepted? || !quoted_account || quoted_account.local? - - InstanceInfo.legacy_quote_software?(quoted_account.domain) - end - def accept! update!(state: :accepted) end diff --git a/app/serializers/activitypub/note_serializer.rb b/app/serializers/activitypub/note_serializer.rb index c2ead2118109eb..5f2589050e4f53 100644 --- a/app/serializers/activitypub/note_serializer.rb +++ b/app/serializers/activitypub/note_serializer.rb @@ -279,7 +279,7 @@ def quote? end def quote_authorization? - object.quote.present? && (Setting.auto_accept_legacy_quotes ? object.quote.legacy_accepted? : ActivityPub::TagManager.instance.approval_uri_for(object.quote).present?) + object.quote.present? && ActivityPub::TagManager.instance.approval_uri_for(object.quote).present? end def quote diff --git a/spec/serializers/activitypub/note_serializer_spec.rb b/spec/serializers/activitypub/note_serializer_spec.rb index 091eb9cdfc6979..01ab5367029dd7 100644 --- a/spec/serializers/activitypub/note_serializer_spec.rb +++ b/spec/serializers/activitypub/note_serializer_spec.rb @@ -113,6 +113,82 @@ def reply_items end end + context 'with a pending quote' do + let(:quoted_account) { Fabricate(:account) } + let(:quoted_status) { Fabricate(:status, account: quoted_account) } + let!(:quote) { Fabricate(:quote, status: parent, quoted_status: quoted_status, state: :accepted) } + + shared_examples 'quote is authorized' do + it 'has the expected shape' do + expect(subject).to include({ + 'type' => 'Note', + 'quote' => ActivityPub::TagManager.instance.uri_for(quote.quoted_status), + 'quoteUri' => ActivityPub::TagManager.instance.uri_for(quote.quoted_status), + '_misskey_quote' => ActivityPub::TagManager.instance.uri_for(quote.quoted_status), + 'quoteAuthorization' => ActivityPub::TagManager.instance.approval_uri_for(quote), + }) + end + end + + shared_examples 'quote is not authorized' do + it 'has the expected shape' do + expect(subject).to include({ + 'type' => 'Note', + 'quote' => ActivityPub::TagManager.instance.uri_for(quote.quoted_status), + 'quoteUri' => ActivityPub::TagManager.instance.uri_for(quote.quoted_status), + '_misskey_quote' => ActivityPub::TagManager.instance.uri_for(quote.quoted_status), + }) + expect(subject).to_not have_key('quoteAuthorization') + end + end + + it_behaves_like 'quote is authorized' + + context 'when quote is pending' do + let(:quote) { Fabricate(:quote, status: parent, quoted_status: quoted_status, state: :pending) } + + it_behaves_like 'quote is not authorized' + end + + context 'when quote is from misskey and approval_uri is nil' do + let(:quoted_account) { Fabricate(:account, uri: 'https://example.com/actor', domain: 'example.com') } + + before { Fabricate(:instance_info, domain: 'example.com', software: 'misskey') } + + it_behaves_like 'quote is not authorized' + end + + context 'when quote is from misskey and approval_uri is nil, auto_accept_legacy_quotes is enabled' do + let(:quoted_account) { Fabricate(:account, uri: 'https://example.com/actor', domain: 'example.com') } + + before do + Fabricate(:instance_info, domain: 'example.com', software: 'misskey') + Setting.auto_accept_legacy_quotes = true + end + + it_behaves_like 'quote is authorized' + end + + context 'when quote is from mastodon and approval_uri is nil' do + let(:quoted_account) { Fabricate(:account, uri: 'https://example.com/actor', domain: 'example.com') } + + before { Fabricate(:instance_info, domain: 'example.com', software: 'mastodon') } + + it_behaves_like 'quote is not authorized' + end + + context 'when quote is from mastodon and approval_uri is nil, auto_accept_legacy_quotes is enabled' do + let(:quoted_account) { Fabricate(:account, uri: 'https://example.com/actor', domain: 'example.com') } + + before do + Fabricate(:instance_info, domain: 'example.com', software: 'mastodon') + Setting.auto_accept_legacy_quotes = true + end + + it_behaves_like 'quote is not authorized' + end + end + context 'with a quote policy', feature: :outgoing_quotes do let(:parent) { Fabricate(:status, quote_approval_policy: Status::QUOTE_APPROVAL_POLICY_FLAGS[:followers] << 16) }