Add short documentation on every MRF Policy
[akkoma] / lib / pleroma / web / activity_pub / mrf / tag_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.TagPolicy do
6 alias Pleroma.User
7 @behaviour Pleroma.Web.ActivityPub.MRF
8 @moduledoc "Apply policies based on user tags"
9
10 defp get_tags(%User{tags: tags}) when is_list(tags), do: tags
11 defp get_tags(_), do: []
12
13 defp process_tag(
14 "mrf_tag:media-force-nsfw",
15 %{"type" => "Create", "object" => %{"attachment" => child_attachment} = object} = message
16 )
17 when length(child_attachment) > 0 do
18 tags = (object["tag"] || []) ++ ["nsfw"]
19
20 object =
21 object
22 |> Map.put("tags", tags)
23 |> Map.put("sensitive", true)
24
25 message = Map.put(message, "object", object)
26
27 {:ok, message}
28 end
29
30 defp process_tag(
31 "mrf_tag:media-strip",
32 %{"type" => "Create", "object" => %{"attachment" => child_attachment} = object} = message
33 )
34 when length(child_attachment) > 0 do
35 object = Map.delete(object, "attachment")
36 message = Map.put(message, "object", object)
37
38 {:ok, message}
39 end
40
41 defp process_tag(
42 "mrf_tag:force-unlisted",
43 %{"type" => "Create", "to" => to, "cc" => cc, "actor" => actor} = message
44 ) do
45 user = User.get_cached_by_ap_id(actor)
46
47 if Enum.member?(to, "https://www.w3.org/ns/activitystreams#Public") do
48 to =
49 List.delete(to, "https://www.w3.org/ns/activitystreams#Public") ++ [user.follower_address]
50
51 cc =
52 List.delete(cc, user.follower_address) ++ ["https://www.w3.org/ns/activitystreams#Public"]
53
54 object =
55 message["object"]
56 |> Map.put("to", to)
57 |> Map.put("cc", cc)
58
59 message =
60 message
61 |> Map.put("to", to)
62 |> Map.put("cc", cc)
63 |> Map.put("object", object)
64
65 {:ok, message}
66 else
67 {:ok, message}
68 end
69 end
70
71 defp process_tag(
72 "mrf_tag:sandbox",
73 %{"type" => "Create", "to" => to, "cc" => cc, "actor" => actor} = message
74 ) do
75 user = User.get_cached_by_ap_id(actor)
76
77 if Enum.member?(to, "https://www.w3.org/ns/activitystreams#Public") or
78 Enum.member?(cc, "https://www.w3.org/ns/activitystreams#Public") do
79 to =
80 List.delete(to, "https://www.w3.org/ns/activitystreams#Public") ++ [user.follower_address]
81
82 cc = List.delete(cc, "https://www.w3.org/ns/activitystreams#Public")
83
84 object =
85 message["object"]
86 |> Map.put("to", to)
87 |> Map.put("cc", cc)
88
89 message =
90 message
91 |> Map.put("to", to)
92 |> Map.put("cc", cc)
93 |> Map.put("object", object)
94
95 {:ok, message}
96 else
97 {:ok, message}
98 end
99 end
100
101 defp process_tag(
102 "mrf_tag:disable-remote-subscription",
103 %{"type" => "Follow", "actor" => actor} = message
104 ) do
105 user = User.get_cached_by_ap_id(actor)
106
107 if user.local == true do
108 {:ok, message}
109 else
110 {:reject, nil}
111 end
112 end
113
114 defp process_tag("mrf_tag:disable-any-subscription", %{"type" => "Follow"}), do: {:reject, nil}
115
116 defp process_tag(_, message), do: {:ok, message}
117
118 def filter_message(actor, message) do
119 User.get_cached_by_ap_id(actor)
120 |> get_tags()
121 |> Enum.reduce({:ok, message}, fn
122 tag, {:ok, message} ->
123 process_tag(tag, message)
124
125 _, error ->
126 error
127 end)
128 end
129
130 @impl true
131 def filter(%{"object" => target_actor, "type" => "Follow"} = message),
132 do: filter_message(target_actor, message)
133
134 @impl true
135 def filter(%{"actor" => actor, "type" => "Create"} = message),
136 do: filter_message(actor, message)
137
138 @impl true
139 def filter(message), do: {:ok, message}
140 end