Add support for inlined objects in activity audience (#14514)
* Add support for inlined objects in activity audience * Add tests
This commit is contained in:
		
							parent
							
								
									ec75a4f48b
								
							
						
					
					
						commit
						4468fce63c
					
				
					 5 changed files with 62 additions and 12 deletions
				
			
		|  | @ -172,7 +172,7 @@ class ActivityPub::Activity | |||
|   end | ||||
| 
 | ||||
|   def first_mentioned_local_account | ||||
|     audience = (as_array(@json['to']) + as_array(@json['cc'])).uniq | ||||
|     audience = (as_array(@json['to']) + as_array(@json['cc'])).map { |x| value_or_id(x) }.uniq | ||||
|     local_usernames = audience.select { |uri| ActivityPub::TagManager.instance.local_uri?(uri) } | ||||
|                               .map { |uri| ActivityPub::TagManager.instance.uri_to_local_id(uri, :username) } | ||||
| 
 | ||||
|  |  | |||
|  | @ -34,12 +34,20 @@ class ActivityPub::Activity::Announce < ActivityPub::Activity | |||
| 
 | ||||
|   private | ||||
| 
 | ||||
|   def audience_to | ||||
|     as_array(@json['to']).map { |x| value_or_id(x) } | ||||
|   end | ||||
| 
 | ||||
|   def audience_cc | ||||
|     as_array(@json['cc']).map { |x| value_or_id(x) } | ||||
|   end | ||||
| 
 | ||||
|   def visibility_from_audience | ||||
|     if equals_or_includes?(@json['to'], ActivityPub::TagManager::COLLECTIONS[:public]) | ||||
|     if audience_to.include?(ActivityPub::TagManager::COLLECTIONS[:public]) | ||||
|       :public | ||||
|     elsif equals_or_includes?(@json['cc'], ActivityPub::TagManager::COLLECTIONS[:public]) | ||||
|     elsif audience_cc.include?(ActivityPub::TagManager::COLLECTIONS[:public]) | ||||
|       :unlisted | ||||
|     elsif equals_or_includes?(@json['to'], @account.followers_url) | ||||
|     elsif audience_to.include?(@account.followers_url) | ||||
|       :private | ||||
|     else | ||||
|       :direct | ||||
|  |  | |||
|  | @ -65,11 +65,11 @@ class ActivityPub::Activity::Create < ActivityPub::Activity | |||
|   end | ||||
| 
 | ||||
|   def audience_to | ||||
|     @object['to'] || @json['to'] | ||||
|     as_array(@object['to'] || @json['to']).map { |x| value_or_id(x) } | ||||
|   end | ||||
| 
 | ||||
|   def audience_cc | ||||
|     @object['cc'] || @json['cc'] | ||||
|     as_array(@object['cc'] || @json['cc']).map { |x| value_or_id(x) } | ||||
|   end | ||||
| 
 | ||||
|   def process_status | ||||
|  | @ -122,7 +122,7 @@ class ActivityPub::Activity::Create < ActivityPub::Activity | |||
|   end | ||||
| 
 | ||||
|   def process_audience | ||||
|     (as_array(audience_to) + as_array(audience_cc)).uniq.each do |audience| | ||||
|     (audience_to + audience_cc).uniq.each do |audience| | ||||
|       next if audience == ActivityPub::TagManager::COLLECTIONS[:public] | ||||
| 
 | ||||
|       # Unlike with tags, there is no point in resolving accounts we don't already | ||||
|  | @ -352,11 +352,11 @@ class ActivityPub::Activity::Create < ActivityPub::Activity | |||
|   end | ||||
| 
 | ||||
|   def visibility_from_audience | ||||
|     if equals_or_includes?(audience_to, ActivityPub::TagManager::COLLECTIONS[:public]) | ||||
|     if audience_to.include?(ActivityPub::TagManager::COLLECTIONS[:public]) | ||||
|       :public | ||||
|     elsif equals_or_includes?(audience_cc, ActivityPub::TagManager::COLLECTIONS[:public]) | ||||
|     elsif audience_cc.include?(ActivityPub::TagManager::COLLECTIONS[:public]) | ||||
|       :unlisted | ||||
|     elsif equals_or_includes?(audience_to, @account.followers_url) | ||||
|     elsif audience_to.include?(@account.followers_url) | ||||
|       :private | ||||
|     else | ||||
|       :direct | ||||
|  | @ -365,7 +365,7 @@ class ActivityPub::Activity::Create < ActivityPub::Activity | |||
| 
 | ||||
|   def audience_includes?(account) | ||||
|     uri = ActivityPub::TagManager.instance.uri_for(account) | ||||
|     equals_or_includes?(audience_to, uri) || equals_or_includes?(audience_cc, uri) | ||||
|     audience_to.include?(uri) || audience_cc.include?(uri) | ||||
|   end | ||||
| 
 | ||||
|   def replied_to_status | ||||
|  | @ -477,7 +477,7 @@ class ActivityPub::Activity::Create < ActivityPub::Activity | |||
|   def addresses_local_accounts? | ||||
|     return true if @options[:delivered_to_account_id] | ||||
| 
 | ||||
|     local_usernames = (as_array(audience_to) + as_array(audience_cc)).uniq.select { |uri| ActivityPub::TagManager.instance.local_uri?(uri) }.map { |uri| ActivityPub::TagManager.instance.uri_to_local_id(uri, :username) } | ||||
|     local_usernames = (audience_to + audience_cc).uniq.select { |uri| ActivityPub::TagManager.instance.local_uri?(uri) }.map { |uri| ActivityPub::TagManager.instance.uri_to_local_id(uri, :username) } | ||||
| 
 | ||||
|     return false if local_usernames.empty? | ||||
| 
 | ||||
|  |  | |||
|  | @ -73,6 +73,26 @@ RSpec.describe ActivityPub::Activity::Announce do | |||
|           expect(sender.reblogged?(sender.statuses.first)).to be true | ||||
|         end | ||||
|       end | ||||
| 
 | ||||
|       context 'self-boost of a previously unknown status with correct attributedTo, inlined Collection in audience' do | ||||
|         let(:object_json) do | ||||
|           { | ||||
|             id: 'https://example.com/actor#bar', | ||||
|             type: 'Note', | ||||
|             content: 'Lorem ipsum', | ||||
|             attributedTo: 'https://example.com/actor', | ||||
|             to: { | ||||
|               'type': 'OrderedCollection', | ||||
|               'id': 'http://example.com/followers', | ||||
|               'first': 'http://example.com/followers?page=true', | ||||
|             } | ||||
|           } | ||||
|         end | ||||
| 
 | ||||
|         it 'creates a reblog by sender of status' do | ||||
|           expect(sender.reblogged?(sender.statuses.first)).to be true | ||||
|         end | ||||
|       end | ||||
|     end | ||||
| 
 | ||||
|     context 'when the status belongs to a local user' do | ||||
|  |  | |||
|  | @ -121,6 +121,28 @@ RSpec.describe ActivityPub::Activity::Create do | |||
|         end | ||||
|       end | ||||
| 
 | ||||
|       context 'private with inlined Collection in audience' do | ||||
|         let(:object_json) do | ||||
|           { | ||||
|             id: [ActivityPub::TagManager.instance.uri_for(sender), '#bar'].join, | ||||
|             type: 'Note', | ||||
|             content: 'Lorem ipsum', | ||||
|             to: { | ||||
|               'type': 'OrderedCollection', | ||||
|               'id': 'http://example.com/followers', | ||||
|               'first': 'http://example.com/followers?page=true', | ||||
|             } | ||||
|           } | ||||
|         end | ||||
| 
 | ||||
|         it 'creates status' do | ||||
|           status = sender.statuses.first | ||||
| 
 | ||||
|           expect(status).to_not be_nil | ||||
|           expect(status.visibility).to eq 'private' | ||||
|         end | ||||
|       end | ||||
| 
 | ||||
|       context 'limited' do | ||||
|         let(:recipient) { Fabricate(:account) } | ||||
| 
 | ||||
|  |  | |||
		Loading…
	
		Reference in a new issue