]> cat aescling's git repositories - mastodon.git/commitdiff
Fetch boosted statuses on behalf of a follower (fixes #7426) (#7459)
authorThibG <thib@sitedethib.com>
Sat, 12 May 2018 14:48:32 +0000 (16:48 +0200)
committerEugen Rochko <eugen@zeonfederated.com>
Sat, 12 May 2018 14:48:32 +0000 (16:48 +0200)
When an ActivityPub Announce is processed and the boosted toot is not known,
fetch it on behalf of one of the booster's followers. This is to allow
fetching self-boosts of previously-unknown private toots.

If fetching on behalf of a user fails, try fetching it anonymously: the
selected follower of a boosting user may be banned by the boosted toot's
author.

app/helpers/jsonld_helper.rb
app/lib/activitypub/activity/announce.rb
app/services/activitypub/fetch_remote_status_service.rb

index e9056166c103793ff55ccdba803b6ab2feabfd31..9d2b6cf00d28024db7c3cb4a5fd9a9b152fd66cf 100644 (file)
@@ -52,18 +52,22 @@ module JsonLdHelper
     graph.dump(:normalize)
   end
 
-  def fetch_resource(uri, id)
+  def fetch_resource(uri, id, on_behalf_of = nil)
     unless id
-      json = fetch_resource_without_id_validation(uri)
+      json = fetch_resource_without_id_validation(uri, on_behalf_of)
       return unless json
       uri = json['id']
     end
 
-    json = fetch_resource_without_id_validation(uri)
+    json = fetch_resource_without_id_validation(uri, on_behalf_of)
     json.present? && json['id'] == uri ? json : nil
   end
 
-  def fetch_resource_without_id_validation(uri)
+  def fetch_resource_without_id_validation(uri, on_behalf_of = nil)
+    build_request(uri, on_behalf_of).perform do |response|
+      return body_to_json(response.body_with_limit) if response.code == 200
+    end
+    # If request failed, retry without doing it on behalf of a user
     build_request(uri).perform do |response|
       response.code == 200 ? body_to_json(response.body_with_limit) : nil
     end
@@ -85,8 +89,9 @@ module JsonLdHelper
 
   private
 
-  def build_request(uri)
+  def build_request(uri, on_behalf_of = nil)
     request = Request.new(:get, uri)
+    request.on_behalf_of(on_behalf_of) if on_behalf_of
     request.add_headers('Accept' => 'application/activity+json, application/ld+json')
     request
   end
index 7e146ea8c43d79f20ed6e52a4ad082b36a99268c..f810c88a27a24f69e8059da422ce012c377c3eb2 100644 (file)
@@ -30,7 +30,7 @@ class ActivityPub::Activity::Announce < ActivityPub::Activity
     if object_uri.start_with?('http')
       return if ActivityPub::TagManager.instance.local_uri?(object_uri)
 
-      ActivityPub::FetchRemoteStatusService.new.call(object_uri, id: true)
+      ActivityPub::FetchRemoteStatusService.new.call(object_uri, id: true, on_behalf_of: @account.followers.local.first)
     elsif @object['url'].present?
       ::FetchRemoteStatusService.new.call(@object['url'])
     end
index b6c00a9e7e2ba70c95f6646ac015440786691037..2b447abb32eb5fa95771d9cb7424b138326f6125 100644 (file)
@@ -4,9 +4,9 @@ class ActivityPub::FetchRemoteStatusService < BaseService
   include JsonLdHelper
 
   # Should be called when uri has already been checked for locality
-  def call(uri, id: true, prefetched_body: nil)
+  def call(uri, id: true, prefetched_body: nil, on_behalf_of: nil)
     @json = if prefetched_body.nil?
-              fetch_resource(uri, id)
+              fetch_resource(uri, id, on_behalf_of)
             else
               body_to_json(prefetched_body)
             end