From 2f1f1a4f30430544d77c82627011800b65d51ba3 Mon Sep 17 00:00:00 2001 From: William Pitcock Date: Thu, 25 Oct 2018 05:02:21 +0000 Subject: [PATCH 1/3] activitypub: splice users into recipient lists when they receive messages at their personal inbox closes #343 --- .../activity_pub/activity_pub_controller.ex | 11 ++++- lib/pleroma/web/activity_pub/utils.ex | 42 +++++++++++++++++++ 2 files changed, 52 insertions(+), 1 deletion(-) diff --git a/lib/pleroma/web/activity_pub/activity_pub_controller.ex b/lib/pleroma/web/activity_pub/activity_pub_controller.ex index 2750add8b..a7b1c0079 100644 --- a/lib/pleroma/web/activity_pub/activity_pub_controller.ex +++ b/lib/pleroma/web/activity_pub/activity_pub_controller.ex @@ -4,6 +4,7 @@ defmodule Pleroma.Web.ActivityPub.ActivityPubController do alias Pleroma.Web.ActivityPub.{ObjectView, UserView} alias Pleroma.Web.ActivityPub.ActivityPub alias Pleroma.Web.ActivityPub.Relay + alias Pleroma.Web.ActivityPub.Utils alias Pleroma.Web.Federator require Logger @@ -87,7 +88,15 @@ def outbox(conn, %{"nickname" => nickname}) do outbox(conn, %{"nickname" => nickname, "max_id" => nil}) end - # TODO: Ensure that this inbox is a recipient of the message + def inbox(%{assigns: %{valid_signature: true}} = conn, %{"nickname" => nickname} = params) do + with %User{} = user <- User.get_cached_by_nickname(nickname), + true <- Utils.recipient_in_message(user.ap_id, params), + params <- Utils.maybe_splice_recipient(user.ap_id, params) do + Federator.enqueue(:incoming_ap_doc, params) + json(conn, "ok") + end + end + def inbox(%{assigns: %{valid_signature: true}} = conn, params) do Federator.enqueue(:incoming_ap_doc, params) json(conn, "ok") diff --git a/lib/pleroma/web/activity_pub/utils.ex b/lib/pleroma/web/activity_pub/utils.ex index 43a1f432d..8b5feef1c 100644 --- a/lib/pleroma/web/activity_pub/utils.ex +++ b/lib/pleroma/web/activity_pub/utils.ex @@ -19,6 +19,48 @@ def normalize_params(params) do Map.put(params, "actor", get_ap_id(params["actor"])) end + defp recipient_in_collection(ap_id, coll) when is_binary(coll), do: ap_id == coll + defp recipient_in_collection(ap_id, coll) when is_list(coll), do: ap_id in coll + defp recipient_in_collection(_, _), do: false + + def recipient_in_message(ap_id, params) do + cond do + recipient_in_collection(ap_id, params["to"]) -> + true + + recipient_in_collection(ap_id, params["cc"]) -> + true + + recipient_in_collection(ap_id, params["bto"]) -> + true + + recipient_in_collection(ap_id, params["bcc"]) -> + true + + true -> + false + end + end + + defp extract_list(target) when is_binary(target), do: [target] + defp extract_list(lst) when is_list(lst), do: lst + defp extract_list(_), do: [] + + def maybe_splice_recipient(ap_id, params) do + need_splice = + !recipient_in_collection(ap_id, params["to"]) && + !recipient_in_collection(ap_id, params["cc"]) + + cc_list = extract_list(params["cc"]) + + if need_splice do + params + |> Map.put(params, "cc", [ap_id | cc_list]) + else + params + end + end + def make_json_ld_header do %{ "@context" => [ From ce70eb8c0097e7d07ebc43b601c0913170d6283e Mon Sep 17 00:00:00 2001 From: William Pitcock Date: Thu, 25 Oct 2018 05:24:01 +0000 Subject: [PATCH 2/3] activitypub utils: fix user splicing --- lib/pleroma/web/activity_pub/utils.ex | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/pleroma/web/activity_pub/utils.ex b/lib/pleroma/web/activity_pub/utils.ex index 8b5feef1c..266667f81 100644 --- a/lib/pleroma/web/activity_pub/utils.ex +++ b/lib/pleroma/web/activity_pub/utils.ex @@ -55,7 +55,7 @@ def maybe_splice_recipient(ap_id, params) do if need_splice do params - |> Map.put(params, "cc", [ap_id | cc_list]) + |> Map.put("cc", [ap_id | cc_list]) else params end From b1d1f9bc271d80f05b2f636e304775e6803c02f6 Mon Sep 17 00:00:00 2001 From: William Pitcock Date: Thu, 25 Oct 2018 05:24:17 +0000 Subject: [PATCH 3/3] tests: add test for user inbox --- test/fixtures/mastodon-post-activity.json | 1 - .../activity_pub_controller_test.exs | 23 ++++++++++++++++++- 2 files changed, 22 insertions(+), 2 deletions(-) diff --git a/test/fixtures/mastodon-post-activity.json b/test/fixtures/mastodon-post-activity.json index 693e0ce39..b91263431 100644 --- a/test/fixtures/mastodon-post-activity.json +++ b/test/fixtures/mastodon-post-activity.json @@ -21,7 +21,6 @@ "http://localtesting.pleroma.lol/users/lain" ], "id": "http://mastodon.example.org/users/admin/statuses/99512778738411822/activity", - "nickname": "lain", "object": { "atomUri": "http://mastodon.example.org/users/admin/statuses/99512778738411822", "attachment": [], diff --git a/test/web/activity_pub/activity_pub_controller_test.exs b/test/web/activity_pub/activity_pub_controller_test.exs index 3ed7be402..e63cd6583 100644 --- a/test/web/activity_pub/activity_pub_controller_test.exs +++ b/test/web/activity_pub/activity_pub_controller_test.exs @@ -46,7 +46,7 @@ test "it returns 404 for non-public messages", %{conn: conn} do end end - describe "/users/:nickname/inbox" do + describe "/inbox" do test "it inserts an incoming activity into the database", %{conn: conn} do data = File.read!("test/fixtures/mastodon-post-activity.json") |> Poison.decode!() @@ -62,6 +62,27 @@ test "it inserts an incoming activity into the database", %{conn: conn} do end end + describe "/users/:nickname/inbox" do + test "it inserts an incoming activity into the database", %{conn: conn} do + user = insert(:user) + + data = + File.read!("test/fixtures/mastodon-post-activity.json") + |> Poison.decode!() + |> Map.put("bcc", [user.ap_id]) + + conn = + conn + |> assign(:valid_signature, true) + |> put_req_header("content-type", "application/activity+json") + |> post("/users/#{user.nickname}/inbox", data) + + assert "ok" == json_response(conn, 200) + :timer.sleep(500) + assert Activity.get_by_ap_id(data["id"]) + end + end + describe "/users/:nickname/outbox" do test "it returns a note activity in a collection", %{conn: conn} do note_activity = insert(:note_activity)