[#468] Merged `upstream/develop`.
[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 @behaviour Pleroma.Web.ActivityPub.MRF
8
9 defp delist_message(message, threshold) when threshold > 0 do
10 follower_collection = User.get_cached_by_ap_id(message["actor"]).follower_address
11
12 follower_collection? = Enum.member?(message["to"] ++ message["cc"], follower_collection)
13
14 message =
15 case get_recipient_count(message) do
16 {:public, recipients}
17 when follower_collection? and recipients > threshold ->
18 message
19 |> Map.put("to", [follower_collection])
20 |> Map.put("cc", ["https://www.w3.org/ns/activitystreams#Public"])
21
22 {:public, recipients} when recipients > threshold ->
23 message
24 |> Map.put("to", [])
25 |> Map.put("cc", ["https://www.w3.org/ns/activitystreams#Public"])
26
27 _ ->
28 message
29 end
30
31 {:ok, message}
32 end
33
34 defp delist_message(message, _threshold), do: {:ok, message}
35
36 defp reject_message(message, threshold) when threshold > 0 do
37 with {_, recipients} <- get_recipient_count(message) do
38 if recipients > threshold do
39 {:reject, nil}
40 else
41 {:ok, message}
42 end
43 end
44 end
45
46 defp reject_message(message, _threshold), do: {:ok, message}
47
48 defp get_recipient_count(message) do
49 recipients = (message["to"] || []) ++ (message["cc"] || [])
50 follower_collection = User.get_cached_by_ap_id(message["actor"]).follower_address
51
52 if Enum.member?(recipients, "https://www.w3.org/ns/activitystreams#Public") do
53 recipients =
54 recipients
55 |> List.delete("https://www.w3.org/ns/activitystreams#Public")
56 |> List.delete(follower_collection)
57
58 {:public, length(recipients)}
59 else
60 recipients =
61 recipients
62 |> List.delete(follower_collection)
63
64 {:not_public, length(recipients)}
65 end
66 end
67
68 @impl true
69 def filter(%{"type" => "Create"} = message) do
70 reject_threshold =
71 Pleroma.Config.get(
72 [:mrf_hellthread, :reject_threshold],
73 Pleroma.Config.get([:mrf_hellthread, :threshold])
74 )
75
76 delist_threshold = Pleroma.Config.get([:mrf_hellthread, :delist_threshold])
77
78 with {:ok, message} <- reject_message(message, reject_threshold),
79 {:ok, message} <- delist_message(message, delist_threshold) do
80 {:ok, message}
81 else
82 _e -> {:reject, nil}
83 end
84 end
85
86 @impl true
87 def filter(message), do: {:ok, message}
88 end