From 551c3d9391c0eeb282d750979b8eef5025c41482 Mon Sep 17 00:00:00 2001 From: sxsdv1 Date: Tue, 1 Jan 2019 22:16:46 +0100 Subject: [PATCH 1/2] Split create activity specifics from update_outbox --- .../activity_pub/activity_pub_controller.ex | 42 ++++++++++++------- .../activity_pub_controller_test.exs | 17 ++++++++ 2 files changed, 44 insertions(+), 15 deletions(-) diff --git a/lib/pleroma/web/activity_pub/activity_pub_controller.ex b/lib/pleroma/web/activity_pub/activity_pub_controller.ex index fc7972eaf..d23c54933 100644 --- a/lib/pleroma/web/activity_pub/activity_pub_controller.ex +++ b/lib/pleroma/web/activity_pub/activity_pub_controller.ex @@ -165,9 +165,29 @@ def read_inbox(%{assigns: %{user: user}} = conn, %{"nickname" => nickname} = par end end + def handle_user_activity(user, %{"type" => "Create"} = params) do + object = + params["object"] + |> Map.merge(Map.take(params, ["to", "cc"])) + |> Map.put("attributedTo", user.ap_id()) + |> Transmogrifier.fix_object() + + ActivityPub.create(%{ + to: params["to"], + actor: user, + context: object["context"], + object: object, + additional: Map.take(params, ["cc"]) + }) + end + + def handle_user_activity(_, _) do + {:error, "Unhandled activity type"} + end + def update_outbox( %{assigns: %{user: user}} = conn, - %{"nickname" => nickname, "type" => "Create"} = params + %{"nickname" => nickname} = params ) do if nickname == user.nickname do actor = user.ap_id() @@ -178,24 +198,16 @@ def update_outbox( |> Map.put("actor", actor) |> Transmogrifier.fix_addressing() - object = - params["object"] - |> Map.merge(Map.take(params, ["to", "cc"])) - |> Map.put("attributedTo", actor) - |> Transmogrifier.fix_object() - - with {:ok, %Activity{} = activity} <- - ActivityPub.create(%{ - to: params["to"], - actor: user, - context: object["context"], - object: object, - additional: Map.take(params, ["cc"]) - }) do + with {:ok, %Activity{} = activity} <- handle_user_activity(user, params) do conn |> put_status(:created) |> put_resp_header("location", activity.data["id"]) |> json(activity.data) + else + {:error, message} -> + conn + |> put_status(:bad_request) + |> json(message) end else conn diff --git a/test/web/activity_pub/activity_pub_controller_test.exs b/test/web/activity_pub/activity_pub_controller_test.exs index cb95e0e09..77dc96617 100644 --- a/test/web/activity_pub/activity_pub_controller_test.exs +++ b/test/web/activity_pub/activity_pub_controller_test.exs @@ -192,6 +192,23 @@ test "it inserts an incoming activity into the database", %{conn: conn} do result = json_response(conn, 201) assert Activity.get_by_ap_id(result["id"]) end + + test "it rejects an incoming activity with bogus type", %{conn: conn} do + data = File.read!("test/fixtures/activitypub-client-post-activity.json") |> Poison.decode!() + user = insert(:user) + + data = + data + |> Map.put("type", "BadType") + + conn = + conn + |> assign(:user, user) + |> put_req_header("content-type", "application/activity+json") + |> post("/users/#{user.nickname}/outbox", data) + + assert json_response(conn, 400) + end end describe "/users/:nickname/followers" do From 4e1cc2bab6ec76af1b6de986561a82887d18f366 Mon Sep 17 00:00:00 2001 From: sxsdv1 Date: Tue, 1 Jan 2019 23:19:40 +0100 Subject: [PATCH 2/2] Implement delete activity --- .../activity_pub/activity_pub_controller.ex | 10 ++++ .../activity_pub_controller_test.exs | 49 ++++++++++++++++++- 2 files changed, 57 insertions(+), 2 deletions(-) diff --git a/lib/pleroma/web/activity_pub/activity_pub_controller.ex b/lib/pleroma/web/activity_pub/activity_pub_controller.ex index d23c54933..a3f736fee 100644 --- a/lib/pleroma/web/activity_pub/activity_pub_controller.ex +++ b/lib/pleroma/web/activity_pub/activity_pub_controller.ex @@ -181,6 +181,16 @@ def handle_user_activity(user, %{"type" => "Create"} = params) do }) end + def handle_user_activity(user, %{"type" => "Delete"} = params) do + with %Object{} = object <- Object.normalize(params["object"]), + true <- user.info.is_moderator || user.ap_id == object.data["actor"], + {:ok, delete} <- ActivityPub.delete(object) do + {:ok, delete} + else + _ -> {:error, "Can't delete object"} + end + end + def handle_user_activity(_, _) do {:error, "Unhandled activity type"} end diff --git a/test/web/activity_pub/activity_pub_controller_test.exs b/test/web/activity_pub/activity_pub_controller_test.exs index 77dc96617..620e03674 100644 --- a/test/web/activity_pub/activity_pub_controller_test.exs +++ b/test/web/activity_pub/activity_pub_controller_test.exs @@ -6,7 +6,7 @@ defmodule Pleroma.Web.ActivityPub.ActivityPubControllerTest do use Pleroma.Web.ConnCase import Pleroma.Factory alias Pleroma.Web.ActivityPub.{UserView, ObjectView} - alias Pleroma.{Repo, User} + alias Pleroma.{Object, Repo, User} alias Pleroma.Activity setup_all do @@ -179,7 +179,7 @@ test "it rejects posts from other users", %{conn: conn} do assert json_response(conn, 403) end - test "it inserts an incoming activity into the database", %{conn: conn} do + test "it inserts an incoming create activity into the database", %{conn: conn} do data = File.read!("test/fixtures/activitypub-client-post-activity.json") |> Poison.decode!() user = insert(:user) @@ -209,6 +209,51 @@ test "it rejects an incoming activity with bogus type", %{conn: conn} do assert json_response(conn, 400) end + + test "it erects a tombstone when receiving a delete activity", %{conn: conn} do + note_activity = insert(:note_activity) + user = User.get_cached_by_ap_id(note_activity.data["actor"]) + + data = %{ + type: "Delete", + object: %{ + id: note_activity.data["object"]["id"] + } + } + + conn = + conn + |> assign(:user, user) + |> put_req_header("content-type", "application/activity+json") + |> post("/users/#{user.nickname}/outbox", data) + + result = json_response(conn, 201) + assert Activity.get_by_ap_id(result["id"]) + + object = Object.get_by_ap_id(note_activity.data["object"]["id"]) + assert object + assert object.data["type"] == "Tombstone" + end + + test "it rejects delete activity of object from other actor", %{conn: conn} do + note_activity = insert(:note_activity) + user = insert(:user) + + data = %{ + type: "Delete", + object: %{ + id: note_activity.data["object"]["id"] + } + } + + conn = + conn + |> assign(:user, user) + |> put_req_header("content-type", "application/activity+json") + |> post("/users/#{user.nickname}/outbox", data) + + assert json_response(conn, 400) + end end describe "/users/:nickname/followers" do