diff --git a/lib/pleroma/web/activity_pub/activity_pub_controller.ex b/lib/pleroma/web/activity_pub/activity_pub_controller.ex index daf0d38e6..3d126e7d3 100644 --- a/lib/pleroma/web/activity_pub/activity_pub_controller.ex +++ b/lib/pleroma/web/activity_pub/activity_pub_controller.ex @@ -482,6 +482,24 @@ defmodule Pleroma.Web.ActivityPub.ActivityPubController do {:ok, activity} end + defp validate_visibility(%User{} = user, %{"type" => type, "object" => object} = activity) do + with {_, %Object{} = normalized_object} <- {:normalize, Object.normalize(object, fetch: false)}, + {_, true} <- {:visibility, Visibility.visible_for_user?(normalized_object, user)} do + {:ok, activity} + else + {:normalize, _} -> + if user.local and type == "Create" do + # Creating new object via C2S + {:ok, activity} + else + {:error, "No such object found"} + end + + {:visibility, _} -> + {:forbidden, "You can't interact with this object"} + end + end + def update_outbox( %{assigns: %{user: %User{nickname: nickname, ap_id: actor} = user}} = conn, %{"nickname" => nickname} = params @@ -493,7 +511,8 @@ defmodule Pleroma.Web.ActivityPub.ActivityPubController do |> Map.put("actor", actor) with {:ok, params} <- fix_user_message(user, params), - {:ok, activity, _} <- Pipeline.common_pipeline(params, local: true), + {:ok, activity} <- validate_visibility(user, params), + {:ok, activity, _} <- Pipeline.common_pipeline(activity, local: true), %Activity{data: activity_data} <- Activity.normalize(activity) do conn |> put_status(:created) diff --git a/test/pleroma/web/activity_pub/activity_pub_controller_test.exs b/test/pleroma/web/activity_pub/activity_pub_controller_test.exs index 2b8418dcd..adb65431c 100644 --- a/test/pleroma/web/activity_pub/activity_pub_controller_test.exs +++ b/test/pleroma/web/activity_pub/activity_pub_controller_test.exs @@ -1706,6 +1706,82 @@ defmodule Pleroma.Web.ActivityPub.ActivityPubControllerTest do assert note_object == Object.normalize(note_activity, fetch: false) end + test "it rejects like activity to object invisible to actor", %{conn: conn} do + user = insert(:user) + stranger = insert(:user, local: true) + {:ok, post} = CommonAPI.post(user, %{status: "cofe", visibility: "private"}) + + assert Pleroma.Web.ActivityPub.Visibility.private?(post) + + post_object = Object.normalize(post, fetch: false) + + data = %{ + type: "Like", + object: %{ + id: post_object.data["id"] + } + } + + conn = + conn + |> assign(:user, stranger) + |> put_req_header("content-type", "application/activity+json") + |> post("/users/#{stranger.nickname}/outbox", data) + + assert json_response(conn, 403) + end + + test "it rejects announce activity to object invisible to actor", %{conn: conn} do + user = insert(:user) + stranger = insert(:user, local: true) + {:ok, post} = CommonAPI.post(user, %{status: "cofe", visibility: "private"}) + + assert Pleroma.Web.ActivityPub.Visibility.private?(post) + + post_object = Object.normalize(post, fetch: false) + + data = %{ + type: "Announce", + object: %{ + id: post_object.data["id"] + } + } + + conn = + conn + |> assign(:user, stranger) + |> put_req_header("content-type", "application/activity+json") + |> post("/users/#{stranger.nickname}/outbox", data) + + assert json_response(conn, 403) + end + + test "it rejects emojireact activity to object invisible to actor", %{conn: conn} do + user = insert(:user) + stranger = insert(:user, local: true) + {:ok, post} = CommonAPI.post(user, %{status: "cofe", visibility: "private"}) + + assert Pleroma.Web.ActivityPub.Visibility.private?(post) + + post_object = Object.normalize(post, fetch: false) + + data = %{ + type: "EmojiReact", + object: %{ + id: post_object.data["id"] + }, + content: "😀" + } + + conn = + conn + |> assign(:user, stranger) + |> put_req_header("content-type", "application/activity+json") + |> post("/users/#{stranger.nickname}/outbox", data) + + assert json_response(conn, 403) + end + test "it increases like count when receiving a like action", %{conn: conn} do note_activity = insert(:note_activity) note_object = Object.normalize(note_activity, fetch: false)