Fix status updates not being forwarded like deletes through ActivityPub (#17648)
Fix #17521
This commit is contained in:
		
					parent
					
						
							
								48caeb9d65
							
						
					
				
			
			
				commit
				
					
						0dc57ab6ed
					
				
			
		
					 3 changed files with 76 additions and 40 deletions
				
			
		|  | @ -37,50 +37,16 @@ class ActivityPub::Activity::Delete < ActivityPub::Activity | |||
| 
 | ||||
|       return if @status.nil? | ||||
| 
 | ||||
|       forward! if @json['signature'].present? && @status.distributable? | ||||
|       forwarder.forward! if forwarder.forwardable? | ||||
|       delete_now! | ||||
|     end | ||||
|   end | ||||
| 
 | ||||
|   def rebloggers_ids | ||||
|     return @rebloggers_ids if defined?(@rebloggers_ids) | ||||
|     @rebloggers_ids = @status.reblogs.includes(:account).references(:account).merge(Account.local).pluck(:account_id) | ||||
|   end | ||||
| 
 | ||||
|   def inboxes_for_reblogs | ||||
|     Account.where(id: ::Follow.where(target_account_id: rebloggers_ids).select(:account_id)).inboxes | ||||
|   end | ||||
| 
 | ||||
|   def replied_to_status | ||||
|     return @replied_to_status if defined?(@replied_to_status) | ||||
|     @replied_to_status = @status.thread | ||||
|   end | ||||
| 
 | ||||
|   def reply_to_local? | ||||
|     !replied_to_status.nil? && replied_to_status.account.local? | ||||
|   end | ||||
| 
 | ||||
|   def inboxes_for_reply | ||||
|     replied_to_status.account.followers.inboxes | ||||
|   end | ||||
| 
 | ||||
|   def forward! | ||||
|     inboxes = inboxes_for_reblogs | ||||
|     inboxes += inboxes_for_reply if reply_to_local? | ||||
|     inboxes -= [@account.preferred_inbox_url] | ||||
| 
 | ||||
|     sender_id = reply_to_local? ? replied_to_status.account_id : rebloggers_ids.first | ||||
| 
 | ||||
|     ActivityPub::LowPriorityDeliveryWorker.push_bulk(inboxes.uniq) do |inbox_url| | ||||
|       [payload, sender_id, inbox_url] | ||||
|     end | ||||
|   def forwarder | ||||
|     @forwarder ||= ActivityPub::Forwarder.new(@account, @json, @status) | ||||
|   end | ||||
| 
 | ||||
|   def delete_now! | ||||
|     RemoveStatusService.new.call(@status, redraft: false) | ||||
|   end | ||||
| 
 | ||||
|   def payload | ||||
|     @payload ||= Oj.dump(@json) | ||||
|   end | ||||
| end | ||||
|  |  | |||
|  | @ -22,10 +22,15 @@ class ActivityPub::Activity::Update < ActivityPub::Activity | |||
|   def update_status | ||||
|     return reject_payload! if invalid_origin?(@object['id']) | ||||
| 
 | ||||
|     status = Status.find_by(uri: object_uri, account_id: @account.id) | ||||
|     @status = Status.find_by(uri: object_uri, account_id: @account.id) | ||||
| 
 | ||||
|     return if status.nil? | ||||
|     return if @status.nil? | ||||
| 
 | ||||
|     ActivityPub::ProcessStatusUpdateService.new.call(status, @object) | ||||
|     forwarder.forward! if forwarder.forwardable? | ||||
|     ActivityPub::ProcessStatusUpdateService.new.call(@status, @object) | ||||
|   end | ||||
| 
 | ||||
|   def forwarder | ||||
|     @forwarder ||= ActivityPub::Forwarder.new(@account, @json, @status) | ||||
|   end | ||||
| end | ||||
|  |  | |||
							
								
								
									
										65
									
								
								app/lib/activitypub/forwarder.rb
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										65
									
								
								app/lib/activitypub/forwarder.rb
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,65 @@ | |||
| # frozen_string_literal: true | ||||
| 
 | ||||
| class ActivityPub::Forwarder | ||||
|   def initialize(account, original_json, status) | ||||
|     @json    = original_json | ||||
|     @account = account | ||||
|     @status  = status | ||||
|   end | ||||
| 
 | ||||
|   def forwardable? | ||||
|     @json['signature'].present? && @status.distributable? | ||||
|   end | ||||
| 
 | ||||
|   def forward! | ||||
|     ActivityPub::LowPriorityDeliveryWorker.push_bulk(inboxes) do |inbox_url| | ||||
|       [payload, signature_account_id, inbox_url] | ||||
|     end | ||||
|   end | ||||
| 
 | ||||
|   private | ||||
| 
 | ||||
|   def payload | ||||
|     @payload ||= Oj.dump(@json) | ||||
|   end | ||||
| 
 | ||||
|   def reblogged_by_account_ids | ||||
|     @reblogged_by_account_ids ||= @status.reblogs.includes(:account).references(:account).merge(Account.local).pluck(:account_id) | ||||
|   end | ||||
| 
 | ||||
|   def signature_account_id | ||||
|     @signature_account_id ||= begin | ||||
|       if in_reply_to_local? | ||||
|         in_reply_to.account_id | ||||
|       else | ||||
|         reblogged_by_account_ids.first | ||||
|       end | ||||
|     end | ||||
|   end | ||||
| 
 | ||||
|   def inboxes | ||||
|     @inboxes ||= begin | ||||
|       arr  = inboxes_for_followers_of_reblogged_by_accounts | ||||
|       arr += inboxes_for_followers_of_replied_to_account if in_reply_to_local? | ||||
|       arr -= [@account.preferred_inbox_url] | ||||
|       arr.uniq! | ||||
|       arr | ||||
|     end | ||||
|   end | ||||
| 
 | ||||
|   def inboxes_for_followers_of_reblogged_by_accounts | ||||
|     Account.where(id: ::Follow.where(target_account_id: reblogged_by_account_ids).select(:account_id)).inboxes | ||||
|   end | ||||
| 
 | ||||
|   def inboxes_for_followers_of_replied_to_account | ||||
|     in_reply_to.account.followers.inboxes | ||||
|   end | ||||
| 
 | ||||
|   def in_reply_to | ||||
|     @status.thread | ||||
|   end | ||||
| 
 | ||||
|   def in_reply_to_local? | ||||
|     @status.thread&.account&.local? | ||||
|   end | ||||
| end | ||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue