forked from AkkomaGang/akkoma
Transmogrifier: Make proper use of the LikeValidator.
This commit is contained in:
parent
66452f518f
commit
203d61b950
5 changed files with 68 additions and 29 deletions
|
@ -10,6 +10,8 @@ defmodule Pleroma.Web.ActivityPub.ObjectValidator do
|
||||||
"""
|
"""
|
||||||
|
|
||||||
alias Pleroma.Web.ActivityPub.ObjectValidators.LikeValidator
|
alias Pleroma.Web.ActivityPub.ObjectValidators.LikeValidator
|
||||||
|
alias Pleroma.User
|
||||||
|
alias Pleroma.Object
|
||||||
|
|
||||||
@spec validate(map(), keyword()) :: {:ok, map(), keyword()} | {:error, any()}
|
@spec validate(map(), keyword()) :: {:ok, map(), keyword()} | {:error, any()}
|
||||||
def validate(object, meta)
|
def validate(object, meta)
|
||||||
|
@ -24,9 +26,15 @@ def validate(%{"type" => "Like"} = object, meta) do
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
defp stringify_keys(object) do
|
def stringify_keys(object) do
|
||||||
object
|
object
|
||||||
|> Enum.map(fn {key, val} -> {to_string(key), val} end)
|
|> Enum.map(fn {key, val} -> {to_string(key), val} end)
|
||||||
|> Enum.into(%{})
|
|> Enum.into(%{})
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def fetch_actor_and_object(object) do
|
||||||
|
User.get_or_fetch_by_ap_id(object["actor"])
|
||||||
|
Object.normalize(object["object"])
|
||||||
|
:ok
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -33,7 +33,7 @@ def cast_data(data) do
|
||||||
def validate_data(data_cng) do
|
def validate_data(data_cng) do
|
||||||
data_cng
|
data_cng
|
||||||
|> validate_inclusion(:type, ["Like"])
|
|> 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(:actor, &actor_valid?/2)
|
||||||
|> validate_change(:object, &object_valid?/2)
|
|> validate_change(:object, &object_valid?/2)
|
||||||
|> validate_existing_like()
|
|> validate_existing_like()
|
||||||
|
|
|
@ -16,6 +16,8 @@ defmodule Pleroma.Web.ActivityPub.Transmogrifier do
|
||||||
alias Pleroma.Web.ActivityPub.Visibility
|
alias Pleroma.Web.ActivityPub.Visibility
|
||||||
alias Pleroma.Web.Federator
|
alias Pleroma.Web.Federator
|
||||||
alias Pleroma.Workers.TransmogrifierWorker
|
alias Pleroma.Workers.TransmogrifierWorker
|
||||||
|
alias Pleroma.Web.ActivityPub.ObjectValidator
|
||||||
|
alias Pleroma.Web.ActivityPub.ObjectValidators.LikeValidator
|
||||||
|
|
||||||
import Ecto.Query
|
import Ecto.Query
|
||||||
|
|
||||||
|
@ -562,39 +564,21 @@ def handle_incoming(
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
def handle_incoming(
|
def handle_incoming(%{"type" => "Like"} = data, _options) do
|
||||||
%{"type" => "Like", "object" => _object_id, "actor" => _actor, "id" => _id} = data,
|
with {_, %{changes: cast_data}} <- {:casting_data, LikeValidator.cast_data(data)},
|
||||||
_options
|
cast_data <- ObjectValidator.stringify_keys(cast_data),
|
||||||
) do
|
:ok <- ObjectValidator.fetch_actor_and_object(cast_data),
|
||||||
with data <- Map.take(data, ["type", "object", "actor", "context", "id"]),
|
{_, {:ok, cast_data}} <- {:maybe_add_context, maybe_add_context_from_object(cast_data)},
|
||||||
actor <- Containment.get_actor(data),
|
{_, {:ok, cast_data}} <-
|
||||||
object <- Containment.get_object(data),
|
{:maybe_add_recipients, maybe_add_recipients_from_object(cast_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"]),
|
|
||||||
{_, {:ok, activity, _meta}} <-
|
{_, {:ok, activity, _meta}} <-
|
||||||
{:common_pipeline, ActivityPub.common_pipeline(data, local: false)} do
|
{:common_pipeline, ActivityPub.common_pipeline(cast_data, local: false)} do
|
||||||
{:ok, activity}
|
{:ok, activity}
|
||||||
else
|
else
|
||||||
e -> {:error, e}
|
e -> {:error, e}
|
||||||
end
|
end
|
||||||
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(
|
def handle_incoming(
|
||||||
%{"type" => "Announce", "object" => object_id, "actor" => _actor, "id" => id} = data,
|
%{"type" => "Announce", "object" => object_id, "actor" => _actor, "id" => id} = data,
|
||||||
_options
|
_options
|
||||||
|
@ -1156,4 +1140,47 @@ def maybe_fix_user_url(%{"url" => url} = data) when is_map(url) do
|
||||||
def maybe_fix_user_url(data), do: data
|
def maybe_fix_user_url(data), do: data
|
||||||
|
|
||||||
def maybe_fix_user_object(data), do: maybe_fix_user_url(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
|
end
|
||||||
|
|
|
@ -13,6 +13,8 @@ defmodule Pleroma.Web.ActivityPub.ObjectValidatorTest do
|
||||||
{:ok, post_activity} = CommonAPI.post(user, %{"status" => "uguu"})
|
{:ok, post_activity} = CommonAPI.post(user, %{"status" => "uguu"})
|
||||||
|
|
||||||
valid_like = %{
|
valid_like = %{
|
||||||
|
"to" => [user.ap_id],
|
||||||
|
"cc" => [],
|
||||||
"type" => "Like",
|
"type" => "Like",
|
||||||
"id" => Utils.generate_activity_id(),
|
"id" => Utils.generate_activity_id(),
|
||||||
"object" => post_activity.data["object"],
|
"object" => post_activity.data["object"],
|
||||||
|
|
|
@ -333,7 +333,9 @@ test "it works for incoming likes" do
|
||||||
|> Poison.decode!()
|
|> Poison.decode!()
|
||||||
|> Map.put("object", activity.data["object"])
|
|> 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["actor"] == "http://mastodon.example.org/users/admin"
|
||||||
assert data["type"] == "Like"
|
assert data["type"] == "Like"
|
||||||
|
|
Loading…
Reference in a new issue