From cc09079aea54f5ff754925e0d5fbbc3b268dcb6d Mon Sep 17 00:00:00 2001
From: Alex Gleason <alex@alexgleason.me>
Date: Wed, 6 Jan 2021 15:39:14 -0600
Subject: [PATCH] Exclude blockers from notifications when `blockers_visible:
 false`

---
 lib/pleroma/notification.ex                   | 12 ++++++++++++
 .../notification_controller_test.exs          | 19 +++++++++++++++++++
 2 files changed, 31 insertions(+)

diff --git a/lib/pleroma/notification.ex b/lib/pleroma/notification.ex
index dd7a1c824..e9c9b3ea2 100644
--- a/lib/pleroma/notification.ex
+++ b/lib/pleroma/notification.ex
@@ -132,6 +132,7 @@ defmodule Pleroma.Notification do
     |> preload([n, a, o], activity: {a, object: o})
     |> exclude_notification_muted(user, exclude_notification_muted_opts)
     |> exclude_blocked(user, exclude_blocked_opts)
+    |> exclude_blockers(user)
     |> exclude_filtered(user)
     |> exclude_visibility(opts)
   end
@@ -145,6 +146,17 @@ defmodule Pleroma.Notification do
     |> FollowingRelationship.keep_following_or_not_domain_blocked(user)
   end
 
+  defp exclude_blockers(query, user) do
+    if Pleroma.Config.get([:activitypub, :blockers_visible]) == true do
+      query
+    else
+      blocker_ap_ids = User.incoming_relationships_ungrouped_ap_ids(user, [:block])
+
+      query
+      |> where([n, a], a.actor not in ^blocker_ap_ids)
+    end
+  end
+
   defp exclude_notification_muted(query, _, %{@include_muted_option => true}) do
     query
   end
diff --git a/test/pleroma/web/mastodon_api/controllers/notification_controller_test.exs b/test/pleroma/web/mastodon_api/controllers/notification_controller_test.exs
index 9ac8488f6..ef35bdd00 100644
--- a/test/pleroma/web/mastodon_api/controllers/notification_controller_test.exs
+++ b/test/pleroma/web/mastodon_api/controllers/notification_controller_test.exs
@@ -103,6 +103,25 @@ defmodule Pleroma.Web.MastodonAPI.NotificationControllerTest do
     assert [_] = result
   end
 
+  test "excludes mentions from blockers when blockers_visible is false" do
+    clear_config([:activitypub, :blockers_visible], false)
+
+    %{user: user, conn: conn} = oauth_access(["read:notifications"])
+    blocker = insert(:user)
+
+    {:ok, _} = CommonAPI.block(blocker, user)
+    {:ok, activity} = CommonAPI.post(blocker, %{status: "hi @#{user.nickname}"})
+
+    {:ok, [_notification]} = Notification.create_notifications(activity)
+
+    conn =
+      conn
+      |> assign(:user, user)
+      |> get("/api/v1/notifications")
+
+    assert [] == json_response_and_validate_schema(conn, 200)
+  end
+
   test "getting a single notification" do
     %{user: user, conn: conn} = oauth_access(["read:notifications"])
     other_user = insert(:user)