Add support for dereferencing objects through bearcaps (#14683)
This commit is contained in:
		
							parent
							
								
									ce8f33dd2f
								
							
						
					
					
						commit
						52157fdcba
					
				
					 4 changed files with 166 additions and 14 deletions
				
			
		
							
								
								
									
										69
									
								
								app/lib/activitypub/dereferencer.rb
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										69
									
								
								app/lib/activitypub/dereferencer.rb
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,69 @@ | |||
| # frozen_string_literal: true | ||||
| 
 | ||||
| class ActivityPub::Dereferencer | ||||
|   include JsonLdHelper | ||||
| 
 | ||||
|   def initialize(uri, permitted_origin: nil, signature_account: nil) | ||||
|     @uri               = uri | ||||
|     @permitted_origin  = permitted_origin | ||||
|     @signature_account = signature_account | ||||
|   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_account) if @signature_account | ||||
| 
 | ||||
|     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 | ||||
		Reference in a new issue