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
							
								
									9669557be1
								
							
						
					
					
						commit
						720214feb0
					
				
					 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…
	
	Add table
		
		Reference in a new issue