mirror of
https://github.com/mastodon/mastodon.git
synced 2026-03-21 18:05:23 -05:00
Start of handling FeatureRequest activities (#38193)
This commit is contained in:
parent
8d5d66ecfc
commit
c993daa347
|
|
@ -59,6 +59,8 @@ class ActivityPub::Activity
|
|||
ActivityPub::Activity::Move
|
||||
when 'QuoteRequest'
|
||||
ActivityPub::Activity::QuoteRequest
|
||||
when 'FeatureRequest'
|
||||
ActivityPub::Activity::FeatureRequest
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
|||
46
app/lib/activitypub/activity/feature_request.rb
Normal file
46
app/lib/activitypub/activity/feature_request.rb
Normal file
|
|
@ -0,0 +1,46 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
class ActivityPub::Activity::FeatureRequest < ActivityPub::Activity
|
||||
include Payloadable
|
||||
|
||||
def perform
|
||||
return unless Mastodon::Feature.collections_federation_enabled?
|
||||
return if non_matching_uri_hosts?(@account.uri, @json['id'])
|
||||
|
||||
@collection = @account.collections.find_by(uri: value_or_id(@json['instrument']))
|
||||
@featured_account = ActivityPub::TagManager.instance.uris_to_local_accounts([value_or_id(@json['object'])]).first
|
||||
|
||||
return if @collection.nil? || @featured_account.nil?
|
||||
|
||||
if AccountPolicy.new(@account, @featured_account).feature?
|
||||
accept_request!
|
||||
else
|
||||
reject_request!
|
||||
end
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def accept_request!
|
||||
collection_item = @collection.collection_items.create!(
|
||||
account: @featured_account,
|
||||
state: :accepted
|
||||
)
|
||||
|
||||
queue_delivery!(collection_item, ActivityPub::AcceptFeatureRequestSerializer)
|
||||
end
|
||||
|
||||
def reject_request!
|
||||
collection_item = @collection.collection_items.build(
|
||||
account: @featured_account,
|
||||
state: :rejected
|
||||
)
|
||||
|
||||
queue_delivery!(collection_item, ActivityPub::RejectFeatureRequestSerializer)
|
||||
end
|
||||
|
||||
def queue_delivery!(collection_item, serializer)
|
||||
json = Oj.dump(serialize_payload(collection_item, serializer))
|
||||
ActivityPub::DeliveryWorker.perform_async(json, @featured_account.id, @account.inbox_url)
|
||||
end
|
||||
end
|
||||
|
|
@ -32,7 +32,7 @@ class CollectionItem < ApplicationRecord
|
|||
validates :approval_uri, presence: true, unless: -> { local? || account&.local? }
|
||||
validates :account, presence: true, if: :accepted?
|
||||
validates :object_uri, presence: true, if: -> { account.nil? }
|
||||
validates :uri, presence: true, if: :remote?
|
||||
validates :uri, presence: true, if: :remote_item_with_remote_account?
|
||||
|
||||
before_validation :set_position, on: :create
|
||||
before_validation :set_activity_uri, only: :create, if: :local_item_with_remote_account?
|
||||
|
|
@ -50,6 +50,10 @@ class CollectionItem < ApplicationRecord
|
|||
local? && account&.remote?
|
||||
end
|
||||
|
||||
def remote_item_with_remote_account?
|
||||
remote? && account&.remote?
|
||||
end
|
||||
|
||||
def object_type
|
||||
:featured_item
|
||||
end
|
||||
|
|
|
|||
54
spec/lib/activitypub/activity/feature_request_spec.rb
Normal file
54
spec/lib/activitypub/activity/feature_request_spec.rb
Normal file
|
|
@ -0,0 +1,54 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
require 'rails_helper'
|
||||
|
||||
RSpec.describe ActivityPub::Activity::FeatureRequest do
|
||||
let(:sender) { Fabricate(:remote_account) }
|
||||
let(:recipient) { Fabricate(:account, discoverable:) }
|
||||
let(:collection) { Fabricate(:remote_collection, account: sender) }
|
||||
|
||||
let(:json) do
|
||||
{
|
||||
'@context' => [
|
||||
'https://www.w3.org/ns/activitystreams',
|
||||
],
|
||||
'id' => 'https://example.com/feature_requests/1',
|
||||
'type' => 'FeatureRequest',
|
||||
'actor' => sender.uri,
|
||||
'object' => ActivityPub::TagManager.instance.uri_for(recipient),
|
||||
'instrument' => collection.uri,
|
||||
}
|
||||
end
|
||||
|
||||
describe '#perform', feature: :collections_federation do
|
||||
subject { described_class.new(json, sender) }
|
||||
|
||||
context 'when recipient is discoverable' do
|
||||
let(:discoverable) { true }
|
||||
|
||||
it 'schedules a job to send an `Accept` activity' do
|
||||
expect { subject.perform }
|
||||
.to enqueue_sidekiq_job(ActivityPub::DeliveryWorker)
|
||||
.with(satisfying do |body|
|
||||
response_json = JSON.parse(body)
|
||||
response_json['type'] == 'Accept' &&
|
||||
response_json['to'] == sender.uri
|
||||
end, recipient.id, sender.inbox_url)
|
||||
end
|
||||
end
|
||||
|
||||
context 'when recipient is not discoverable' do
|
||||
let(:discoverable) { false }
|
||||
|
||||
it 'schedules a job to send a `Reject` activity' do
|
||||
expect { subject.perform }
|
||||
.to enqueue_sidekiq_job(ActivityPub::DeliveryWorker)
|
||||
.with(satisfying do |body|
|
||||
response_json = JSON.parse(body)
|
||||
response_json['type'] == 'Reject' &&
|
||||
response_json['to'] == sender.uri
|
||||
end, recipient.id, sender.inbox_url)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
@ -17,8 +17,9 @@ RSpec.describe CollectionItem do
|
|||
end
|
||||
|
||||
context 'when item is not local' do
|
||||
subject { Fabricate.build(:collection_item, collection: remote_collection) }
|
||||
subject { Fabricate.build(:collection_item, collection: remote_collection, account:) }
|
||||
|
||||
let(:account) { Fabricate.build(:remote_account) }
|
||||
let(:remote_collection) { Fabricate.build(:collection, local: false) }
|
||||
|
||||
it { is_expected.to validate_presence_of(:uri) }
|
||||
|
|
@ -28,6 +29,12 @@ RSpec.describe CollectionItem do
|
|||
|
||||
it { is_expected.to validate_presence_of(:approval_uri) }
|
||||
end
|
||||
|
||||
context 'when account is local' do
|
||||
let(:account) { Fabricate.build(:account) }
|
||||
|
||||
it { is_expected.to_not validate_presence_of(:uri) }
|
||||
end
|
||||
end
|
||||
|
||||
context 'when account is not present' do
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user