ActivityPub: Return Announces when filtering by `following`.
authorlain <lain@soykaf.club>
Tue, 22 Sep 2020 12:20:19 +0000 (14:20 +0200)
committerlain <lain@soykaf.club>
Tue, 22 Sep 2020 12:20:19 +0000 (14:20 +0200)
lib/pleroma/web/activity_pub/activity_pub.ex
test/web/activity_pub/activity_pub_test.exs

index aacd58d0310d3dbed462c61f9da6073caf3fea43..eb44cffec14eddb5634a3973a1f6625fbcd14acb 100644 (file)
@@ -790,7 +790,17 @@ defmodule Pleroma.Web.ActivityPub.ActivityPub do
       [activity, object] in query,
       where:
         fragment(
-          "?->>'inReplyTo' is null OR ? && array_remove(?, ?) OR ? = ?",
+          """
+          ?->>'type' != 'Create'     -- This isn't a Create      
+          OR ?->>'inReplyTo' is null -- this isn't a reply
+          OR ? && array_remove(?, ?) -- The recipient is us or one of our friends, 
+                                     -- unless they are the author (because authors 
+                                     -- are also part of the recipients). This leads
+                                     -- to a bug that self-replies by friends won't
+                                     -- show up.
+          OR ? = ?                   -- The actor is us
+          """,
+          activity.data,
           object.data,
           ^[user.ap_id | User.get_cached_user_friends_ap_ids(user)],
           activity.recipients,
index 7bdad3810d960df6f8337d0d75d02a5835276203..804305a1381321e35c4ae38dcc8d67febcecf5de 100644 (file)
@@ -2177,4 +2177,84 @@ defmodule Pleroma.Web.ActivityPub.ActivityPubTest do
       assert user.nickname == orig_user.nickname
     end
   end
+
+  describe "reply filtering" do
+    test "`following` still contains announcements by friends" do
+      user = insert(:user)
+      followed = insert(:user)
+      not_followed = insert(:user)
+
+      User.follow(user, followed)
+
+      {:ok, followed_post} = CommonAPI.post(followed, %{status: "Hello"})
+
+      {:ok, not_followed_to_followed} =
+        CommonAPI.post(not_followed, %{
+          status: "Also hello",
+          in_reply_to_status_id: followed_post.id
+        })
+
+      {:ok, retoot} = CommonAPI.repeat(not_followed_to_followed.id, followed)
+
+      params =
+        %{}
+        |> Map.put(:type, ["Create", "Announce"])
+        |> Map.put(:blocking_user, user)
+        |> Map.put(:muting_user, user)
+        |> Map.put(:reply_filtering_user, user)
+        |> Map.put(:reply_visibility, "following")
+        |> Map.put(:announce_filtering_user, user)
+        |> Map.put(:user, user)
+
+      activities =
+        [user.ap_id | User.following(user)]
+        |> ActivityPub.fetch_activities(params)
+
+      followed_post_id = followed_post.id
+      retoot_id = retoot.id
+
+      assert [%{id: ^followed_post_id}, %{id: ^retoot_id}] = activities
+
+      assert length(activities) == 2
+    end
+
+    # This test is skipped because, while this is the desired behavior,
+    # there seems to be no good way to achieve it with the method that
+    # we currently use for detecting to who a reply is directed.
+    # This is a TODO and should be fixed by a later rewrite of the code
+    # in question.
+    @tag skip: true
+    test "`following` still contains self-replies by friends" do
+      user = insert(:user)
+      followed = insert(:user)
+      not_followed = insert(:user)
+
+      User.follow(user, followed)
+
+      {:ok, followed_post} = CommonAPI.post(followed, %{status: "Hello"})
+      {:ok, not_followed_post} = CommonAPI.post(not_followed, %{status: "Also hello"})
+
+      {:ok, _followed_to_not_followed} =
+        CommonAPI.post(followed, %{status: "sup", in_reply_to_status_id: not_followed_post.id})
+
+      {:ok, _followed_self_reply} =
+        CommonAPI.post(followed, %{status: "Also cofe", in_reply_to_status_id: followed_post.id})
+
+      params =
+        %{}
+        |> Map.put(:type, ["Create", "Announce"])
+        |> Map.put(:blocking_user, user)
+        |> Map.put(:muting_user, user)
+        |> Map.put(:reply_filtering_user, user)
+        |> Map.put(:reply_visibility, "following")
+        |> Map.put(:announce_filtering_user, user)
+        |> Map.put(:user, user)
+
+      activities =
+        [user.ap_id | User.following(user)]
+        |> ActivityPub.fetch_activities(params)
+
+      assert length(activities) == 2
+    end
+  end
 end