Merge remote-tracking branch 'pleroma/develop' into feature/disable-account
[akkoma] / lib / pleroma / web / activity_pub / mrf / hellthread_policy.ex
1 # Pleroma: A lightweight social networking server
2 # Copyright © 2017-2019 Pleroma Authors <https://pleroma.social/>
3 # SPDX-License-Identifier: AGPL-3.0-only
4
5 defmodule Pleroma.Web.ActivityPub.MRF.HellthreadPolicy do
6 alias Pleroma.User
7 @moduledoc "Block messages with too much mentions (configurable)"
8
9 @behaviour Pleroma.Web.ActivityPub.MRF
10
11 defp delist_message(message, threshold) when threshold > 0 do
12 follower_collection = User.get_cached_by_ap_id(message["actor"]).follower_address
13
14 follower_collection? = Enum.member?(message["to"] ++ message["cc"], follower_collection)
15
16 message =
17 case get_recipient_count(message) do
18 {:public, recipients}
19 when follower_collection? and recipients > threshold ->
20 message
21 |> Map.put("to", [follower_collection])
22 |> Map.put("cc", ["https://www.w3.org/ns/activitystreams#Public"])
23
24 {:public, recipients} when recipients > threshold ->
25 message
26 |> Map.put("to", [])
27 |> Map.put("cc", ["https://www.w3.org/ns/activitystreams#Public"])
28
29 _ ->
30 message
31 end
32
33 {:ok, message}
34 end
35
36 defp delist_message(message, _threshold), do: {:ok, message}
37
38 defp reject_message(message, threshold) when threshold > 0 do
39 with {_, recipients} <- get_recipient_count(message) do
40 if recipients > threshold do
41 {:reject, nil}
42 else
43 {:ok, message}
44 end
45 end
46 end
47
48 defp reject_message(message, _threshold), do: {:ok, message}
49
50 defp get_recipient_count(message) do
51 recipients = (message["to"] || []) ++ (message["cc"] || [])
52 follower_collection = User.get_cached_by_ap_id(message["actor"]).follower_address
53
54 if Enum.member?(recipients, "https://www.w3.org/ns/activitystreams#Public") do
55 recipients =
56 recipients
57 |> List.delete("https://www.w3.org/ns/activitystreams#Public")
58 |> List.delete(follower_collection)
59
60 {:public, length(recipients)}
61 else
62 recipients =
63 recipients
64 |> List.delete(follower_collection)
65
66 {:not_public, length(recipients)}
67 end
68 end
69
70 @impl true
71 def filter(%{"type" => "Create"} = message) do
72 reject_threshold =
73 Pleroma.Config.get(
74 [:mrf_hellthread, :reject_threshold],
75 Pleroma.Config.get([:mrf_hellthread, :threshold])
76 )
77
78 delist_threshold = Pleroma.Config.get([:mrf_hellthread, :delist_threshold])
79
80 with {:ok, message} <- reject_message(message, reject_threshold),
81 {:ok, message} <- delist_message(message, delist_threshold) do
82 {:ok, message}
83 else
84 _e -> {:reject, nil}
85 end
86 end
87
88 @impl true
89 def filter(message), do: {:ok, message}
90 end