Fix MRF policies to also work with Update
[akkoma] / test / pleroma / web / activity_pub / mrf / anti_link_spam_policy_test.exs
1 # Pleroma: A lightweight social networking server
2 # Copyright © 2017-2021 Pleroma Authors <https://pleroma.social/>
3 # SPDX-License-Identifier: AGPL-3.0-only
4
5 defmodule Pleroma.Web.ActivityPub.MRF.AntiLinkSpamPolicyTest do
6 use Pleroma.DataCase
7 import Pleroma.Factory
8 import ExUnit.CaptureLog
9
10 alias Pleroma.Web.ActivityPub.MRF
11 alias Pleroma.Web.ActivityPub.MRF.AntiLinkSpamPolicy
12
13 @linkless_message %{
14 "type" => "Create",
15 "object" => %{
16 "content" => "hi world!"
17 }
18 }
19
20 @linkful_message %{
21 "type" => "Create",
22 "object" => %{
23 "content" => "<a href='https://example.com'>hi world!</a>"
24 }
25 }
26
27 @response_message %{
28 "type" => "Create",
29 "object" => %{
30 "name" => "yes",
31 "type" => "Answer"
32 }
33 }
34
35 @linkless_update_message %{
36 "type" => "Update",
37 "object" => %{
38 "content" => "hi world!"
39 }
40 }
41
42 @linkful_update_message %{
43 "type" => "Update",
44 "object" => %{
45 "content" => "<a href='https://example.com'>hi world!</a>"
46 }
47 }
48
49 @response_update_message %{
50 "type" => "Update",
51 "object" => %{
52 "name" => "yes",
53 "type" => "Answer"
54 }
55 }
56
57 describe "with new user" do
58 test "it allows posts without links" do
59 user = insert(:user, local: false)
60
61 assert user.note_count == 0
62
63 message =
64 @linkless_message
65 |> Map.put("actor", user.ap_id)
66
67 update_message =
68 @linkless_update_message
69 |> Map.put("actor", user.ap_id)
70
71 {:ok, _message} = AntiLinkSpamPolicy.filter(message)
72 {:ok, _update_message} = AntiLinkSpamPolicy.filter(update_message)
73 end
74
75 test "it disallows posts with links" do
76 user = insert(:user, local: false)
77
78 assert user.note_count == 0
79
80 message = %{
81 "type" => "Create",
82 "actor" => user.ap_id,
83 "object" => %{
84 "formerRepresentations" => %{
85 "type" => "OrderedCollection",
86 "orderedItems" => [
87 %{
88 "content" => "<a href='https://example.com'>hi world!</a>"
89 }
90 ]
91 },
92 "content" => "mew"
93 }
94 }
95
96 update_message = %{
97 "type" => "Update",
98 "actor" => user.ap_id,
99 "object" => %{
100 "formerRepresentations" => %{
101 "type" => "OrderedCollection",
102 "orderedItems" => [
103 %{
104 "content" => "<a href='https://example.com'>hi world!</a>"
105 }
106 ]
107 },
108 "content" => "mew"
109 }
110 }
111
112 {:reject, _} = MRF.filter_one(AntiLinkSpamPolicy, message)
113 {:reject, _} = MRF.filter_one(AntiLinkSpamPolicy, update_message)
114 end
115
116 test "it allows posts with links for local users" do
117 user = insert(:user)
118
119 assert user.note_count == 0
120
121 message =
122 @linkful_message
123 |> Map.put("actor", user.ap_id)
124
125 update_message =
126 @linkful_update_message
127 |> Map.put("actor", user.ap_id)
128
129 {:ok, _message} = AntiLinkSpamPolicy.filter(message)
130 {:ok, _update_message} = AntiLinkSpamPolicy.filter(update_message)
131 end
132
133 test "it disallows posts with links in history" do
134 user = insert(:user, local: false)
135
136 assert user.note_count == 0
137
138 message =
139 @linkful_message
140 |> Map.put("actor", user.ap_id)
141
142 update_message =
143 @linkful_update_message
144 |> Map.put("actor", user.ap_id)
145
146 {:reject, _} = AntiLinkSpamPolicy.filter(message)
147 {:reject, _} = AntiLinkSpamPolicy.filter(update_message)
148 end
149 end
150
151 describe "with old user" do
152 test "it allows posts without links" do
153 user = insert(:user, note_count: 1)
154
155 assert user.note_count == 1
156
157 message =
158 @linkless_message
159 |> Map.put("actor", user.ap_id)
160
161 update_message =
162 @linkless_update_message
163 |> Map.put("actor", user.ap_id)
164
165 {:ok, _message} = AntiLinkSpamPolicy.filter(message)
166 {:ok, _update_message} = AntiLinkSpamPolicy.filter(update_message)
167 end
168
169 test "it allows posts with links" do
170 user = insert(:user, note_count: 1)
171
172 assert user.note_count == 1
173
174 message =
175 @linkful_message
176 |> Map.put("actor", user.ap_id)
177
178 update_message =
179 @linkful_update_message
180 |> Map.put("actor", user.ap_id)
181
182 {:ok, _message} = AntiLinkSpamPolicy.filter(message)
183 {:ok, _update_message} = AntiLinkSpamPolicy.filter(update_message)
184 end
185 end
186
187 describe "with followed new user" do
188 test "it allows posts without links" do
189 user = insert(:user, follower_count: 1)
190
191 assert user.follower_count == 1
192
193 message =
194 @linkless_message
195 |> Map.put("actor", user.ap_id)
196
197 update_message =
198 @linkless_update_message
199 |> Map.put("actor", user.ap_id)
200
201 {:ok, _message} = AntiLinkSpamPolicy.filter(message)
202 {:ok, _update_message} = AntiLinkSpamPolicy.filter(update_message)
203 end
204
205 test "it allows posts with links" do
206 user = insert(:user, follower_count: 1)
207
208 assert user.follower_count == 1
209
210 message =
211 @linkful_message
212 |> Map.put("actor", user.ap_id)
213
214 update_message =
215 @linkful_update_message
216 |> Map.put("actor", user.ap_id)
217
218 {:ok, _message} = AntiLinkSpamPolicy.filter(message)
219 {:ok, _update_message} = AntiLinkSpamPolicy.filter(update_message)
220 end
221 end
222
223 describe "with unknown actors" do
224 setup do
225 Tesla.Mock.mock(fn
226 %{method: :get, url: "http://invalid.actor"} ->
227 %Tesla.Env{status: 500, body: ""}
228 end)
229
230 :ok
231 end
232
233 test "it rejects posts without links" do
234 message =
235 @linkless_message
236 |> Map.put("actor", "http://invalid.actor")
237
238 update_message =
239 @linkless_update_message
240 |> Map.put("actor", "http://invalid.actor")
241
242 assert capture_log(fn ->
243 {:reject, _} = AntiLinkSpamPolicy.filter(message)
244 end) =~ "[error] Could not decode user at fetch http://invalid.actor"
245
246 assert capture_log(fn ->
247 {:reject, _} = AntiLinkSpamPolicy.filter(update_message)
248 end) =~ "[error] Could not decode user at fetch http://invalid.actor"
249 end
250
251 test "it rejects posts with links" do
252 message =
253 @linkful_message
254 |> Map.put("actor", "http://invalid.actor")
255
256 update_message =
257 @linkful_update_message
258 |> Map.put("actor", "http://invalid.actor")
259
260 assert capture_log(fn ->
261 {:reject, _} = AntiLinkSpamPolicy.filter(message)
262 end) =~ "[error] Could not decode user at fetch http://invalid.actor"
263
264 assert capture_log(fn ->
265 {:reject, _} = AntiLinkSpamPolicy.filter(update_message)
266 end) =~ "[error] Could not decode user at fetch http://invalid.actor"
267 end
268 end
269
270 describe "with contentless-objects" do
271 test "it does not reject them or error out" do
272 user = insert(:user, note_count: 1)
273
274 message =
275 @response_message
276 |> Map.put("actor", user.ap_id)
277
278 update_message =
279 @response_update_message
280 |> Map.put("actor", user.ap_id)
281
282 {:ok, _message} = AntiLinkSpamPolicy.filter(message)
283 {:ok, _update_message} = AntiLinkSpamPolicy.filter(update_message)
284 end
285 end
286 end