diff --git a/lib/pleroma/user.ex b/lib/pleroma/user.ex index 63c5b4102..601aa9cf0 100644 --- a/lib/pleroma/user.ex +++ b/lib/pleroma/user.ex @@ -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) diff --git a/lib/pleroma/web/activity_pub/activity_pub.ex b/lib/pleroma/web/activity_pub/activity_pub.ex index f25314ff6..3c4aed241 100644 --- a/lib/pleroma/web/activity_pub/activity_pub.ex +++ b/lib/pleroma/web/activity_pub/activity_pub.ex @@ -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 diff --git a/test/web/activity_pub/activity_pub_test.exs b/test/web/activity_pub/activity_pub_test.exs index d437ad456..503bbf0db 100644 --- a/test/web/activity_pub/activity_pub_test.exs +++ b/test/web/activity_pub/activity_pub_test.exs @@ -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)