Add support for fetching Create and Announce activities by URI (#16383)
* Add support for fetching Create and Announce activities by URI This should improve compatibility with ZAP and offer a way to fetch boosts, which is currently not possible. * Add tests
This commit is contained in:
		
							parent
							
								
									70931fd687
								
							
						
					
					
						commit
						3f9b28ce26
					
				
					 2 changed files with 60 additions and 10 deletions
				
			
		|  | @ -13,7 +13,20 @@ class ActivityPub::FetchRemoteStatusService < BaseService | |||
|       end | ||||
|     end | ||||
| 
 | ||||
|     return if !(supported_context? && expected_type?) || actor_id.nil? || !trustworthy_attribution?(@json['id'], actor_id) | ||||
|     return unless supported_context? | ||||
| 
 | ||||
|     actor_id = nil | ||||
|     activity_json = nil | ||||
| 
 | ||||
|     if expected_object_type? | ||||
|       actor_id = value_or_id(first_of_value(@json['attributedTo'])) | ||||
|       activity_json = { 'type' => 'Create', 'actor' => actor_id, 'object' => @json } | ||||
|     elsif expected_activity_type? | ||||
|       actor_id = value_or_id(first_of_value(@json['actor'])) | ||||
|       activity_json = @json | ||||
|     end | ||||
| 
 | ||||
|     return if activity_json.nil? || !trustworthy_attribution?(@json['id'], actor_id) | ||||
| 
 | ||||
|     actor = ActivityPub::TagManager.instance.uri_to_resource(actor_id, Account) | ||||
|     actor = ActivityPub::FetchRemoteAccountService.new.call(actor_id, id: true) if actor.nil? || needs_update?(actor) | ||||
|  | @ -25,14 +38,6 @@ class ActivityPub::FetchRemoteStatusService < BaseService | |||
| 
 | ||||
|   private | ||||
| 
 | ||||
|   def activity_json | ||||
|     { 'type' => 'Create', 'actor' => actor_id, 'object' => @json } | ||||
|   end | ||||
| 
 | ||||
|   def actor_id | ||||
|     value_or_id(first_of_value(@json['attributedTo'])) | ||||
|   end | ||||
| 
 | ||||
|   def trustworthy_attribution?(uri, attributed_to) | ||||
|     return false if uri.nil? || attributed_to.nil? | ||||
|     Addressable::URI.parse(uri).normalized_host.casecmp(Addressable::URI.parse(attributed_to).normalized_host).zero? | ||||
|  | @ -42,7 +47,11 @@ class ActivityPub::FetchRemoteStatusService < BaseService | |||
|     super(@json) | ||||
|   end | ||||
| 
 | ||||
|   def expected_type? | ||||
|   def expected_activity_type? | ||||
|     equals_or_includes_any?(@json['type'], %w(Create Announce)) | ||||
|   end | ||||
| 
 | ||||
|   def expected_object_type? | ||||
|     equals_or_includes_any?(@json['type'], ActivityPub::Activity::Create::SUPPORTED_TYPES + ActivityPub::Activity::Create::CONVERTED_TYPES) | ||||
|   end | ||||
| 
 | ||||
|  |  | |||
|  | @ -145,5 +145,46 @@ RSpec.describe ActivityPub::FetchRemoteStatusService, type: :service do | |||
|         expect(sender.statuses.first).to be_nil | ||||
|       end | ||||
|     end | ||||
| 
 | ||||
|     context 'with a valid Create activity' do | ||||
|       let(:object) do | ||||
|         { | ||||
|           '@context': 'https://www.w3.org/ns/activitystreams', | ||||
|           id: "https://#{valid_domain}/@foo/1234/create", | ||||
|           type: 'Create', | ||||
|           actor: ActivityPub::TagManager.instance.uri_for(sender), | ||||
|           object: note, | ||||
|         } | ||||
|       end | ||||
| 
 | ||||
|       it 'creates status' do | ||||
|         status = sender.statuses.first | ||||
| 
 | ||||
|         expect(status).to_not be_nil | ||||
|         expect(status.uri).to eq note[:id] | ||||
|         expect(status.text).to eq note[:content] | ||||
|       end | ||||
|     end | ||||
| 
 | ||||
|     context 'with a Create activity with a mismatching id' do | ||||
|       let(:object) do | ||||
|         { | ||||
|           '@context': 'https://www.w3.org/ns/activitystreams', | ||||
|           id: "https://#{valid_domain}/@foo/1234/create", | ||||
|           type: 'Create', | ||||
|           actor: ActivityPub::TagManager.instance.uri_for(sender), | ||||
|           object: { | ||||
|             id: "https://real.address/@foo/1234", | ||||
|             type: 'Note', | ||||
|             content: 'Lorem ipsum', | ||||
|             attributedTo: ActivityPub::TagManager.instance.uri_for(sender), | ||||
|           }, | ||||
|         } | ||||
|       end | ||||
| 
 | ||||
|       it 'does not create status' do | ||||
|         expect(sender.statuses.first).to be_nil | ||||
|       end | ||||
|     end | ||||
|   end | ||||
| end | ||||
|  |  | |||
		Loading…
	
		Reference in a new issue