Transmogrifier: Move following to the pipeline.
authorlain <lain@soykaf.club>
Wed, 8 Jul 2020 12:30:53 +0000 (14:30 +0200)
committerlain <lain@soykaf.club>
Wed, 8 Jul 2020 12:30:53 +0000 (14:30 +0200)
lib/pleroma/web/activity_pub/object_validators/follow_validator.ex
lib/pleroma/web/activity_pub/side_effects.ex
lib/pleroma/web/activity_pub/transmogrifier.ex
test/web/activity_pub/transmogrifier/follow_handling_test.exs

index 2035ad9ba2af1c7faa778a70e4f49c1478c4b691..ca27246168cb61dfffbb08130656e1b8e3ff2a0d 100644 (file)
@@ -19,6 +19,7 @@ defmodule Pleroma.Web.ActivityPub.ObjectValidators.FollowValidator do
     field(:to, ObjectValidators.Recipients, default: [])
     field(:cc, ObjectValidators.Recipients, default: [])
     field(:object, ObjectValidators.ObjectID)
+    field(:state, :string, default: "pending")
   end
 
   def cast_data(data) do
@@ -30,6 +31,7 @@ defmodule Pleroma.Web.ActivityPub.ObjectValidators.FollowValidator do
     cng
     |> validate_required([:id, :type, :actor, :to, :cc, :object])
     |> validate_inclusion(:type, ["Follow"])
+    |> validate_inclusion(:state, ~w{pending reject accept})
     |> validate_actor_presence()
     |> validate_actor_presence(field_name: :object)
   end
index 61feeae4d68fb4799634b58b03a0ceaad9c3800d..2845609138a86fba5c9cbcc219e6d2057496621c 100644 (file)
@@ -9,6 +9,7 @@ defmodule Pleroma.Web.ActivityPub.SideEffects do
   alias Pleroma.Activity.Ir.Topics
   alias Pleroma.Chat
   alias Pleroma.Chat.MessageReference
+  alias Pleroma.FollowingRelationship
   alias Pleroma.Notification
   alias Pleroma.Object
   alias Pleroma.Repo
@@ -21,6 +22,65 @@ defmodule Pleroma.Web.ActivityPub.SideEffects do
 
   def handle(object, meta \\ [])
 
+  # Tasks this handle
+  # - Follows if possible
+  # - Sends a notification
+  # - Generates accept or reject if appropriate
+  def handle(
+        %{
+          data: %{
+            "id" => follow_id,
+            "type" => "Follow",
+            "object" => followed_user,
+            "actor" => following_user
+          }
+        } = object,
+        meta
+      ) do
+    with %User{} = follower <- User.get_cached_by_ap_id(following_user),
+         %User{} = followed <- User.get_cached_by_ap_id(followed_user),
+         {_, {:ok, _}, _, _} <-
+           {:following, User.follow(follower, followed, :follow_pending), follower, followed} do
+      if followed.local && !followed.locked do
+        Utils.update_follow_state_for_all(object, "accept")
+        FollowingRelationship.update(follower, followed, :follow_accept)
+
+        %{
+          to: [following_user],
+          actor: followed,
+          object: follow_id,
+          local: true
+        }
+        |> ActivityPub.accept()
+      end
+    else
+      {:following, {:error, _}, follower, followed} ->
+        Utils.update_follow_state_for_all(object, "reject")
+        FollowingRelationship.update(follower, followed, :follow_reject)
+
+        if followed.local do
+          %{
+            to: [follower.ap_id],
+            actor: followed,
+            object: follow_id,
+            local: true
+          }
+          |> ActivityPub.reject()
+        end
+
+      _ ->
+        nil
+    end
+
+    {:ok, notifications} = Notification.create_notifications(object, do_send: false)
+
+    meta =
+      meta
+      |> add_notifications(notifications)
+
+    {:ok, object, meta}
+  end
+
   # Tasks this handles:
   # - Unfollow and block
   def handle(
index 117e930b37a0a73a85bc4c3429760c0f14c1a3a2..884646cebf98ce45e85a342523e16ac41e2c28f5 100644 (file)
@@ -529,66 +529,6 @@ defmodule Pleroma.Web.ActivityPub.Transmogrifier do
     end
   end
 
-  def handle_incoming(
-        %{"type" => "Follow", "object" => followed, "actor" => follower, "id" => id} = data,
-        _options
-      ) do
-    with %User{local: true} = followed <-
-           User.get_cached_by_ap_id(Containment.get_actor(%{"actor" => followed})),
-         {:ok, %User{} = follower} <-
-           User.get_or_fetch_by_ap_id(Containment.get_actor(%{"actor" => follower})),
-         {:ok, activity} <-
-           ActivityPub.follow(follower, followed, id, false, skip_notify_and_stream: true) do
-      with deny_follow_blocked <- Pleroma.Config.get([:user, :deny_follow_blocked]),
-           {_, false} <- {:user_blocked, User.blocks?(followed, follower) && deny_follow_blocked},
-           {_, false} <- {:user_locked, User.locked?(followed)},
-           {_, {:ok, follower}} <- {:follow, User.follow(follower, followed)},
-           {_, {:ok, _}} <-
-             {:follow_state_update, Utils.update_follow_state_for_all(activity, "accept")},
-           {:ok, _relationship} <-
-             FollowingRelationship.update(follower, followed, :follow_accept) do
-        ActivityPub.accept(%{
-          to: [follower.ap_id],
-          actor: followed,
-          object: data,
-          local: true
-        })
-      else
-        {:user_blocked, true} ->
-          {:ok, _} = Utils.update_follow_state_for_all(activity, "reject")
-          {:ok, _relationship} = FollowingRelationship.update(follower, followed, :follow_reject)
-
-          ActivityPub.reject(%{
-            to: [follower.ap_id],
-            actor: followed,
-            object: data,
-            local: true
-          })
-
-        {:follow, {:error, _}} ->
-          {:ok, _} = Utils.update_follow_state_for_all(activity, "reject")
-          {:ok, _relationship} = FollowingRelationship.update(follower, followed, :follow_reject)
-
-          ActivityPub.reject(%{
-            to: [follower.ap_id],
-            actor: followed,
-            object: data,
-            local: true
-          })
-
-        {:user_locked, true} ->
-          {:ok, _relationship} = FollowingRelationship.update(follower, followed, :follow_pending)
-          :noop
-      end
-
-      ActivityPub.notify_and_stream(activity)
-      {:ok, activity}
-    else
-      _e ->
-        :error
-    end
-  end
-
   def handle_incoming(
         %{"type" => "Accept", "object" => follow_object, "actor" => _actor, "id" => id} = data,
         _options
@@ -696,7 +636,7 @@ defmodule Pleroma.Web.ActivityPub.Transmogrifier do
         %{"type" => type} = data,
         _options
       )
-      when type in ~w{Update Block} do
+      when type in ~w{Update Block Follow} do
     with {:ok, %User{}} <- ObjectValidator.fetch_actor(data),
          {:ok, activity, _} <- Pipeline.common_pipeline(data, local: false) do
       {:ok, activity}
index 06c39eed67e074c00e83d4000e2435c6ee7d7491..17e764ca14f835d2178640eed9730a1eefb8e5c1 100644 (file)
@@ -160,7 +160,7 @@ defmodule Pleroma.Web.ActivityPub.Transmogrifier.FollowHandlingTest do
         |> Poison.decode!()
         |> Map.put("object", user.ap_id)
 
-      with_mock Pleroma.User, [:passthrough], follow: fn _, _ -> {:error, :testing} end do
+      with_mock Pleroma.User, [:passthrough], follow: fn _, _, _ -> {:error, :testing} end do
         {:ok, %Activity{data: %{"id" => id}}} = Transmogrifier.handle_incoming(data)
 
         %Activity{} = activity = Activity.get_by_ap_id(id)