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