Merge branch 'develop' into feature/digest-email
[akkoma] / test / web / activity_pub / mrf / simple_policy_test.exs
1 # Pleroma: A lightweight social networking server
2 # Copyright © 2019 Pleroma Authors <https://pleroma.social/>
3 # SPDX-License-Identifier: AGPL-3.0-only
4
5 defmodule Pleroma.Web.ActivityPub.MRF.SimplePolicyTest do
6 use Pleroma.DataCase
7 import Pleroma.Factory
8 alias Pleroma.Config
9 alias Pleroma.Web.ActivityPub.MRF.SimplePolicy
10
11 setup do
12 orig = Config.get!(:mrf_simple)
13
14 Config.put(:mrf_simple,
15 media_removal: [],
16 media_nsfw: [],
17 federated_timeline_removal: [],
18 report_removal: [],
19 reject: [],
20 accept: [],
21 avatar_removal: [],
22 banner_removal: []
23 )
24
25 on_exit(fn ->
26 Config.put(:mrf_simple, orig)
27 end)
28 end
29
30 describe "when :media_removal" do
31 test "is empty" do
32 Config.put([:mrf_simple, :media_removal], [])
33 media_message = build_media_message()
34 local_message = build_local_message()
35
36 assert SimplePolicy.filter(media_message) == {:ok, media_message}
37 assert SimplePolicy.filter(local_message) == {:ok, local_message}
38 end
39
40 test "has a matching host" do
41 Config.put([:mrf_simple, :media_removal], ["remote.instance"])
42 media_message = build_media_message()
43 local_message = build_local_message()
44
45 assert SimplePolicy.filter(media_message) ==
46 {:ok,
47 media_message
48 |> Map.put("object", Map.delete(media_message["object"], "attachment"))}
49
50 assert SimplePolicy.filter(local_message) == {:ok, local_message}
51 end
52
53 test "match with wildcard domain" do
54 Config.put([:mrf_simple, :media_removal], ["*.remote.instance"])
55 media_message = build_media_message()
56 local_message = build_local_message()
57
58 assert SimplePolicy.filter(media_message) ==
59 {:ok,
60 media_message
61 |> Map.put("object", Map.delete(media_message["object"], "attachment"))}
62
63 assert SimplePolicy.filter(local_message) == {:ok, local_message}
64 end
65 end
66
67 describe "when :media_nsfw" do
68 test "is empty" do
69 Config.put([:mrf_simple, :media_nsfw], [])
70 media_message = build_media_message()
71 local_message = build_local_message()
72
73 assert SimplePolicy.filter(media_message) == {:ok, media_message}
74 assert SimplePolicy.filter(local_message) == {:ok, local_message}
75 end
76
77 test "has a matching host" do
78 Config.put([:mrf_simple, :media_nsfw], ["remote.instance"])
79 media_message = build_media_message()
80 local_message = build_local_message()
81
82 assert SimplePolicy.filter(media_message) ==
83 {:ok,
84 media_message
85 |> put_in(["object", "tag"], ["foo", "nsfw"])
86 |> put_in(["object", "sensitive"], true)}
87
88 assert SimplePolicy.filter(local_message) == {:ok, local_message}
89 end
90
91 test "match with wildcard domain" do
92 Config.put([:mrf_simple, :media_nsfw], ["*.remote.instance"])
93 media_message = build_media_message()
94 local_message = build_local_message()
95
96 assert SimplePolicy.filter(media_message) ==
97 {:ok,
98 media_message
99 |> put_in(["object", "tag"], ["foo", "nsfw"])
100 |> put_in(["object", "sensitive"], true)}
101
102 assert SimplePolicy.filter(local_message) == {:ok, local_message}
103 end
104 end
105
106 defp build_media_message do
107 %{
108 "actor" => "https://remote.instance/users/bob",
109 "type" => "Create",
110 "object" => %{
111 "attachment" => [%{}],
112 "tag" => ["foo"],
113 "sensitive" => false
114 }
115 }
116 end
117
118 describe "when :report_removal" do
119 test "is empty" do
120 Config.put([:mrf_simple, :report_removal], [])
121 report_message = build_report_message()
122 local_message = build_local_message()
123
124 assert SimplePolicy.filter(report_message) == {:ok, report_message}
125 assert SimplePolicy.filter(local_message) == {:ok, local_message}
126 end
127
128 test "has a matching host" do
129 Config.put([:mrf_simple, :report_removal], ["remote.instance"])
130 report_message = build_report_message()
131 local_message = build_local_message()
132
133 assert SimplePolicy.filter(report_message) == {:reject, nil}
134 assert SimplePolicy.filter(local_message) == {:ok, local_message}
135 end
136
137 test "match with wildcard domain" do
138 Config.put([:mrf_simple, :report_removal], ["*.remote.instance"])
139 report_message = build_report_message()
140 local_message = build_local_message()
141
142 assert SimplePolicy.filter(report_message) == {:reject, nil}
143 assert SimplePolicy.filter(local_message) == {:ok, local_message}
144 end
145 end
146
147 defp build_report_message do
148 %{
149 "actor" => "https://remote.instance/users/bob",
150 "type" => "Flag"
151 }
152 end
153
154 describe "when :federated_timeline_removal" do
155 test "is empty" do
156 Config.put([:mrf_simple, :federated_timeline_removal], [])
157 {_, ftl_message} = build_ftl_actor_and_message()
158 local_message = build_local_message()
159
160 assert SimplePolicy.filter(ftl_message) == {:ok, ftl_message}
161 assert SimplePolicy.filter(local_message) == {:ok, local_message}
162 end
163
164 test "has a matching host" do
165 {actor, ftl_message} = build_ftl_actor_and_message()
166
167 ftl_message_actor_host =
168 ftl_message
169 |> Map.fetch!("actor")
170 |> URI.parse()
171 |> Map.fetch!(:host)
172
173 Config.put([:mrf_simple, :federated_timeline_removal], [ftl_message_actor_host])
174 local_message = build_local_message()
175
176 assert {:ok, ftl_message} = SimplePolicy.filter(ftl_message)
177 assert actor.follower_address in ftl_message["to"]
178 refute actor.follower_address in ftl_message["cc"]
179 refute "https://www.w3.org/ns/activitystreams#Public" in ftl_message["to"]
180 assert "https://www.w3.org/ns/activitystreams#Public" in ftl_message["cc"]
181
182 assert SimplePolicy.filter(local_message) == {:ok, local_message}
183 end
184
185 test "match with wildcard domain" do
186 {actor, ftl_message} = build_ftl_actor_and_message()
187
188 ftl_message_actor_host =
189 ftl_message
190 |> Map.fetch!("actor")
191 |> URI.parse()
192 |> Map.fetch!(:host)
193
194 Config.put([:mrf_simple, :federated_timeline_removal], ["*." <> ftl_message_actor_host])
195 local_message = build_local_message()
196
197 assert {:ok, ftl_message} = SimplePolicy.filter(ftl_message)
198 assert actor.follower_address in ftl_message["to"]
199 refute actor.follower_address in ftl_message["cc"]
200 refute "https://www.w3.org/ns/activitystreams#Public" in ftl_message["to"]
201 assert "https://www.w3.org/ns/activitystreams#Public" in ftl_message["cc"]
202
203 assert SimplePolicy.filter(local_message) == {:ok, local_message}
204 end
205
206 test "has a matching host but only as:Public in to" do
207 {_actor, ftl_message} = build_ftl_actor_and_message()
208
209 ftl_message_actor_host =
210 ftl_message
211 |> Map.fetch!("actor")
212 |> URI.parse()
213 |> Map.fetch!(:host)
214
215 ftl_message = Map.put(ftl_message, "cc", [])
216
217 Config.put([:mrf_simple, :federated_timeline_removal], [ftl_message_actor_host])
218
219 assert {:ok, ftl_message} = SimplePolicy.filter(ftl_message)
220 refute "https://www.w3.org/ns/activitystreams#Public" in ftl_message["to"]
221 assert "https://www.w3.org/ns/activitystreams#Public" in ftl_message["cc"]
222 end
223 end
224
225 defp build_ftl_actor_and_message do
226 actor = insert(:user)
227
228 {actor,
229 %{
230 "actor" => actor.ap_id,
231 "to" => ["https://www.w3.org/ns/activitystreams#Public", "http://foo.bar/baz"],
232 "cc" => [actor.follower_address, "http://foo.bar/qux"]
233 }}
234 end
235
236 describe "when :reject" do
237 test "is empty" do
238 Config.put([:mrf_simple, :reject], [])
239
240 remote_message = build_remote_message()
241
242 assert SimplePolicy.filter(remote_message) == {:ok, remote_message}
243 end
244
245 test "has a matching host" do
246 Config.put([:mrf_simple, :reject], ["remote.instance"])
247
248 remote_message = build_remote_message()
249
250 assert SimplePolicy.filter(remote_message) == {:reject, nil}
251 end
252
253 test "match with wildcard domain" do
254 Config.put([:mrf_simple, :reject], ["*.remote.instance"])
255
256 remote_message = build_remote_message()
257
258 assert SimplePolicy.filter(remote_message) == {:reject, nil}
259 end
260 end
261
262 describe "when :accept" do
263 test "is empty" do
264 Config.put([:mrf_simple, :accept], [])
265
266 local_message = build_local_message()
267 remote_message = build_remote_message()
268
269 assert SimplePolicy.filter(local_message) == {:ok, local_message}
270 assert SimplePolicy.filter(remote_message) == {:ok, remote_message}
271 end
272
273 test "is not empty but it doesn't have a matching host" do
274 Config.put([:mrf_simple, :accept], ["non.matching.remote"])
275
276 local_message = build_local_message()
277 remote_message = build_remote_message()
278
279 assert SimplePolicy.filter(local_message) == {:ok, local_message}
280 assert SimplePolicy.filter(remote_message) == {:reject, nil}
281 end
282
283 test "has a matching host" do
284 Config.put([:mrf_simple, :accept], ["remote.instance"])
285
286 local_message = build_local_message()
287 remote_message = build_remote_message()
288
289 assert SimplePolicy.filter(local_message) == {:ok, local_message}
290 assert SimplePolicy.filter(remote_message) == {:ok, remote_message}
291 end
292
293 test "match with wildcard domain" do
294 Config.put([:mrf_simple, :accept], ["*.remote.instance"])
295
296 local_message = build_local_message()
297 remote_message = build_remote_message()
298
299 assert SimplePolicy.filter(local_message) == {:ok, local_message}
300 assert SimplePolicy.filter(remote_message) == {:ok, remote_message}
301 end
302 end
303
304 describe "when :avatar_removal" do
305 test "is empty" do
306 Config.put([:mrf_simple, :avatar_removal], [])
307
308 remote_user = build_remote_user()
309
310 assert SimplePolicy.filter(remote_user) == {:ok, remote_user}
311 end
312
313 test "is not empty but it doesn't have a matching host" do
314 Config.put([:mrf_simple, :avatar_removal], ["non.matching.remote"])
315
316 remote_user = build_remote_user()
317
318 assert SimplePolicy.filter(remote_user) == {:ok, remote_user}
319 end
320
321 test "has a matching host" do
322 Config.put([:mrf_simple, :avatar_removal], ["remote.instance"])
323
324 remote_user = build_remote_user()
325 {:ok, filtered} = SimplePolicy.filter(remote_user)
326
327 refute filtered["icon"]
328 end
329
330 test "match with wildcard domain" do
331 Config.put([:mrf_simple, :avatar_removal], ["*.remote.instance"])
332
333 remote_user = build_remote_user()
334 {:ok, filtered} = SimplePolicy.filter(remote_user)
335
336 refute filtered["icon"]
337 end
338 end
339
340 describe "when :banner_removal" do
341 test "is empty" do
342 Config.put([:mrf_simple, :banner_removal], [])
343
344 remote_user = build_remote_user()
345
346 assert SimplePolicy.filter(remote_user) == {:ok, remote_user}
347 end
348
349 test "is not empty but it doesn't have a matching host" do
350 Config.put([:mrf_simple, :banner_removal], ["non.matching.remote"])
351
352 remote_user = build_remote_user()
353
354 assert SimplePolicy.filter(remote_user) == {:ok, remote_user}
355 end
356
357 test "has a matching host" do
358 Config.put([:mrf_simple, :banner_removal], ["remote.instance"])
359
360 remote_user = build_remote_user()
361 {:ok, filtered} = SimplePolicy.filter(remote_user)
362
363 refute filtered["image"]
364 end
365
366 test "match with wildcard domain" do
367 Config.put([:mrf_simple, :banner_removal], ["*.remote.instance"])
368
369 remote_user = build_remote_user()
370 {:ok, filtered} = SimplePolicy.filter(remote_user)
371
372 refute filtered["image"]
373 end
374 end
375
376 defp build_local_message do
377 %{
378 "actor" => "#{Pleroma.Web.base_url()}/users/alice",
379 "to" => [],
380 "cc" => []
381 }
382 end
383
384 defp build_remote_message do
385 %{"actor" => "https://remote.instance/users/bob"}
386 end
387
388 defp build_remote_user do
389 %{
390 "id" => "https://remote.instance/users/bob",
391 "icon" => %{
392 "url" => "http://example.com/image.jpg",
393 "type" => "Image"
394 },
395 "image" => %{
396 "url" => "http://example.com/image.jpg",
397 "type" => "Image"
398 },
399 "type" => "Person"
400 }
401 end
402 end