70 lines
1.6 KiB
Ruby
70 lines
1.6 KiB
Ruby
|
# 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
|