diff options
author | Thibaut Girka <thib@sitedethib.com> | 2020-08-30 16:13:08 +0200 |
---|---|---|
committer | Thibaut Girka <thib@sitedethib.com> | 2020-08-30 16:13:08 +0200 |
commit | 8c3c27bf063d648823da39a206be3efd285611ad (patch) | |
tree | c78c0bed2bab5ed64a7dfd546b91b21600947112 /app/lib/activitypub/dereferencer.rb | |
parent | 30632adf9eda6d83a9b4269f23f11ced5e09cd93 (diff) | |
parent | 52157fdcba0837c782edbfd240be07cabc551de9 (diff) |
Merge branch 'master' into glitch-soc/merge-upstream
Conflicts: - `app/controllers/accounts_controller.rb`: Upstream change too close to a glitch-soc change related to instance-local toots. Merged upstream changes. - `app/services/fan_out_on_write_service.rb`: Minor conflict due to glitch-soc's handling of Direct Messages, merged upstream changes. - `yarn.lock`: Not really a conflict, caused by glitch-soc-only dependencies being textually too close to updated upstream dependencies. Merged upstream changes.
Diffstat (limited to 'app/lib/activitypub/dereferencer.rb')
-rw-r--r-- | app/lib/activitypub/dereferencer.rb | 69 |
1 files changed, 69 insertions, 0 deletions
diff --git a/app/lib/activitypub/dereferencer.rb b/app/lib/activitypub/dereferencer.rb new file mode 100644 index 000000000..bea69608f --- /dev/null +++ b/app/lib/activitypub/dereferencer.rb @@ -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 |