* Move ActivityPub::FetchRemoteAccountService to ActivityPub::FetchRemoteActorService ActivityPub::FetchRemoteAccountService is kept as a wrapper for when the actor is specifically required to be an Account * Refactor SignatureVerification to allow non-Account actors * fixup! Move ActivityPub::FetchRemoteAccountService to ActivityPub::FetchRemoteActorService * Refactor ActivityPub::FetchRemoteKeyService to potentially return non-Account actors * Refactor inbound ActivityPub payload processing to accept non-Account actors * Refactor inbound ActivityPub processing to accept activities relayed through non-Account * Refactor how Account key URIs are built * Refactor Request and drop unused key_id_format parameter * Rename ActivityPub::Dereferencer `signature_account` to `signature_actor`
		
			
				
	
	
		
			69 lines
		
	
	
	
		
			1.6 KiB
		
	
	
	
		
			Ruby
		
	
	
	
	
	
			
		
		
	
	
			69 lines
		
	
	
	
		
			1.6 KiB
		
	
	
	
		
			Ruby
		
	
	
	
	
	
| # frozen_string_literal: true
 | |
| 
 | |
| class ActivityPub::Dereferencer
 | |
|   include JsonLdHelper
 | |
| 
 | |
|   def initialize(uri, permitted_origin: nil, signature_actor: nil)
 | |
|     @uri               = uri
 | |
|     @permitted_origin  = permitted_origin
 | |
|     @signature_actor = signature_actor
 | |
|   end
 | |
| 
 | |
|   def object
 | |
|     @object ||= fetch_object!
 | |
|   end
 | |
| 
 | |
|   private
 | |
| 
 | |
|   def bear_cap?
 | |
|     @uri.start_with?('bear:')
 | |
|   end
 | |
| 
 | |
|   def fetch_object!
 | |
|     if bear_cap?
 | |
|       fetch_with_token!
 | |
|     else
 | |
|       fetch_with_signature!
 | |
|     end
 | |
|   end
 | |
| 
 | |
|   def fetch_with_token!
 | |
|     perform_request(bear_cap['u'], headers: { 'Authorization' => "Bearer #{bear_cap['t']}" })
 | |
|   end
 | |
| 
 | |
|   def fetch_with_signature!
 | |
|     perform_request(@uri)
 | |
|   end
 | |
| 
 | |
|   def bear_cap
 | |
|     @bear_cap ||= Addressable::URI.parse(@uri).query_values
 | |
|   end
 | |
| 
 | |
|   def perform_request(uri, headers: nil)
 | |
|     return if invalid_origin?(uri)
 | |
| 
 | |
|     req = Request.new(:get, uri)
 | |
| 
 | |
|     req.add_headers('Accept' => 'application/activity+json, application/ld+json')
 | |
|     req.add_headers(headers) if headers
 | |
|     req.on_behalf_of(@signature_actor) if @signature_actor
 | |
| 
 | |
|     req.perform do |res|
 | |
|       if res.code == 200
 | |
|         json = body_to_json(res.body_with_limit)
 | |
|         json if json.present? && json['id'] == uri
 | |
|       else
 | |
|         raise Mastodon::UnexpectedResponseError, res unless response_successful?(res) || response_error_unsalvageable?(res)
 | |
|       end
 | |
|     end
 | |
|   end
 | |
| 
 | |
|   def invalid_origin?(uri)
 | |
|     return true if unsupported_uri_scheme?(uri)
 | |
| 
 | |
|     needle   = Addressable::URI.parse(uri).host
 | |
|     haystack = Addressable::URI.parse(@permitted_origin).host
 | |
| 
 | |
|     !haystack.casecmp(needle).zero?
 | |
|   end
 | |
| end
 |