diff --git a/CHANGELOG.md b/CHANGELOG.md
index 4b4048109..db505591b 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -78,6 +78,7 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/).
- ActivityPub: Deactivated user deletion
- ActivityPub: Fix `/users/:nickname/inbox` crashing without an authenticated user
- MRF: fix ability to follow a relay when AntiFollowbotPolicy was enabled
+- Mastodon API: Blocks are now treated consistently between the Streaming API and the Timeline APIs
### Added
- Expiring/ephemeral activites. All activities can have expires_at value set, which controls when they should be deleted automatically.
diff --git a/lib/pleroma/web/streamer/ping.ex b/lib/pleroma/web/streamer/ping.ex
index f77cbb95c..db3e68abe 100644
--- a/lib/pleroma/web/streamer/ping.ex
+++ b/lib/pleroma/web/streamer/ping.ex
@@ -1,3 +1,7 @@
+# Pleroma: A lightweight social networking server
+# Copyright © 2017-2019 Pleroma Authors
+# SPDX-License-Identifier: AGPL-3.0-only
+
defmodule Pleroma.Web.Streamer.Ping do
use GenServer
require Logger
diff --git a/lib/pleroma/web/streamer/state.ex b/lib/pleroma/web/streamer/state.ex
index c48752d95..5ce3ebb8a 100644
--- a/lib/pleroma/web/streamer/state.ex
+++ b/lib/pleroma/web/streamer/state.ex
@@ -1,3 +1,7 @@
+# Pleroma: A lightweight social networking server
+# Copyright © 2017-2019 Pleroma Authors
+# SPDX-License-Identifier: AGPL-3.0-only
+
defmodule Pleroma.Web.Streamer.State do
use GenServer
require Logger
diff --git a/lib/pleroma/web/streamer/streamer_socket.ex b/lib/pleroma/web/streamer/streamer_socket.ex
index f006c0306..cf0fa3077 100644
--- a/lib/pleroma/web/streamer/streamer_socket.ex
+++ b/lib/pleroma/web/streamer/streamer_socket.ex
@@ -1,3 +1,7 @@
+# Pleroma: A lightweight social networking server
+# Copyright © 2017-2019 Pleroma Authors
+# SPDX-License-Identifier: AGPL-3.0-only
+
defmodule Pleroma.Web.Streamer.StreamerSocket do
defstruct transport_pid: nil, user: nil
diff --git a/lib/pleroma/web/streamer/supervisor.ex b/lib/pleroma/web/streamer/supervisor.ex
index 6afe19323..ec5985085 100644
--- a/lib/pleroma/web/streamer/supervisor.ex
+++ b/lib/pleroma/web/streamer/supervisor.ex
@@ -1,3 +1,7 @@
+# Pleroma: A lightweight social networking server
+# Copyright © 2017-2019 Pleroma Authors
+# SPDX-License-Identifier: AGPL-3.0-only
+
defmodule Pleroma.Web.Streamer.Supervisor do
use Supervisor
diff --git a/lib/pleroma/web/streamer/worker.ex b/lib/pleroma/web/streamer/worker.ex
index 5804508eb..0ea224874 100644
--- a/lib/pleroma/web/streamer/worker.ex
+++ b/lib/pleroma/web/streamer/worker.ex
@@ -1,3 +1,7 @@
+# Pleroma: A lightweight social networking server
+# Copyright © 2017-2019 Pleroma Authors
+# SPDX-License-Identifier: AGPL-3.0-only
+
defmodule Pleroma.Web.Streamer.Worker do
use GenServer
@@ -128,11 +132,14 @@ defp should_send?(%User{} = user, %Activity{} = item) do
blocks = user.info.blocks || []
mutes = user.info.mutes || []
reblog_mutes = user.info.muted_reblogs || []
+ recipient_blocks = MapSet.new(blocks ++ mutes)
+ recipients = MapSet.new(item.recipients)
domain_blocks = Pleroma.Web.ActivityPub.MRF.subdomains_regex(user.info.domain_blocks)
with parent when not is_nil(parent) <- Object.normalize(item),
true <- Enum.all?([blocks, mutes, reblog_mutes], &(item.actor not in &1)),
true <- Enum.all?([blocks, mutes], &(parent.data["actor"] not in &1)),
+ true <- MapSet.disjoint?(recipients, recipient_blocks),
%{host: item_host} <- URI.parse(item.actor),
%{host: parent_host} <- URI.parse(parent.data["actor"]),
false <- Pleroma.Web.ActivityPub.MRF.subdomain_match?(domain_blocks, item_host),
@@ -194,11 +201,8 @@ def push_to_socket(topics, topic, item) do
# Get the current user so we have up-to-date blocks etc.
if socket_user do
user = User.get_cached_by_ap_id(socket_user.ap_id)
- blocks = user.info.blocks || []
- mutes = user.info.mutes || []
- with true <- Enum.all?([blocks, mutes], &(item.actor not in &1)),
- true <- thread_containment(item, user) do
+ if should_send?(user, item) do
send(transport_pid, {:text, StreamerView.render("update.json", item, user)})
end
else
diff --git a/test/web/streamer/streamer_test.exs b/test/web/streamer/streamer_test.exs
index b8fcd41fa..d33eb1e42 100644
--- a/test/web/streamer/streamer_test.exs
+++ b/test/web/streamer/streamer_test.exs
@@ -233,30 +233,68 @@ test "it sends message if recipients invalid and thread containment is enabled b
end
end
- test "it doesn't send to blocked users" do
- user = insert(:user)
- blocked_user = insert(:user)
- {:ok, user} = User.block(user, blocked_user)
+ describe "blocks" do
+ test "it doesn't send messages involving blocked users" do
+ user = insert(:user)
+ blocked_user = insert(:user)
+ {:ok, user} = User.block(user, blocked_user)
- task =
- Task.async(fn ->
- refute_receive {:text, _}, 1_000
- end)
+ task =
+ Task.async(fn ->
+ refute_receive {:text, _}, 1_000
+ end)
- fake_socket = %StreamerSocket{
- transport_pid: task.pid,
- user: user
- }
+ fake_socket = %StreamerSocket{
+ transport_pid: task.pid,
+ user: user
+ }
- {:ok, activity} = CommonAPI.post(blocked_user, %{"status" => "Test"})
+ {:ok, activity} = CommonAPI.post(blocked_user, %{"status" => "Test"})
- topics = %{
- "public" => [fake_socket]
- }
+ topics = %{
+ "public" => [fake_socket]
+ }
- Worker.push_to_socket(topics, "public", activity)
+ Worker.push_to_socket(topics, "public", activity)
- Task.await(task)
+ Task.await(task)
+ end
+
+ test "it doesn't send messages transitively involving blocked users" do
+ blocker = insert(:user)
+ blockee = insert(:user)
+ friend = insert(:user)
+
+ task =
+ Task.async(fn ->
+ refute_receive {:text, _}, 1_000
+ end)
+
+ fake_socket = %StreamerSocket{
+ transport_pid: task.pid,
+ user: blocker
+ }
+
+ topics = %{
+ "public" => [fake_socket]
+ }
+
+ {:ok, blocker} = User.block(blocker, blockee)
+
+ {:ok, activity_one} = CommonAPI.post(friend, %{"status" => "hey! @#{blockee.nickname}"})
+
+ Worker.push_to_socket(topics, "public", activity_one)
+
+ {:ok, activity_two} = CommonAPI.post(blockee, %{"status" => "hey! @#{friend.nickname}"})
+
+ Worker.push_to_socket(topics, "public", activity_two)
+
+ {:ok, activity_three} = CommonAPI.post(blockee, %{"status" => "hey! @#{blocker.nickname}"})
+
+ Worker.push_to_socket(topics, "public", activity_three)
+
+ Task.await(task)
+ end
end
test "it doesn't send unwanted DMs to list" do