Fix some ActivityPub JSON bugs (#4796)
- Fix assumption that `url` is always a string. Handle it if it's an array of strings, array of objects, object, or string, both for accounts and for objects - `sharedInbox` is actually supposed to be under `endpoints`, handle both cases and adjust the serializer
This commit is contained in:
		
							parent
							
								
									36872cd22c
								
							
						
					
					
						commit
						be4bfd2ec1
					
				
					 3 changed files with 40 additions and 8 deletions
				
			
		|  | @ -33,7 +33,7 @@ class ActivityPub::Activity::Create < ActivityPub::Activity | |||
|   def status_params | ||||
|     { | ||||
|       uri: @object['id'], | ||||
|       url: @object['url'] || @object['id'], | ||||
|       url: object_url || @object['id'], | ||||
|       account: @account, | ||||
|       text: text_from_content || '', | ||||
|       language: language_from_content, | ||||
|  | @ -147,6 +147,16 @@ class ActivityPub::Activity::Create < ActivityPub::Activity | |||
|     @object['contentMap'].keys.first | ||||
|   end | ||||
| 
 | ||||
|   def object_url | ||||
|     return if @object['url'].blank? | ||||
| 
 | ||||
|     value = first_of_value(@object['url']) | ||||
| 
 | ||||
|     return value if value.is_a?(String) | ||||
| 
 | ||||
|     value['href'] | ||||
|   end | ||||
| 
 | ||||
|   def language_map? | ||||
|     @object['contentMap'].is_a?(Hash) && !@object['contentMap'].empty? | ||||
|   end | ||||
|  |  | |||
|  | @ -4,7 +4,7 @@ class ActivityPub::ActorSerializer < ActiveModel::Serializer | |||
|   include RoutingHelper | ||||
| 
 | ||||
|   attributes :id, :type, :following, :followers, | ||||
|              :inbox, :outbox, :shared_inbox, | ||||
|              :inbox, :outbox, | ||||
|              :preferred_username, :name, :summary, | ||||
|              :url, :manually_approves_followers | ||||
| 
 | ||||
|  | @ -24,6 +24,18 @@ class ActivityPub::ActorSerializer < ActiveModel::Serializer | |||
|     end | ||||
|   end | ||||
| 
 | ||||
|   class EndpointsSerializer < ActiveModel::Serializer | ||||
|     include RoutingHelper | ||||
| 
 | ||||
|     attributes :shared_inbox | ||||
| 
 | ||||
|     def shared_inbox | ||||
|       inbox_url | ||||
|     end | ||||
|   end | ||||
| 
 | ||||
|   has_one :endpoints, serializer: EndpointsSerializer | ||||
| 
 | ||||
|   has_one :icon,  serializer: ImageSerializer, if: :avatar_exists? | ||||
|   has_one :image, serializer: ImageSerializer, if: :header_exists? | ||||
| 
 | ||||
|  | @ -51,8 +63,8 @@ class ActivityPub::ActorSerializer < ActiveModel::Serializer | |||
|     account_outbox_url(object) | ||||
|   end | ||||
| 
 | ||||
|   def shared_inbox | ||||
|     inbox_url | ||||
|   def endpoints | ||||
|     object | ||||
|   end | ||||
| 
 | ||||
|   def preferred_username | ||||
|  |  | |||
|  | @ -6,7 +6,7 @@ class ActivityPub::ProcessAccountService < BaseService | |||
|   # Should be called with confirmed valid JSON | ||||
|   # and WebFinger-resolved username and domain | ||||
|   def call(username, domain, json) | ||||
|     return unless json['inbox'].present? | ||||
|     return if json['inbox'].blank? | ||||
| 
 | ||||
|     @json     = json | ||||
|     @uri      = @json['id'] | ||||
|  | @ -42,9 +42,9 @@ class ActivityPub::ProcessAccountService < BaseService | |||
|     @account.protocol            = :activitypub | ||||
|     @account.inbox_url           = @json['inbox'] || '' | ||||
|     @account.outbox_url          = @json['outbox'] || '' | ||||
|     @account.shared_inbox_url    = @json['sharedInbox'] || '' | ||||
|     @account.shared_inbox_url    = (@json['endpoints'].is_a?(Hash) ? @json['endpoints']['sharedInbox'] : @json['sharedInbox']) || '' | ||||
|     @account.followers_url       = @json['followers'] || '' | ||||
|     @account.url                 = @json['url'] || @uri | ||||
|     @account.url                 = url || @uri | ||||
|     @account.display_name        = @json['name'] || '' | ||||
|     @account.note                = @json['summary'] || '' | ||||
|     @account.avatar_remote_url   = image_url('icon') | ||||
|  | @ -62,7 +62,7 @@ class ActivityPub::ProcessAccountService < BaseService | |||
|     value = first_of_value(@json[key]) | ||||
| 
 | ||||
|     return if value.nil? | ||||
|     return @json[key]['url'] if @json[key].is_a?(Hash) | ||||
|     return value['url'] if value.is_a?(Hash) | ||||
| 
 | ||||
|     image = fetch_resource(value) | ||||
|     image['url'] if image | ||||
|  | @ -78,6 +78,16 @@ class ActivityPub::ProcessAccountService < BaseService | |||
|     key['publicKeyPem'] if key | ||||
|   end | ||||
| 
 | ||||
|   def url | ||||
|     return if @json['url'].blank? | ||||
| 
 | ||||
|     value = first_of_value(@json['url']) | ||||
| 
 | ||||
|     return value if value.is_a?(String) | ||||
| 
 | ||||
|     value['href'] | ||||
|   end | ||||
| 
 | ||||
|   def auto_suspend? | ||||
|     domain_block && domain_block.suspend? | ||||
|   end | ||||
|  |  | |||
		Loading…
	
		Reference in a new issue