X-Git-Url: http://git.squeep.com/?a=blobdiff_plain;f=lib%2Fpleroma%2Fweb%2Factivity_pub%2Ftransmogrifier.ex;h=6603e4929d50c384f2ee122426515f7433f3e3d8;hb=e9993acdbbd1649bbcbf3fb36581b91145fe6055;hp=3c27b0d46b1fd36583a110be3bd44a524bf1d68e;hpb=4c1dd55c48f80f3ebdb26d1a0c1a75b7922f578c;p=akkoma diff --git a/lib/pleroma/web/activity_pub/transmogrifier.ex b/lib/pleroma/web/activity_pub/transmogrifier.ex index 3c27b0d46..6603e4929 100644 --- a/lib/pleroma/web/activity_pub/transmogrifier.ex +++ b/lib/pleroma/web/activity_pub/transmogrifier.ex @@ -13,6 +13,9 @@ defmodule Pleroma.Web.ActivityPub.Transmogrifier do alias Pleroma.Repo alias Pleroma.User alias Pleroma.Web.ActivityPub.ActivityPub + alias Pleroma.Web.ActivityPub.ObjectValidator + alias Pleroma.Web.ActivityPub.ObjectValidators.LikeValidator + alias Pleroma.Web.ActivityPub.Pipeline alias Pleroma.Web.ActivityPub.Utils alias Pleroma.Web.ActivityPub.Visibility alias Pleroma.Web.Federator @@ -507,6 +510,7 @@ defmodule Pleroma.Web.ActivityPub.Transmogrifier do }) {:user_locked, true} -> + {:ok, _relationship} = FollowingRelationship.update(follower, followed, "pending") :noop end @@ -565,14 +569,67 @@ defmodule Pleroma.Web.ActivityPub.Transmogrifier do end end + @misskey_reactions %{ + "like" => "👍", + "love" => "❤️", + "laugh" => "😆", + "hmm" => "🤔", + "surprise" => "😮", + "congrats" => "🎉", + "angry" => "💢", + "confused" => "😥", + "rip" => "😇", + "pudding" => "🍮", + "star" => "⭐" + } + + @doc "Rewrite misskey likes into EmojiReactions" def handle_incoming( - %{"type" => "Like", "object" => object_id, "actor" => _actor, "id" => id} = data, + %{ + "type" => "Like", + "_misskey_reaction" => reaction + } = data, + options + ) do + data + |> Map.put("type", "EmojiReaction") + |> Map.put("content", @misskey_reactions[reaction] || reaction) + |> handle_incoming(options) + end + + def handle_incoming(%{"type" => "Like"} = data, _options) do + with {_, {:ok, cast_data_sym}} <- + {:casting_data, + data |> LikeValidator.cast_data() |> Ecto.Changeset.apply_action(:insert)}, + {_, cast_data} <- + {:stringify_keys, ObjectValidator.stringify_keys(cast_data_sym |> Map.from_struct())}, + :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, Pipeline.common_pipeline(cast_data, local: false)} do + {:ok, activity} + else + e -> {:error, e} + end + end + + def handle_incoming( + %{ + "type" => "EmojiReaction", + "object" => object_id, + "actor" => _actor, + "id" => id, + "content" => emoji + } = 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, _object} <- + ActivityPub.react_with_emoji(actor, object, emoji, activity_id: id, local: false) do {:ok, activity} else _e -> :error @@ -619,7 +676,7 @@ defmodule Pleroma.Web.ActivityPub.Transmogrifier do update_data = new_user_data - |> Map.take([:avatar, :banner, :bio, :name]) + |> Map.take([:avatar, :banner, :bio, :name, :also_known_as]) |> Map.put(:fields, fields) |> Map.put(:locked, locked) |> Map.put(:invisible, invisible) @@ -714,6 +771,28 @@ defmodule Pleroma.Web.ActivityPub.Transmogrifier do end end + def handle_incoming( + %{ + "type" => "Undo", + "object" => %{"type" => "EmojiReaction", "id" => reaction_activity_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, activity, _} <- + ActivityPub.unreact_with_emoji(actor, reaction_activity_id, + activity_id: id, + local: false + ) do + {:ok, activity} + else + _e -> :error + end + end + def handle_incoming( %{ "type" => "Undo", @@ -785,6 +864,24 @@ defmodule Pleroma.Web.ActivityPub.Transmogrifier do end end + def handle_incoming( + %{ + "type" => "Move", + "actor" => origin_actor, + "object" => origin_actor, + "target" => target_actor + }, + _options + ) do + with %User{} = origin_user <- User.get_cached_by_ap_id(origin_actor), + {:ok, %User{} = target_user} <- User.get_or_fetch_by_ap_id(target_actor), + true <- origin_actor in target_user.also_known_as do + ActivityPub.move(origin_user, target_user, false) + else + _e -> :error + end + end + def handle_incoming(_, _), do: :error @spec get_obj_helper(String.t(), Keyword.t()) :: {:ok, Object.t()} | nil @@ -1047,7 +1144,7 @@ defmodule Pleroma.Web.ActivityPub.Transmogrifier do Map.put(object, "attachment", attachments) end - defp strip_internal_fields(object) do + def strip_internal_fields(object) do object |> Map.drop(Pleroma.Constants.object_internal_fields()) end @@ -1111,4 +1208,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