Merge branch 'bugfix/widen-streamer-blocks' into 'develop'

widen streaming API block effects

See merge request pleroma/pleroma!1784
This commit is contained in:
kaniini 2019-10-04 17:39:06 +00:00
commit e0c0ea9f13
7 changed files with 81 additions and 22 deletions

View file

@ -78,6 +78,7 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/).
- ActivityPub: Deactivated user deletion - ActivityPub: Deactivated user deletion
- ActivityPub: Fix `/users/:nickname/inbox` crashing without an authenticated user - ActivityPub: Fix `/users/:nickname/inbox` crashing without an authenticated user
- MRF: fix ability to follow a relay when AntiFollowbotPolicy was enabled - 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 ### Added
- Expiring/ephemeral activites. All activities can have expires_at value set, which controls when they should be deleted automatically. - Expiring/ephemeral activites. All activities can have expires_at value set, which controls when they should be deleted automatically.

View file

@ -1,3 +1,7 @@
# Pleroma: A lightweight social networking server
# Copyright © 2017-2019 Pleroma Authors <https://pleroma.social/>
# SPDX-License-Identifier: AGPL-3.0-only
defmodule Pleroma.Web.Streamer.Ping do defmodule Pleroma.Web.Streamer.Ping do
use GenServer use GenServer
require Logger require Logger

View file

@ -1,3 +1,7 @@
# Pleroma: A lightweight social networking server
# Copyright © 2017-2019 Pleroma Authors <https://pleroma.social/>
# SPDX-License-Identifier: AGPL-3.0-only
defmodule Pleroma.Web.Streamer.State do defmodule Pleroma.Web.Streamer.State do
use GenServer use GenServer
require Logger require Logger

View file

@ -1,3 +1,7 @@
# Pleroma: A lightweight social networking server
# Copyright © 2017-2019 Pleroma Authors <https://pleroma.social/>
# SPDX-License-Identifier: AGPL-3.0-only
defmodule Pleroma.Web.Streamer.StreamerSocket do defmodule Pleroma.Web.Streamer.StreamerSocket do
defstruct transport_pid: nil, user: nil defstruct transport_pid: nil, user: nil

View file

@ -1,3 +1,7 @@
# Pleroma: A lightweight social networking server
# Copyright © 2017-2019 Pleroma Authors <https://pleroma.social/>
# SPDX-License-Identifier: AGPL-3.0-only
defmodule Pleroma.Web.Streamer.Supervisor do defmodule Pleroma.Web.Streamer.Supervisor do
use Supervisor use Supervisor

View file

@ -1,3 +1,7 @@
# Pleroma: A lightweight social networking server
# Copyright © 2017-2019 Pleroma Authors <https://pleroma.social/>
# SPDX-License-Identifier: AGPL-3.0-only
defmodule Pleroma.Web.Streamer.Worker do defmodule Pleroma.Web.Streamer.Worker do
use GenServer use GenServer
@ -128,11 +132,14 @@ defp should_send?(%User{} = user, %Activity{} = item) do
blocks = user.info.blocks || [] blocks = user.info.blocks || []
mutes = user.info.mutes || [] mutes = user.info.mutes || []
reblog_mutes = user.info.muted_reblogs || [] 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) domain_blocks = Pleroma.Web.ActivityPub.MRF.subdomains_regex(user.info.domain_blocks)
with parent when not is_nil(parent) <- Object.normalize(item), 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, reblog_mutes], &(item.actor not in &1)),
true <- Enum.all?([blocks, mutes], &(parent.data["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: item_host} <- URI.parse(item.actor),
%{host: parent_host} <- URI.parse(parent.data["actor"]), %{host: parent_host} <- URI.parse(parent.data["actor"]),
false <- Pleroma.Web.ActivityPub.MRF.subdomain_match?(domain_blocks, item_host), 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. # Get the current user so we have up-to-date blocks etc.
if socket_user do if socket_user do
user = User.get_cached_by_ap_id(socket_user.ap_id) 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)), if should_send?(user, item) do
true <- thread_containment(item, user) do
send(transport_pid, {:text, StreamerView.render("update.json", item, user)}) send(transport_pid, {:text, StreamerView.render("update.json", item, user)})
end end
else else

View file

@ -233,30 +233,68 @@ test "it sends message if recipients invalid and thread containment is enabled b
end end
end end
test "it doesn't send to blocked users" do describe "blocks" do
user = insert(:user) test "it doesn't send messages involving blocked users" do
blocked_user = insert(:user) user = insert(:user)
{:ok, user} = User.block(user, blocked_user) blocked_user = insert(:user)
{:ok, user} = User.block(user, blocked_user)
task = task =
Task.async(fn -> Task.async(fn ->
refute_receive {:text, _}, 1_000 refute_receive {:text, _}, 1_000
end) end)
fake_socket = %StreamerSocket{ fake_socket = %StreamerSocket{
transport_pid: task.pid, transport_pid: task.pid,
user: user user: user
} }
{:ok, activity} = CommonAPI.post(blocked_user, %{"status" => "Test"}) {:ok, activity} = CommonAPI.post(blocked_user, %{"status" => "Test"})
topics = %{ topics = %{
"public" => [fake_socket] "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 end
test "it doesn't send unwanted DMs to list" do test "it doesn't send unwanted DMs to list" do