mirror of
https://github.com/glitch-soc/mastodon.git
synced 2026-03-29 03:00:33 +02:00
Handle Accept of a FeatureRequest (#38251)
This commit is contained in:
@@ -5,6 +5,7 @@ class ActivityPub::Activity::Accept < ActivityPub::Activity
|
||||
return accept_follow_for_relay if relay_follow?
|
||||
return accept_follow!(follow_request_from_object) unless follow_request_from_object.nil?
|
||||
return accept_quote!(quote_request_from_object) unless quote_request_from_object.nil?
|
||||
return accept_feature_request! if Mastodon::Feature.collections_federation_enabled? && feature_request_from_object.present?
|
||||
|
||||
case @object['type']
|
||||
when 'Follow'
|
||||
@@ -44,6 +45,17 @@ class ActivityPub::Activity::Accept < ActivityPub::Activity
|
||||
accept_quote!(quote)
|
||||
end
|
||||
|
||||
def accept_feature_request!
|
||||
approval_uri = value_or_id(first_of_value(@json['result']))
|
||||
return if approval_uri.nil? || unsupported_uri_scheme?(approval_uri) || non_matching_uri_hosts?(approval_uri, @account.uri)
|
||||
|
||||
collection_item = feature_request_from_object
|
||||
collection_item.update!(approval_uri:, state: :accepted)
|
||||
|
||||
activity_json = ActiveModelSerializers::SerializableResource.new(collection_item, serializer: ActivityPub::AddFeaturedItemSerializer, adapter: ActivityPub::Adapter).to_json
|
||||
ActivityPub::AccountRawDistributionWorker.perform_async(activity_json, collection_item.collection.account_id)
|
||||
end
|
||||
|
||||
def accept_quote!(quote)
|
||||
approval_uri = value_or_id(first_of_value(@json['result']))
|
||||
return if unsupported_uri_scheme?(approval_uri) || quote.quoted_account != @account || !quote.status.local? || !quote.pending?
|
||||
@@ -72,4 +84,10 @@ class ActivityPub::Activity::Accept < ActivityPub::Activity
|
||||
def target_uri
|
||||
@target_uri ||= value_or_id(@object['actor'])
|
||||
end
|
||||
|
||||
def feature_request_from_object
|
||||
return @collection_item if instance_variable_defined?(:@collection_item)
|
||||
|
||||
@collection_item = CollectionItem.local.find_by(activity_uri: value_or_id(@object), account_id: @account.id)
|
||||
end
|
||||
end
|
||||
|
||||
@@ -171,5 +171,71 @@ RSpec.describe ActivityPub::Activity::Accept do
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
context 'with a FeatureRequest', feature: :collections_federation do
|
||||
let(:collection) { Fabricate(:collection, account: recipient) }
|
||||
let(:collection_item) { Fabricate(:collection_item, collection:, account: sender, state: :pending) }
|
||||
let(:object) { collection_item.activity_uri }
|
||||
let(:approval_uri) { 'https://example.com/stamps/1' }
|
||||
let(:json) do
|
||||
{
|
||||
'id' => 'https://example.com/accepts/1',
|
||||
'type' => 'Accept',
|
||||
'actor' => sender.uri,
|
||||
'to' => ActivityPub::TagManager.instance.uri_for(recipient),
|
||||
'object' => object,
|
||||
'result' => approval_uri,
|
||||
}
|
||||
end
|
||||
|
||||
context 'when activity is valid' do
|
||||
it 'accepts the collection item, stores the authorization uri and federates an `Add` activity' do
|
||||
subject.perform
|
||||
|
||||
expect(collection_item.reload).to be_accepted
|
||||
expect(collection_item.approval_uri).to eq 'https://example.com/stamps/1'
|
||||
expect(ActivityPub::AccountRawDistributionWorker)
|
||||
.to have_enqueued_sidekiq_job
|
||||
end
|
||||
end
|
||||
|
||||
context 'when activity is invalid' do
|
||||
shared_examples 'ignoring activity' do
|
||||
it 'does not accept the item and does not send out an activity' do
|
||||
subject.perform
|
||||
|
||||
expect(collection_item.reload).to_not be_accepted
|
||||
expect(collection_item.approval_uri).to be_nil
|
||||
expect(ActivityPub::AccountRawDistributionWorker)
|
||||
.to_not have_enqueued_sidekiq_job
|
||||
end
|
||||
end
|
||||
|
||||
context 'when matching collection item cannot be found' do
|
||||
let(:object) { 'https://localhost/feature_requests/1' }
|
||||
|
||||
it_behaves_like 'ignoring activity'
|
||||
end
|
||||
|
||||
context 'when the sender is not the featured account' do
|
||||
let(:other_account) { Fabricate(:remote_account) }
|
||||
let(:collection_item) { Fabricate(:collection_item, collection:, account: other_account, state: :pending) }
|
||||
|
||||
it_behaves_like 'ignoring activity'
|
||||
end
|
||||
|
||||
context "when approval_uri does not match the sender's uri" do
|
||||
let(:approval_uri) { 'https://other.localhost/authorizations/1' }
|
||||
|
||||
it_behaves_like 'ignoring activity'
|
||||
end
|
||||
|
||||
context 'when approval_uri is missing' do
|
||||
let(:approval_uri) { nil }
|
||||
|
||||
it_behaves_like 'ignoring activity'
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
Reference in New Issue
Block a user