From 33c614bce002ff27cedbe3969f587c800744b997 Mon Sep 17 00:00:00 2001
From: rinpatch <rinpatch@sdf.org>
Date: Mon, 4 Mar 2019 18:09:58 +0300
Subject: [PATCH] Stop adresssing like activities to actor's follower
 collection on non-public posts

---
 lib/pleroma/web/activity_pub/utils.ex | 25 ++++++++++++--
 test/web/activity_pub/utils_test.exs  | 50 +++++++++++++++++++++++++++
 2 files changed, 72 insertions(+), 3 deletions(-)

diff --git a/lib/pleroma/web/activity_pub/utils.ex b/lib/pleroma/web/activity_pub/utils.ex
index 88f4779c8..9e50789db 100644
--- a/lib/pleroma/web/activity_pub/utils.ex
+++ b/lib/pleroma/web/activity_pub/utils.ex
@@ -7,6 +7,7 @@ defmodule Pleroma.Web.ActivityPub.Utils do
   alias Pleroma.Web
   alias Pleroma.Object
   alias Pleroma.Activity
+  alias Pleroma.Web.ActivityPub.Visibility
   alias Pleroma.User
   alias Pleroma.Notification
   alias Pleroma.Web.Router.Helpers
@@ -274,13 +275,31 @@ defmodule Pleroma.Web.ActivityPub.Utils do
     Repo.all(query)
   end
 
-  def make_like_data(%User{ap_id: ap_id} = actor, %{data: %{"id" => id}} = object, activity_id) do
+  def make_like_data(
+        %User{ap_id: ap_id} = actor,
+        %{data: %{"actor" => object_actor_id, "id" => id}} = object,
+        activity_id
+      ) do
+    object_actor = User.get_cached_by_ap_id(object_actor_id)
+
+    to =
+      if Visibility.is_public?(object) do
+        [actor.follower_address, object.data["actor"]]
+      else
+        [object.data["actor"]]
+      end
+
+    cc =
+      (object.data["to"] ++ (object.data["cc"] || []))
+      |> List.delete(actor.ap_id)
+      |> List.delete(object_actor.follower_address)
+
     data = %{
       "type" => "Like",
       "actor" => ap_id,
       "object" => id,
-      "to" => [actor.follower_address, object.data["actor"]],
-      "cc" => ["https://www.w3.org/ns/activitystreams#Public"],
+      "to" => to,
+      "cc" => cc,
       "context" => object.data["context"]
     }
 
diff --git a/test/web/activity_pub/utils_test.exs b/test/web/activity_pub/utils_test.exs
index aeed0564c..2e5e95795 100644
--- a/test/web/activity_pub/utils_test.exs
+++ b/test/web/activity_pub/utils_test.exs
@@ -1,7 +1,10 @@
 defmodule Pleroma.Web.ActivityPub.UtilsTest do
   use Pleroma.DataCase
+  alias Pleroma.Web.CommonAPI
   alias Pleroma.Web.ActivityPub.Utils
 
+  import Pleroma.Factory
+
   describe "determine_explicit_mentions()" do
     test "works with an object that has mentions" do
       object = %{
@@ -54,4 +57,51 @@ defmodule Pleroma.Web.ActivityPub.UtilsTest do
       assert Utils.determine_explicit_mentions(object) == []
     end
   end
+
+  describe "make_like_data" do
+    setup do
+      user = insert(:user)
+      other_user = insert(:user)
+      third_user = insert(:user)
+      [user: user, other_user: other_user, third_user: third_user]
+    end
+
+    test "addresses actor's follower address if the activity is public", %{
+      user: user,
+      other_user: other_user,
+      third_user: third_user
+    } do
+      expected_to = Enum.sort([user.ap_id, other_user.follower_address])
+      expected_cc = Enum.sort(["https://www.w3.org/ns/activitystreams#Public", third_user.ap_id])
+
+      {:ok, activity} =
+        CommonAPI.post(user, %{
+          "status" =>
+            "hey @#{other_user.nickname}, @#{third_user.nickname} how about beering together this weekend?"
+        })
+
+      %{"to" => to, "cc" => cc} = Utils.make_like_data(other_user, activity, nil)
+      assert Enum.sort(to) == expected_to
+      assert Enum.sort(cc) == expected_cc
+    end
+
+    test "does not adress actor's follower address if the activity is not public", %{
+      user: user,
+      other_user: other_user,
+      third_user: third_user
+    } do
+      expected_to = Enum.sort([user.ap_id])
+      expected_cc = [third_user.ap_id]
+
+      {:ok, activity} =
+        CommonAPI.post(user, %{
+          "status" => "@#{other_user.nickname} @#{third_user.nickname} bought a new swimsuit!",
+          "visibility" => "private"
+        })
+
+      %{"to" => to, "cc" => cc} = Utils.make_like_data(other_user, activity, nil)
+      assert Enum.sort(to) == expected_to
+      assert Enum.sort(cc) == expected_cc
+    end
+  end
 end