modify SQL to include followed-but-domain-blocked activities
authorSadposter <hannah+pleroma@coffee-and-dreams.uk>
Tue, 10 Dec 2019 16:40:12 +0000 (16:40 +0000)
committerSadposter <hannah+pleroma@coffee-and-dreams.uk>
Tue, 10 Dec 2019 16:40:12 +0000 (16:40 +0000)
lib/pleroma/user.ex
lib/pleroma/web/activity_pub/activity_pub.ex
test/web/activity_pub/activity_pub_test.exs

index 63c5b4102dcffd2bad0a7e5d150f1d16aeb214f0..601aa9cf04963c50e2d448f3323850c903dd7954 100644 (file)
@@ -762,6 +762,13 @@ defmodule Pleroma.User do
     |> Repo.all()
   end
 
+  def get_friends_ap_ids(user) do
+    user
+    |> get_friends_query(nil)
+    |> select([u], u.ap_id)
+    |> Repo.all()
+  end
+
   def get_friends_ids(user, page \\ nil) do
     user
     |> get_friends_query(page)
index f25314ff611bcda168134014bdb32519107ad636..3c4aed241c6c521376d4e71a5fcfe3bcc543d5b8 100644 (file)
@@ -915,6 +915,9 @@ defmodule Pleroma.Web.ActivityPub.ActivityPub do
   defp restrict_blocked(query, %{"blocking_user" => %User{} = user}) do
     blocks = user.blocks || []
     domain_blocks = user.domain_blocks || []
+    following_ap_ids =
+        user
+        |> User.get_friends_ap_ids()
 
     query =
       if has_named_binding?(query, :object), do: query, else: Activity.with_joined_object(query)
@@ -930,8 +933,8 @@ defmodule Pleroma.Web.ActivityPub.ActivityPub do
           activity.data,
           ^blocks
         ),
-      where: fragment("not (split_part(?, '/', 3) = ANY(?))", activity.actor, ^domain_blocks),
-      where: fragment("not (split_part(?->>'actor', '/', 3) = ANY(?))", o.data, ^domain_blocks)
+      where: fragment("(not (split_part(?, '/', 3) = ANY(?))) or ? = ANY(?)", activity.actor, ^domain_blocks, activity.actor, ^following_ap_ids),
+      where: fragment("(not (split_part(?->>'actor', '/', 3) = ANY(?))) or (?->>'actor') = ANY(?)", o.data, ^domain_blocks, o.data, ^following_ap_ids)
     )
   end
 
index d437ad456c78a8d1c85e739748fbd321605d6021..503bbf0db662370cccfbc27bffcc27ea14bf0c7d 100644 (file)
@@ -605,6 +605,38 @@ defmodule Pleroma.Web.ActivityPub.ActivityPubTest do
     refute repeat_activity in activities
   end
 
+  test "does return activities from followed users on blocked domains" do
+    domain = "meanies.social"
+    domain_user = insert(:user, %{ap_id: "https://#{domain}/@pundit"})
+    blocker = insert(:user)
+
+    {:ok, blocker} = User.follow(blocker, domain_user)
+    {:ok, blocker} = User.block_domain(blocker, domain)
+
+    assert User.following?(blocker, domain_user)
+    assert User.blocks_domain?(blocker, domain_user)
+    refute User.blocks?(blocker, domain_user)
+
+    note = insert(:note, %{data: %{"actor" => domain_user.ap_id}})
+    activity = insert(:note_activity, %{note: note})
+
+    activities =
+      ActivityPub.fetch_activities([], %{"blocking_user" => blocker, "skip_preload" => true})
+
+    assert activity in activities
+
+    # And check that if the guy we DO follow boosts someone else from their domain, that should be hidden
+    another_user = insert(:user, %{ap_id: "https://#{domain}/@meanie2"})
+    bad_note = insert(:note, %{data: %{"actor" => another_user.ap_id}})
+    bad_activity = insert(:note_activity, %{note: bad_note})
+    {:ok, repeat_activity, _} = CommonAPI.repeat(bad_activity.id, domain_user)
+
+    activities =
+      ActivityPub.fetch_activities([], %{"blocking_user" => blocker, "skip_preload" => true})
+
+    refute repeat_activity in activities
+  end
+
   test "doesn't return muted activities" do
     activity_one = insert(:note_activity)
     activity_two = insert(:note_activity)