activitypub: fix up accept/reject semantics for following
authorWilliam Pitcock <nenolod@dereferenced.org>
Fri, 25 May 2018 06:09:01 +0000 (06:09 +0000)
committerWilliam Pitcock <nenolod@dereferenced.org>
Fri, 25 May 2018 06:14:18 +0000 (06:14 +0000)
fixes #175

lib/pleroma/web/activity_pub/transmogrifier.ex
lib/pleroma/web/mastodon_api/mastodon_api_controller.ex

index 803445011357a3c464ce4b3400f16e2404e32306..eaa716ceadc7987e2dd4c3d98f90cb867031b0da 100644 (file)
@@ -7,6 +7,7 @@ defmodule Pleroma.Web.ActivityPub.Transmogrifier do
   alias Pleroma.Activity
   alias Pleroma.Repo
   alias Pleroma.Web.ActivityPub.ActivityPub
+  alias Pleroma.Web.ActivityPub.Utils
 
   import Ecto.Query
 
@@ -145,6 +146,48 @@ defmodule Pleroma.Web.ActivityPub.Transmogrifier do
     end
   end
 
+  defp get_follow_activity(follow_object) do
+    cond do
+      is_map(follow_object) ->
+        {:ok, follow_object}
+
+      is_binary(follow_object) ->
+        object = get_obj_helper(follow_object) || ActivityPub.fetch_object_from_id(follow_object)
+        if object do
+          {:ok, object}
+        else
+          {:error, nil}
+        end
+
+      true ->
+        {:error, nil}
+    end
+  end
+
+  def handle_incoming(
+        %{"type" => "Accept", "object" => follow_object, "actor" => actor, "id" => id} = data
+      ) do
+    with %User{} = followed <- User.get_or_fetch_by_ap_id(actor),
+         {:ok, follow_activity} <- get_follow_activity(follow_object),
+         %User{local: true} = follower <- User.get_cached_by_ap_id(follow_activity["actor"]) do
+      User.follow(follower, followed)
+
+      {:ok, data}
+    end
+  end
+
+  def handle_incoming(
+        %{"type" => "Reject", "object" => follow_object, "actor" => actor, "id" => id} = data
+      ) do
+    with %User{} = followed <- User.get_or_fetch_by_ap_id(actor),
+         {:ok, follow_activity} <- get_follow_activity(follow_object),
+         %User{local: true} = follower <- User.get_cached_by_ap_id(follow_activity["actor"]),
+         {:ok, follow_activity} <- Utils.fetch_latest_follow(follower, followed),
+         {:ok, activity} <- ActivityPub.delete(follow_activity, false) do
+      {:ok, activity}
+    end
+  end
+
   def handle_incoming(
         %{"type" => "Like", "object" => object_id, "actor" => actor, "id" => id} = _data
       ) do
index 460942f1a6e9ce6a88703c8536ed4b745c896e93..d50d2d9b56e3dcf45a362c22c8884bf2422d73d4 100644 (file)
@@ -429,7 +429,6 @@ defmodule Pleroma.Web.MastodonAPI.MastodonAPIController do
 
   def follow(%{assigns: %{user: follower}} = conn, %{"id" => id}) do
     with %User{} = followed <- Repo.get(User, id),
-         {:ok, follower} <- User.follow(follower, followed),
          {:ok, _activity} <- ActivityPub.follow(follower, followed) do
       render(conn, AccountView, "relationship.json", %{user: follower, target: followed})
     else
@@ -442,7 +441,6 @@ defmodule Pleroma.Web.MastodonAPI.MastodonAPIController do
 
   def follow(%{assigns: %{user: follower}} = conn, %{"uri" => uri}) do
     with %User{} = followed <- Repo.get_by(User, nickname: uri),
-         {:ok, follower} <- User.follow(follower, followed),
          {:ok, _activity} <- ActivityPub.follow(follower, followed) do
       render(conn, AccountView, "account.json", %{user: followed})
     else