From a88734a0a22810bcc47c17fc9120ef7881d670d8 Mon Sep 17 00:00:00 2001 From: lain Date: Wed, 29 Apr 2020 14:25:33 +0200 Subject: [PATCH] Transmogrifier: Fetch missing actors for chatmessages. --- .../web/activity_pub/object_validator.ex | 9 ++++- .../create_chat_message_validator.ex | 2 + .../web/activity_pub/transmogrifier.ex | 8 ++-- .../transmogrifier/chat_message_test.exs | 40 ++++++++++++++++--- 4 files changed, 49 insertions(+), 10 deletions(-) diff --git a/lib/pleroma/web/activity_pub/object_validator.ex b/lib/pleroma/web/activity_pub/object_validator.ex index bada3509d..50904ed59 100644 --- a/lib/pleroma/web/activity_pub/object_validator.ex +++ b/lib/pleroma/web/activity_pub/object_validator.ex @@ -11,6 +11,7 @@ defmodule Pleroma.Web.ActivityPub.ObjectValidator do alias Pleroma.Object alias Pleroma.User + alias Pleroma.Web.ActivityPub.ObjectValidators.Types alias Pleroma.Web.ActivityPub.ObjectValidators.ChatMessageValidator alias Pleroma.Web.ActivityPub.ObjectValidators.CreateChatMessageValidator alias Pleroma.Web.ActivityPub.ObjectValidators.LikeValidator @@ -67,8 +68,14 @@ def stringify_keys(object) do |> Map.new(fn {key, val} -> {to_string(key), val} end) end + def fetch_actor(object) do + with {:ok, actor} <- Types.ObjectID.cast(object["actor"]) do + User.get_or_fetch_by_ap_id(actor) + end + end + def fetch_actor_and_object(object) do - User.get_or_fetch_by_ap_id(object["actor"]) + fetch_actor(object) Object.normalize(object["object"]) :ok end diff --git a/lib/pleroma/web/activity_pub/object_validators/create_chat_message_validator.ex b/lib/pleroma/web/activity_pub/object_validators/create_chat_message_validator.ex index dfc91bf71..88e903182 100644 --- a/lib/pleroma/web/activity_pub/object_validators/create_chat_message_validator.ex +++ b/lib/pleroma/web/activity_pub/object_validators/create_chat_message_validator.ex @@ -12,6 +12,7 @@ defmodule Pleroma.Web.ActivityPub.ObjectValidators.CreateChatMessageValidator do alias Pleroma.Web.ActivityPub.ObjectValidators.Types import Ecto.Changeset + import Pleroma.Web.ActivityPub.ObjectValidators.CommonValidations @primary_key false @@ -42,6 +43,7 @@ def validate_data(cng, meta \\ []) do cng |> validate_required([:id, :actor, :to, :type, :object]) |> validate_inclusion(:type, ["Create"]) + |> validate_actor_presence() |> validate_recipients_match(meta) |> validate_object_nonexistence() end diff --git a/lib/pleroma/web/activity_pub/transmogrifier.ex b/lib/pleroma/web/activity_pub/transmogrifier.ex index 3c2fe73a3..6dbd3f588 100644 --- a/lib/pleroma/web/activity_pub/transmogrifier.ex +++ b/lib/pleroma/web/activity_pub/transmogrifier.ex @@ -647,10 +647,10 @@ def handle_incoming( %{"type" => "Create", "object" => %{"type" => "ChatMessage"}} = data, _options ) do - case Pipeline.common_pipeline(data, local: false) do - {:ok, activity, _} -> - {:ok, activity} - + with {:ok, %User{}} <- ObjectValidator.fetch_actor(data), + {:ok, activity, _} <- Pipeline.common_pipeline(data, local: false) do + {:ok, activity} + else e -> e end diff --git a/test/web/activity_pub/transmogrifier/chat_message_test.exs b/test/web/activity_pub/transmogrifier/chat_message_test.exs index c5600e84e..85644d787 100644 --- a/test/web/activity_pub/transmogrifier/chat_message_test.exs +++ b/test/web/activity_pub/transmogrifier/chat_message_test.exs @@ -26,8 +26,15 @@ test "it rejects messages that don't contain content" do data |> Map.put("object", object) - _author = insert(:user, ap_id: data["actor"], local: false) - _recipient = insert(:user, ap_id: List.first(data["to"]), local: true) + _author = + insert(:user, ap_id: data["actor"], local: false, last_refreshed_at: DateTime.utc_now()) + + _recipient = + insert(:user, + ap_id: List.first(data["to"]), + local: true, + last_refreshed_at: DateTime.utc_now() + ) {:error, _} = Transmogrifier.handle_incoming(data) end @@ -37,8 +44,15 @@ test "it rejects messages that don't concern local users" do File.read!("test/fixtures/create-chat-message.json") |> Poison.decode!() - _author = insert(:user, ap_id: data["actor"], local: false) - _recipient = insert(:user, ap_id: List.first(data["to"]), local: false) + _author = + insert(:user, ap_id: data["actor"], local: false, last_refreshed_at: DateTime.utc_now()) + + _recipient = + insert(:user, + ap_id: List.first(data["to"]), + local: false, + last_refreshed_at: DateTime.utc_now() + ) {:error, _} = Transmogrifier.handle_incoming(data) end @@ -59,12 +73,28 @@ test "it rejects messages where the `to` field of activity and object don't matc refute Object.get_by_ap_id(data["object"]["id"]) end + test "it fetches the actor if they aren't in our system" do + Tesla.Mock.mock(fn env -> apply(HttpRequestMock, :request, [env]) end) + + data = + File.read!("test/fixtures/create-chat-message.json") + |> Poison.decode!() + |> Map.put("actor", "http://mastodon.example.org/users/admin") + |> put_in(["object", "actor"], "http://mastodon.example.org/users/admin") + + _recipient = insert(:user, ap_id: List.first(data["to"]), local: true) + + {:ok, %Activity{} = _activity} = Transmogrifier.handle_incoming(data) + end + test "it inserts it and creates a chat" do data = File.read!("test/fixtures/create-chat-message.json") |> Poison.decode!() - author = insert(:user, ap_id: data["actor"], local: false) + author = + insert(:user, ap_id: data["actor"], local: false, last_refreshed_at: DateTime.utc_now()) + recipient = insert(:user, ap_id: List.first(data["to"]), local: true) {:ok, %Activity{} = activity} = Transmogrifier.handle_incoming(data)