From 572a0e128d74c16d0715e646a5895dac4c34eca4 Mon Sep 17 00:00:00 2001 From: Claire Date: Thu, 31 Jul 2025 09:39:53 +0200 Subject: [PATCH] Change quote verification to not bypass authorization flow for mentions (#35528) --- app/lib/activitypub/parser/status_parser.rb | 3 --- .../concerns/status/interaction_policy_concern.rb | 8 -------- app/services/activitypub/verify_quote_service.rb | 9 +-------- config/locales/en.yml | 4 ++-- config/locales/simple_form.en.yml | 2 +- spec/policies/status_policy_spec.rb | 14 +++++++------- .../activitypub/verify_quote_service_spec.rb | 4 ++-- 7 files changed, 13 insertions(+), 31 deletions(-) diff --git a/app/lib/activitypub/parser/status_parser.rb b/app/lib/activitypub/parser/status_parser.rb index ad3ef72be8a..5a434ed915a 100644 --- a/app/lib/activitypub/parser/status_parser.rb +++ b/app/lib/activitypub/parser/status_parser.rb @@ -152,9 +152,6 @@ class ActivityPub::Parser::StatusParser # Remove the special-meaning actor URI allowed_actors.delete(@options[:actor_uri]) - # Tagged users are always allowed, so remove them - allowed_actors -= as_array(@object['tag']).filter_map { |tag| tag['href'] if equals_or_includes?(tag['type'], 'Mention') } - # Any unrecognized actor is marked as unknown flags |= Status::QUOTE_APPROVAL_POLICY_FLAGS[:unknown] unless allowed_actors.empty? diff --git a/app/models/concerns/status/interaction_policy_concern.rb b/app/models/concerns/status/interaction_policy_concern.rb index 7e7642209db..6ad047fd8d5 100644 --- a/app/models/concerns/status/interaction_policy_concern.rb +++ b/app/models/concerns/status/interaction_policy_concern.rb @@ -33,16 +33,8 @@ module Status::InteractionPolicyConcern automatic_policy = quote_approval_policy >> 16 manual_policy = quote_approval_policy & 0xFFFF - # Checking for public policy first because it's less expensive than looking at mentions return :automatic if automatic_policy.anybits?(QUOTE_APPROVAL_POLICY_FLAGS[:public]) - # Mentioned users are always allowed to quote - if active_mentions.loaded? - return :automatic if active_mentions.any? { |mention| mention.account_id == other_account.id } - elsif active_mentions.exists?(account: other_account) - return :automatic - end - if automatic_policy.anybits?(QUOTE_APPROVAL_POLICY_FLAGS[:followers]) following_author = preloaded_relations[:following] ? preloaded_relations[:following][account_id] : other_account.following?(account) if following_author.nil? return :automatic if following_author diff --git a/app/services/activitypub/verify_quote_service.rb b/app/services/activitypub/verify_quote_service.rb index a83a3c1155a..822abcf4022 100644 --- a/app/services/activitypub/verify_quote_service.rb +++ b/app/services/activitypub/verify_quote_service.rb @@ -45,14 +45,7 @@ class ActivityPub::VerifyQuoteService < BaseService true end - # Always allow someone to quote posts in which they are mentioned - if @quote.quoted_status.active_mentions.exists?(mentions: { account_id: @quote.account_id }) - @quote.accept! - - true - else - false - end + false end def fetch_approval_object(uri, prefetched_body: nil) diff --git a/config/locales/en.yml b/config/locales/en.yml index a149c18c775..59272bb3542 100644 --- a/config/locales/en.yml +++ b/config/locales/en.yml @@ -1906,8 +1906,8 @@ en: ownership: Someone else's post cannot be pinned reblog: A boost cannot be pinned quote_policies: - followers: Followers and mentioned users - nobody: Only mentioned users + followers: Only your followers + nobody: Nobody public: Everyone title: '%{name}: "%{quote}"' visibilities: diff --git a/config/locales/simple_form.en.yml b/config/locales/simple_form.en.yml index 86fb4528de4..8da54f626f7 100644 --- a/config/locales/simple_form.en.yml +++ b/config/locales/simple_form.en.yml @@ -56,7 +56,7 @@ en: scopes: Which APIs the application will be allowed to access. If you select a top-level scope, you don't need to select individual ones. setting_aggregate_reblogs: Do not show new boosts for posts that have been recently boosted (only affects newly-received boosts) setting_always_send_emails: Normally e-mail notifications won't be sent when you are actively using Mastodon - setting_default_quote_policy: Mentioned users are always allowed to quote. This setting will only take effect for posts created with the next Mastodon version, but you can select your preference in preparation + setting_default_quote_policy: This setting will only take effect for posts created with the next Mastodon version, but you can select your preference in preparation. setting_default_sensitive: Sensitive media is hidden by default and can be revealed with a click setting_display_media_default: Hide media marked as sensitive setting_display_media_hide_all: Always hide media diff --git a/spec/policies/status_policy_spec.rb b/spec/policies/status_policy_spec.rb index 63622970455..af6958b68dc 100644 --- a/spec/policies/status_policy_spec.rb +++ b/spec/policies/status_policy_spec.rb @@ -94,19 +94,19 @@ RSpec.describe StatusPolicy, type: :model do expect(subject).to permit(status.account, status) end - it 'grants access when direct and viewer is mentioned' do + it 'does not grant access access when direct and viewer is mentioned but not explicitly allowed' do status.visibility = :direct - status.mentions = [Fabricate(:mention, account: alice)] + status.mentions = [Fabricate(:mention, account: bob)] - expect(subject).to permit(alice, status) + expect(subject).to_not permit(bob, status) end - it 'grants access when direct and non-owner viewer is mentioned and mentions are loaded' do + it 'does not grant access access when direct and viewer is mentioned but not explicitly allowed and mentions are loaded' do status.visibility = :direct status.mentions = [Fabricate(:mention, account: bob)] status.active_mentions.load - expect(subject).to permit(bob, status) + expect(subject).to_not permit(bob, status) end it 'denies access when direct and viewer is not mentioned' do @@ -123,11 +123,11 @@ RSpec.describe StatusPolicy, type: :model do expect(subject).to_not permit(viewer, status) end - it 'grants access when private and viewer is mentioned' do + it 'grants access when private and viewer is mentioned but not otherwise allowed' do status.visibility = :private status.mentions = [Fabricate(:mention, account: bob)] - expect(subject).to permit(bob, status) + expect(subject).to_not permit(bob, status) end it 'denies access when private and non-viewer is mentioned' do diff --git a/spec/services/activitypub/verify_quote_service_spec.rb b/spec/services/activitypub/verify_quote_service_spec.rb index ae4ffae9bb2..94b9e33ed3b 100644 --- a/spec/services/activitypub/verify_quote_service_spec.rb +++ b/spec/services/activitypub/verify_quote_service_spec.rb @@ -267,9 +267,9 @@ RSpec.describe ActivityPub::VerifyQuoteService do quoted_status.mentions << Mention.new(account: account) end - it 'updates the status' do + it 'does not the status' do expect { subject.call(quote) } - .to change(quote, :state).to('accepted') + .to_not change(quote, :state).from('pending') end end end