Merge branch '1149-oban-job-queue' into 'develop'
[akkoma] / lib / pleroma / moderation_log.ex
1 defmodule Pleroma.ModerationLog do
2 use Ecto.Schema
3
4 alias Pleroma.Activity
5 alias Pleroma.ModerationLog
6 alias Pleroma.Repo
7 alias Pleroma.User
8
9 import Ecto.Query
10
11 schema "moderation_log" do
12 field(:data, :map)
13
14 timestamps()
15 end
16
17 def get_all(page, page_size) do
18 from(q in __MODULE__,
19 order_by: [desc: q.inserted_at],
20 limit: ^page_size,
21 offset: ^((page - 1) * page_size)
22 )
23 |> Repo.all()
24 end
25
26 def insert_log(%{
27 actor: %User{} = actor,
28 subject: %User{} = subject,
29 action: action,
30 permission: permission
31 }) do
32 Repo.insert(%ModerationLog{
33 data: %{
34 actor: user_to_map(actor),
35 subject: user_to_map(subject),
36 action: action,
37 permission: permission
38 }
39 })
40 end
41
42 def insert_log(%{
43 actor: %User{} = actor,
44 action: "report_update",
45 subject: %Activity{data: %{"type" => "Flag"}} = subject
46 }) do
47 Repo.insert(%ModerationLog{
48 data: %{
49 actor: user_to_map(actor),
50 action: "report_update",
51 subject: report_to_map(subject)
52 }
53 })
54 end
55
56 def insert_log(%{
57 actor: %User{} = actor,
58 action: "report_response",
59 subject: %Activity{} = subject,
60 text: text
61 }) do
62 Repo.insert(%ModerationLog{
63 data: %{
64 actor: user_to_map(actor),
65 action: "report_response",
66 subject: report_to_map(subject),
67 text: text
68 }
69 })
70 end
71
72 def insert_log(%{
73 actor: %User{} = actor,
74 action: "status_update",
75 subject: %Activity{} = subject,
76 sensitive: sensitive,
77 visibility: visibility
78 }) do
79 Repo.insert(%ModerationLog{
80 data: %{
81 actor: user_to_map(actor),
82 action: "status_update",
83 subject: status_to_map(subject),
84 sensitive: sensitive,
85 visibility: visibility
86 }
87 })
88 end
89
90 def insert_log(%{
91 actor: %User{} = actor,
92 action: "status_delete",
93 subject_id: subject_id
94 }) do
95 Repo.insert(%ModerationLog{
96 data: %{
97 actor: user_to_map(actor),
98 action: "status_delete",
99 subject_id: subject_id
100 }
101 })
102 end
103
104 @spec insert_log(%{actor: User, subject: User, action: String.t()}) ::
105 {:ok, ModerationLog} | {:error, any}
106 def insert_log(%{actor: %User{} = actor, subject: subject, action: action}) do
107 Repo.insert(%ModerationLog{
108 data: %{
109 actor: user_to_map(actor),
110 action: action,
111 subject: user_to_map(subject)
112 }
113 })
114 end
115
116 @spec insert_log(%{actor: User, subjects: [User], action: String.t()}) ::
117 {:ok, ModerationLog} | {:error, any}
118 def insert_log(%{actor: %User{} = actor, subjects: subjects, action: action}) do
119 subjects = Enum.map(subjects, &user_to_map/1)
120
121 Repo.insert(%ModerationLog{
122 data: %{
123 actor: user_to_map(actor),
124 action: action,
125 subjects: subjects
126 }
127 })
128 end
129
130 def insert_log(%{
131 actor: %User{} = actor,
132 followed: %User{} = followed,
133 follower: %User{} = follower,
134 action: "follow"
135 }) do
136 Repo.insert(%ModerationLog{
137 data: %{
138 actor: user_to_map(actor),
139 action: "follow",
140 followed: user_to_map(followed),
141 follower: user_to_map(follower)
142 }
143 })
144 end
145
146 def insert_log(%{
147 actor: %User{} = actor,
148 followed: %User{} = followed,
149 follower: %User{} = follower,
150 action: "unfollow"
151 }) do
152 Repo.insert(%ModerationLog{
153 data: %{
154 actor: user_to_map(actor),
155 action: "unfollow",
156 followed: user_to_map(followed),
157 follower: user_to_map(follower)
158 }
159 })
160 end
161
162 def insert_log(%{
163 actor: %User{} = actor,
164 nicknames: nicknames,
165 tags: tags,
166 action: action
167 }) do
168 Repo.insert(%ModerationLog{
169 data: %{
170 actor: user_to_map(actor),
171 nicknames: nicknames,
172 tags: tags,
173 action: action
174 }
175 })
176 end
177
178 def insert_log(%{
179 actor: %User{} = actor,
180 action: action,
181 target: target
182 })
183 when action in ["relay_follow", "relay_unfollow"] do
184 Repo.insert(%ModerationLog{
185 data: %{
186 actor: user_to_map(actor),
187 action: action,
188 target: target
189 }
190 })
191 end
192
193 defp user_to_map(%User{} = user) do
194 user
195 |> Map.from_struct()
196 |> Map.take([:id, :nickname])
197 |> Map.put(:type, "user")
198 end
199
200 defp report_to_map(%Activity{} = report) do
201 %{
202 type: "report",
203 id: report.id,
204 state: report.data["state"]
205 }
206 end
207
208 defp status_to_map(%Activity{} = status) do
209 %{
210 type: "status",
211 id: status.id
212 }
213 end
214
215 def get_log_entry_message(%ModerationLog{
216 data: %{
217 "actor" => %{"nickname" => actor_nickname},
218 "action" => action,
219 "followed" => %{"nickname" => followed_nickname},
220 "follower" => %{"nickname" => follower_nickname}
221 }
222 }) do
223 "@#{actor_nickname} made @#{follower_nickname} #{action} @#{followed_nickname}"
224 end
225
226 @spec get_log_entry_message(ModerationLog) :: String.t()
227 def get_log_entry_message(%ModerationLog{
228 data: %{
229 "actor" => %{"nickname" => actor_nickname},
230 "action" => "delete",
231 "subject" => %{"nickname" => subject_nickname, "type" => "user"}
232 }
233 }) do
234 "@#{actor_nickname} deleted user @#{subject_nickname}"
235 end
236
237 @spec get_log_entry_message(ModerationLog) :: String.t()
238 def get_log_entry_message(%ModerationLog{
239 data: %{
240 "actor" => %{"nickname" => actor_nickname},
241 "action" => "create",
242 "subjects" => subjects
243 }
244 }) do
245 nicknames =
246 subjects
247 |> Enum.map(&"@#{&1["nickname"]}")
248 |> Enum.join(", ")
249
250 "@#{actor_nickname} created users: #{nicknames}"
251 end
252
253 @spec get_log_entry_message(ModerationLog) :: String.t()
254 def get_log_entry_message(%ModerationLog{
255 data: %{
256 "actor" => %{"nickname" => actor_nickname},
257 "action" => "activate",
258 "subject" => %{"nickname" => subject_nickname, "type" => "user"}
259 }
260 }) do
261 "@#{actor_nickname} activated user @#{subject_nickname}"
262 end
263
264 @spec get_log_entry_message(ModerationLog) :: String.t()
265 def get_log_entry_message(%ModerationLog{
266 data: %{
267 "actor" => %{"nickname" => actor_nickname},
268 "action" => "deactivate",
269 "subject" => %{"nickname" => subject_nickname, "type" => "user"}
270 }
271 }) do
272 "@#{actor_nickname} deactivated user @#{subject_nickname}"
273 end
274
275 @spec get_log_entry_message(ModerationLog) :: String.t()
276 def get_log_entry_message(%ModerationLog{
277 data: %{
278 "actor" => %{"nickname" => actor_nickname},
279 "nicknames" => nicknames,
280 "tags" => tags,
281 "action" => "tag"
282 }
283 }) do
284 nicknames_string =
285 nicknames
286 |> Enum.map(&"@#{&1}")
287 |> Enum.join(", ")
288
289 tags_string = tags |> Enum.join(", ")
290
291 "@#{actor_nickname} added tags: #{tags_string} to users: #{nicknames_string}"
292 end
293
294 @spec get_log_entry_message(ModerationLog) :: String.t()
295 def get_log_entry_message(%ModerationLog{
296 data: %{
297 "actor" => %{"nickname" => actor_nickname},
298 "nicknames" => nicknames,
299 "tags" => tags,
300 "action" => "untag"
301 }
302 }) do
303 nicknames_string =
304 nicknames
305 |> Enum.map(&"@#{&1}")
306 |> Enum.join(", ")
307
308 tags_string = tags |> Enum.join(", ")
309
310 "@#{actor_nickname} removed tags: #{tags_string} from users: #{nicknames_string}"
311 end
312
313 @spec get_log_entry_message(ModerationLog) :: String.t()
314 def get_log_entry_message(%ModerationLog{
315 data: %{
316 "actor" => %{"nickname" => actor_nickname},
317 "action" => "grant",
318 "subject" => %{"nickname" => subject_nickname},
319 "permission" => permission
320 }
321 }) do
322 "@#{actor_nickname} made @#{subject_nickname} #{permission}"
323 end
324
325 @spec get_log_entry_message(ModerationLog) :: String.t()
326 def get_log_entry_message(%ModerationLog{
327 data: %{
328 "actor" => %{"nickname" => actor_nickname},
329 "action" => "revoke",
330 "subject" => %{"nickname" => subject_nickname},
331 "permission" => permission
332 }
333 }) do
334 "@#{actor_nickname} revoked #{permission} role from @#{subject_nickname}"
335 end
336
337 @spec get_log_entry_message(ModerationLog) :: String.t()
338 def get_log_entry_message(%ModerationLog{
339 data: %{
340 "actor" => %{"nickname" => actor_nickname},
341 "action" => "relay_follow",
342 "target" => target
343 }
344 }) do
345 "@#{actor_nickname} followed relay: #{target}"
346 end
347
348 @spec get_log_entry_message(ModerationLog) :: String.t()
349 def get_log_entry_message(%ModerationLog{
350 data: %{
351 "actor" => %{"nickname" => actor_nickname},
352 "action" => "relay_unfollow",
353 "target" => target
354 }
355 }) do
356 "@#{actor_nickname} unfollowed relay: #{target}"
357 end
358
359 @spec get_log_entry_message(ModerationLog) :: String.t()
360 def get_log_entry_message(%ModerationLog{
361 data: %{
362 "actor" => %{"nickname" => actor_nickname},
363 "action" => "report_update",
364 "subject" => %{"id" => subject_id, "state" => state, "type" => "report"}
365 }
366 }) do
367 "@#{actor_nickname} updated report ##{subject_id} with '#{state}' state"
368 end
369
370 @spec get_log_entry_message(ModerationLog) :: String.t()
371 def get_log_entry_message(%ModerationLog{
372 data: %{
373 "actor" => %{"nickname" => actor_nickname},
374 "action" => "report_response",
375 "subject" => %{"id" => subject_id, "type" => "report"},
376 "text" => text
377 }
378 }) do
379 "@#{actor_nickname} responded with '#{text}' to report ##{subject_id}"
380 end
381
382 @spec get_log_entry_message(ModerationLog) :: String.t()
383 def get_log_entry_message(%ModerationLog{
384 data: %{
385 "actor" => %{"nickname" => actor_nickname},
386 "action" => "status_update",
387 "subject" => %{"id" => subject_id, "type" => "status"},
388 "sensitive" => nil,
389 "visibility" => visibility
390 }
391 }) do
392 "@#{actor_nickname} updated status ##{subject_id}, set visibility: '#{visibility}'"
393 end
394
395 @spec get_log_entry_message(ModerationLog) :: String.t()
396 def get_log_entry_message(%ModerationLog{
397 data: %{
398 "actor" => %{"nickname" => actor_nickname},
399 "action" => "status_update",
400 "subject" => %{"id" => subject_id, "type" => "status"},
401 "sensitive" => sensitive,
402 "visibility" => nil
403 }
404 }) do
405 "@#{actor_nickname} updated status ##{subject_id}, set sensitive: '#{sensitive}'"
406 end
407
408 @spec get_log_entry_message(ModerationLog) :: String.t()
409 def get_log_entry_message(%ModerationLog{
410 data: %{
411 "actor" => %{"nickname" => actor_nickname},
412 "action" => "status_update",
413 "subject" => %{"id" => subject_id, "type" => "status"},
414 "sensitive" => sensitive,
415 "visibility" => visibility
416 }
417 }) do
418 "@#{actor_nickname} updated status ##{subject_id}, set sensitive: '#{sensitive}', visibility: '#{
419 visibility
420 }'"
421 end
422
423 @spec get_log_entry_message(ModerationLog) :: String.t()
424 def get_log_entry_message(%ModerationLog{
425 data: %{
426 "actor" => %{"nickname" => actor_nickname},
427 "action" => "status_delete",
428 "subject_id" => subject_id
429 }
430 }) do
431 "@#{actor_nickname} deleted status ##{subject_id}"
432 end
433 end