Blocks: make blockers_visible config work
authorAlex Gleason <alex@alexgleason.me>
Sat, 10 Oct 2020 08:41:35 +0000 (03:41 -0500)
committerAlex Gleason <alex@alexgleason.me>
Sat, 10 Oct 2020 08:41:35 +0000 (03:41 -0500)
lib/pleroma/web/activity_pub/activity_pub.ex
test/web/mastodon_api/controllers/timeline_controller_test.exs

index bf89c228a7188eb916fd4fbb22f105fe8ea730dc..c9712d245ac7a0bbefa5c1ea4483aeff0d3836fc 100644 (file)
@@ -410,6 +410,7 @@ defmodule Pleroma.Web.ActivityPub.ActivityPub do
     |> maybe_preload_bookmarks(opts)
     |> maybe_set_thread_muted_field(opts)
     |> restrict_blocked(opts)
+    |> restrict_blockers_visibility(opts)
     |> restrict_recipients(recipients, opts[:user])
     |> restrict_filtered(opts)
     |> where(
@@ -906,6 +907,31 @@ defmodule Pleroma.Web.ActivityPub.ActivityPub do
 
   defp restrict_blocked(query, _), do: query
 
+  defp restrict_blockers_visibility(query, %{blocking_user: %User{} = user}) do
+    if Config.get([:activitypub, :blockers_visible]) == true do
+      query
+    else
+      blocker_ap_ids = User.incoming_relationships_ungrouped_ap_ids(user, [:block])
+
+      from(
+        activity in query,
+        # The author doesn't block you
+        where: fragment("not (? = ANY(?))", activity.actor, ^blocker_ap_ids),
+
+        # It's not a boost of a user that blocks you
+        where:
+          fragment(
+            "not (?->>'type' = 'Announce' and ?->'to' \\?| ?)",
+            activity.data,
+            activity.data,
+            ^blocker_ap_ids
+          )
+      )
+    end
+  end
+
+  defp restrict_blockers_visibility(query, _), do: query
+
   defp restrict_unlisted(query, %{restrict_unlisted: true}) do
     from(
       activity in query,
@@ -1106,6 +1132,7 @@ defmodule Pleroma.Web.ActivityPub.ActivityPub do
     |> restrict_state(opts)
     |> restrict_favorited_by(opts)
     |> restrict_blocked(restrict_blocked_opts)
+    |> restrict_blockers_visibility(opts)
     |> restrict_muted(restrict_muted_opts)
     |> restrict_filtered(opts)
     |> restrict_media(opts)
index c6e0268fdbdaa80fd885a93976d27f704a98260e..e2a83081163da8ff47eec8878364ed05c9873394 100644 (file)
@@ -126,6 +126,24 @@ defmodule Pleroma.Web.MastodonAPI.TimelineControllerTest do
       [%{"id" => ^reply_from_me}, %{"id" => ^activity_id}] = response
     end
 
+    test "doesn't return posts from users who blocked you when :blockers_visible is disabled" do
+      clear_config([:activitypub, :blockers_visible], false)
+
+      %{conn: conn, user: blockee} = oauth_access(["read:statuses"])
+      blocker = insert(:user)
+      {:ok, _} = User.block(blocker, blockee)
+
+      conn = assign(conn, :user, blockee)
+
+      {:ok, _} = CommonAPI.post(blocker, %{status: "hey!"})
+
+      response =
+        get(conn, "/api/v1/timelines/public")
+        |> json_response_and_validate_schema(200)
+
+      assert length(response) == 0
+    end
+
     test "doesn't return replies if follow is posting with users from blocked domain" do
       %{conn: conn, user: blocker} = oauth_access(["read:statuses"])
       friend = insert(:user)