Transmogrifier: Make proper use of the LikeValidator.
authorlain <lain@soykaf.club>
Thu, 17 Oct 2019 17:35:31 +0000 (19:35 +0200)
committerlain <lain@soykaf.club>
Thu, 17 Oct 2019 17:35:31 +0000 (19:35 +0200)
lib/pleroma/web/activity_pub/object_validator.ex
lib/pleroma/web/activity_pub/object_validators/like_validator.ex
lib/pleroma/web/activity_pub/transmogrifier.ex
test/web/activity_pub/object_validator_test.exs
test/web/activity_pub/transmogrifier_test.exs

index adcb53c65c9ef1ce0f5b7bab902b5887fe4f5bda..33e67dbb9a30e3bd143c3c599bd5230f2d514edc 100644 (file)
@@ -10,6 +10,8 @@ defmodule Pleroma.Web.ActivityPub.ObjectValidator do
   """
 
   alias Pleroma.Web.ActivityPub.ObjectValidators.LikeValidator
+  alias Pleroma.User
+  alias Pleroma.Object
 
   @spec validate(map(), keyword()) :: {:ok, map(), keyword()} | {:error, any()}
   def validate(object, meta)
@@ -24,9 +26,15 @@ defmodule Pleroma.Web.ActivityPub.ObjectValidator do
     end
   end
 
-  defp stringify_keys(object) do
+  def stringify_keys(object) do
     object
     |> Enum.map(fn {key, val} -> {to_string(key), val} end)
     |> Enum.into(%{})
   end
+
+  def fetch_actor_and_object(object) do
+    User.get_or_fetch_by_ap_id(object["actor"])
+    Object.normalize(object["object"])
+    :ok
+  end
 end
index d5a2f7202aefeefaaa6e70f926077c4e72eb675d..e6a5aaca8ad0386f4b1250636932883a2556143f 100644 (file)
@@ -33,7 +33,7 @@ defmodule Pleroma.Web.ActivityPub.ObjectValidators.LikeValidator do
   def validate_data(data_cng) do
     data_cng
     |> validate_inclusion(:type, ["Like"])
-    |> validate_required([:id, :type, :object, :actor, :context])
+    |> validate_required([:id, :type, :object, :actor, :context, :to, :cc])
     |> validate_change(:actor, &actor_valid?/2)
     |> validate_change(:object, &object_valid?/2)
     |> validate_existing_like()
index 3e982adcb514d3ac83e93c7d53ce2ba84346b045..591d7aa9497a3a20b2fcd1df5c3639e01b02bd1c 100644 (file)
@@ -16,6 +16,8 @@ defmodule Pleroma.Web.ActivityPub.Transmogrifier do
   alias Pleroma.Web.ActivityPub.Visibility
   alias Pleroma.Web.Federator
   alias Pleroma.Workers.TransmogrifierWorker
+  alias Pleroma.Web.ActivityPub.ObjectValidator
+  alias Pleroma.Web.ActivityPub.ObjectValidators.LikeValidator
 
   import Ecto.Query
 
@@ -562,39 +564,21 @@ defmodule Pleroma.Web.ActivityPub.Transmogrifier do
     end
   end
 
-  def handle_incoming(
-        %{"type" => "Like", "object" => _object_id, "actor" => _actor, "id" => _id} = data,
-        _options
-      ) do
-    with data <- Map.take(data, ["type", "object", "actor", "context", "id"]),
-         actor <- Containment.get_actor(data),
-         object <- Containment.get_object(data),
-         data <- data |> Map.put("actor", actor) |> Map.put("object", object),
-         _user <- User.get_or_fetch_by_ap_id(actor),
-         object <- Object.normalize(object),
-         data <- Map.put_new(data, "context", object.data["context"]),
+  def handle_incoming(%{"type" => "Like"} = data, _options) do
+    with {_, %{changes: cast_data}} <- {:casting_data, LikeValidator.cast_data(data)},
+         cast_data <- ObjectValidator.stringify_keys(cast_data),
+         :ok <- ObjectValidator.fetch_actor_and_object(cast_data),
+         {_, {:ok, cast_data}} <- {:maybe_add_context, maybe_add_context_from_object(cast_data)},
+         {_, {:ok, cast_data}} <-
+           {:maybe_add_recipients, maybe_add_recipients_from_object(cast_data)},
          {_, {:ok, activity, _meta}} <-
-           {:common_pipeline, ActivityPub.common_pipeline(data, local: false)} do
+           {:common_pipeline, ActivityPub.common_pipeline(cast_data, local: false)} do
       {:ok, activity}
     else
       e -> {:error, e}
     end
   end
 
-  # def handle_incoming(
-  #       %{"type" => "Like", "object" => object_id, "actor" => _actor, "id" => id} = data,
-  #       _options
-  #     ) do
-  #   with actor <- Containment.get_actor(data),
-  #        {:ok, %User{} = actor} <- User.get_or_fetch_by_ap_id(actor),
-  #        {:ok, object} <- get_obj_helper(object_id),
-  #        {:ok, activity, _object} <- ActivityPub.like(actor, object, id, false) do
-  #     {:ok, activity}
-  #   else
-  #     _e -> :error
-  #   end
-  # end
-
   def handle_incoming(
         %{"type" => "Announce", "object" => object_id, "actor" => _actor, "id" => id} = data,
         _options
@@ -1156,4 +1140,47 @@ defmodule Pleroma.Web.ActivityPub.Transmogrifier do
   def maybe_fix_user_url(data), do: data
 
   def maybe_fix_user_object(data), do: maybe_fix_user_url(data)
+
+  defp maybe_add_context_from_object(%{"context" => context} = data) when is_binary(context),
+    do: {:ok, data}
+
+  defp maybe_add_context_from_object(%{"object" => object} = data) when is_binary(object) do
+    if object = Object.normalize(object) do
+      data =
+        data
+        |> Map.put("context", object.data["context"])
+
+      {:ok, data}
+    else
+      {:error, "No context on referenced object"}
+    end
+  end
+
+  defp maybe_add_context_from_object(_) do
+    {:error, "No referenced object"}
+  end
+
+  defp maybe_add_recipients_from_object(%{"object" => object} = data) do
+    to = data["to"] || []
+    cc = data["cc"] || []
+
+    if to == [] && cc == [] do
+      if object = Object.normalize(object) do
+        data =
+          data
+          |> Map.put("to", [object.data["actor"]])
+          |> Map.put("cc", cc)
+
+        {:ok, data}
+      else
+        {:error, "No actor on referenced object"}
+      end
+    else
+      {:ok, data}
+    end
+  end
+
+  defp maybe_add_recipients_from_object(_) do
+    {:error, "No referenced object"}
+  end
 end
index 374a7c0dfe683bf77b5054fe5ea9cb357238d7eb..2292db6d71482243f8ef9c2f82571987c5151f26 100644 (file)
@@ -13,6 +13,8 @@ defmodule Pleroma.Web.ActivityPub.ObjectValidatorTest do
       {:ok, post_activity} = CommonAPI.post(user, %{"status" => "uguu"})
 
       valid_like = %{
+        "to" => [user.ap_id],
+        "cc" => [],
         "type" => "Like",
         "id" => Utils.generate_activity_id(),
         "object" => post_activity.data["object"],
index 28edc55083d7099e1f31b4ff893b86f7dfedff6e..e5d4dcd64bbdfb4ae9a471ad9c7010c868753fb9 100644 (file)
@@ -333,7 +333,9 @@ defmodule Pleroma.Web.ActivityPub.TransmogrifierTest do
         |> Poison.decode!()
         |> Map.put("object", activity.data["object"])
 
-      {:ok, %Activity{data: data, local: false}} = Transmogrifier.handle_incoming(data)
+      {:ok, %Activity{data: data, local: false} = activity} = Transmogrifier.handle_incoming(data)
+
+      refute Enum.empty?(activity.recipients)
 
       assert data["actor"] == "http://mastodon.example.org/users/admin"
       assert data["type"] == "Like"