cec3570ebfa1bd4253af035127dd759434de4cf4
[akkoma] / test / web / admin_api / admin_api_controller_test.exs
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.AdminAPI.AdminAPIControllerTest do
6 use Pleroma.Web.ConnCase
7 use Oban.Testing, repo: Pleroma.Repo
8
9 alias Pleroma.Activity
10 alias Pleroma.HTML
11 alias Pleroma.ModerationLog
12 alias Pleroma.Repo
13 alias Pleroma.Tests.ObanHelpers
14 alias Pleroma.User
15 alias Pleroma.UserInviteToken
16 alias Pleroma.Web.CommonAPI
17 alias Pleroma.Web.MediaProxy
18 import Pleroma.Factory
19
20 describe "/api/pleroma/admin/users" do
21 test "Delete" do
22 admin = insert(:user, info: %{is_admin: true})
23 user = insert(:user)
24
25 conn =
26 build_conn()
27 |> assign(:user, admin)
28 |> put_req_header("accept", "application/json")
29 |> delete("/api/pleroma/admin/users?nickname=#{user.nickname}")
30
31 log_entry = Repo.one(ModerationLog)
32
33 assert log_entry.data["subject"]["nickname"] == user.nickname
34 assert log_entry.data["action"] == "delete"
35
36 assert ModerationLog.get_log_entry_message(log_entry) ==
37 "@#{admin.nickname} deleted user @#{user.nickname}"
38
39 assert json_response(conn, 200) == user.nickname
40 end
41
42 test "Create" do
43 admin = insert(:user, info: %{is_admin: true})
44
45 conn =
46 build_conn()
47 |> assign(:user, admin)
48 |> put_req_header("accept", "application/json")
49 |> post("/api/pleroma/admin/users", %{
50 "users" => [
51 %{
52 "nickname" => "lain",
53 "email" => "lain@example.org",
54 "password" => "test"
55 },
56 %{
57 "nickname" => "lain2",
58 "email" => "lain2@example.org",
59 "password" => "test"
60 }
61 ]
62 })
63
64 response = json_response(conn, 200) |> Enum.map(&Map.get(&1, "type"))
65 assert response == ["success", "success"]
66
67 log_entry = Repo.one(ModerationLog)
68
69 assert ["lain", "lain2"] -- Enum.map(log_entry.data["subjects"], & &1["nickname"]) == []
70 end
71
72 test "Cannot create user with exisiting email" do
73 admin = insert(:user, info: %{is_admin: true})
74 user = insert(:user)
75
76 conn =
77 build_conn()
78 |> assign(:user, admin)
79 |> put_req_header("accept", "application/json")
80 |> post("/api/pleroma/admin/users", %{
81 "users" => [
82 %{
83 "nickname" => "lain",
84 "email" => user.email,
85 "password" => "test"
86 }
87 ]
88 })
89
90 assert json_response(conn, 409) == [
91 %{
92 "code" => 409,
93 "data" => %{
94 "email" => user.email,
95 "nickname" => "lain"
96 },
97 "error" => "email has already been taken",
98 "type" => "error"
99 }
100 ]
101 end
102
103 test "Cannot create user with exisiting nickname" do
104 admin = insert(:user, info: %{is_admin: true})
105 user = insert(:user)
106
107 conn =
108 build_conn()
109 |> assign(:user, admin)
110 |> put_req_header("accept", "application/json")
111 |> post("/api/pleroma/admin/users", %{
112 "users" => [
113 %{
114 "nickname" => user.nickname,
115 "email" => "someuser@plerama.social",
116 "password" => "test"
117 }
118 ]
119 })
120
121 assert json_response(conn, 409) == [
122 %{
123 "code" => 409,
124 "data" => %{
125 "email" => "someuser@plerama.social",
126 "nickname" => user.nickname
127 },
128 "error" => "nickname has already been taken",
129 "type" => "error"
130 }
131 ]
132 end
133
134 test "Multiple user creation works in transaction" do
135 admin = insert(:user, info: %{is_admin: true})
136 user = insert(:user)
137
138 conn =
139 build_conn()
140 |> assign(:user, admin)
141 |> put_req_header("accept", "application/json")
142 |> post("/api/pleroma/admin/users", %{
143 "users" => [
144 %{
145 "nickname" => "newuser",
146 "email" => "newuser@pleroma.social",
147 "password" => "test"
148 },
149 %{
150 "nickname" => "lain",
151 "email" => user.email,
152 "password" => "test"
153 }
154 ]
155 })
156
157 assert json_response(conn, 409) == [
158 %{
159 "code" => 409,
160 "data" => %{
161 "email" => user.email,
162 "nickname" => "lain"
163 },
164 "error" => "email has already been taken",
165 "type" => "error"
166 },
167 %{
168 "code" => 409,
169 "data" => %{
170 "email" => "newuser@pleroma.social",
171 "nickname" => "newuser"
172 },
173 "error" => "",
174 "type" => "error"
175 }
176 ]
177
178 assert User.get_by_nickname("newuser") === nil
179 end
180 end
181
182 describe "/api/pleroma/admin/users/:nickname" do
183 test "Show", %{conn: conn} do
184 admin = insert(:user, info: %{is_admin: true})
185 user = insert(:user)
186
187 conn =
188 conn
189 |> assign(:user, admin)
190 |> get("/api/pleroma/admin/users/#{user.nickname}")
191
192 expected = %{
193 "deactivated" => false,
194 "id" => to_string(user.id),
195 "local" => true,
196 "nickname" => user.nickname,
197 "roles" => %{"admin" => false, "moderator" => false},
198 "tags" => [],
199 "avatar" => User.avatar_url(user) |> MediaProxy.url(),
200 "display_name" => HTML.strip_tags(user.name || user.nickname)
201 }
202
203 assert expected == json_response(conn, 200)
204 end
205
206 test "when the user doesn't exist", %{conn: conn} do
207 admin = insert(:user, info: %{is_admin: true})
208 user = build(:user)
209
210 conn =
211 conn
212 |> assign(:user, admin)
213 |> get("/api/pleroma/admin/users/#{user.nickname}")
214
215 assert "Not found" == json_response(conn, 404)
216 end
217 end
218
219 describe "/api/pleroma/admin/users/follow" do
220 test "allows to force-follow another user" do
221 admin = insert(:user, info: %{is_admin: true})
222 user = insert(:user)
223 follower = insert(:user)
224
225 build_conn()
226 |> assign(:user, admin)
227 |> put_req_header("accept", "application/json")
228 |> post("/api/pleroma/admin/users/follow", %{
229 "follower" => follower.nickname,
230 "followed" => user.nickname
231 })
232
233 user = User.get_cached_by_id(user.id)
234 follower = User.get_cached_by_id(follower.id)
235
236 assert User.following?(follower, user)
237
238 log_entry = Repo.one(ModerationLog)
239
240 assert ModerationLog.get_log_entry_message(log_entry) ==
241 "@#{admin.nickname} made @#{follower.nickname} follow @#{user.nickname}"
242 end
243 end
244
245 describe "/api/pleroma/admin/users/unfollow" do
246 test "allows to force-unfollow another user" do
247 admin = insert(:user, info: %{is_admin: true})
248 user = insert(:user)
249 follower = insert(:user)
250
251 User.follow(follower, user)
252
253 build_conn()
254 |> assign(:user, admin)
255 |> put_req_header("accept", "application/json")
256 |> post("/api/pleroma/admin/users/unfollow", %{
257 "follower" => follower.nickname,
258 "followed" => user.nickname
259 })
260
261 user = User.get_cached_by_id(user.id)
262 follower = User.get_cached_by_id(follower.id)
263
264 refute User.following?(follower, user)
265
266 log_entry = Repo.one(ModerationLog)
267
268 assert ModerationLog.get_log_entry_message(log_entry) ==
269 "@#{admin.nickname} made @#{follower.nickname} unfollow @#{user.nickname}"
270 end
271 end
272
273 describe "PUT /api/pleroma/admin/users/tag" do
274 setup do
275 admin = insert(:user, info: %{is_admin: true})
276 user1 = insert(:user, %{tags: ["x"]})
277 user2 = insert(:user, %{tags: ["y"]})
278 user3 = insert(:user, %{tags: ["unchanged"]})
279
280 conn =
281 build_conn()
282 |> assign(:user, admin)
283 |> put_req_header("accept", "application/json")
284 |> put(
285 "/api/pleroma/admin/users/tag?nicknames[]=#{user1.nickname}&nicknames[]=#{
286 user2.nickname
287 }&tags[]=foo&tags[]=bar"
288 )
289
290 %{conn: conn, admin: admin, user1: user1, user2: user2, user3: user3}
291 end
292
293 test "it appends specified tags to users with specified nicknames", %{
294 conn: conn,
295 admin: admin,
296 user1: user1,
297 user2: user2
298 } do
299 assert json_response(conn, :no_content)
300 assert User.get_cached_by_id(user1.id).tags == ["x", "foo", "bar"]
301 assert User.get_cached_by_id(user2.id).tags == ["y", "foo", "bar"]
302
303 log_entry = Repo.one(ModerationLog)
304
305 users =
306 [user1.nickname, user2.nickname]
307 |> Enum.map(&"@#{&1}")
308 |> Enum.join(", ")
309
310 tags = ["foo", "bar"] |> Enum.join(", ")
311
312 assert ModerationLog.get_log_entry_message(log_entry) ==
313 "@#{admin.nickname} added tags: #{tags} to users: #{users}"
314 end
315
316 test "it does not modify tags of not specified users", %{conn: conn, user3: user3} do
317 assert json_response(conn, :no_content)
318 assert User.get_cached_by_id(user3.id).tags == ["unchanged"]
319 end
320 end
321
322 describe "DELETE /api/pleroma/admin/users/tag" do
323 setup do
324 admin = insert(:user, info: %{is_admin: true})
325 user1 = insert(:user, %{tags: ["x"]})
326 user2 = insert(:user, %{tags: ["y", "z"]})
327 user3 = insert(:user, %{tags: ["unchanged"]})
328
329 conn =
330 build_conn()
331 |> assign(:user, admin)
332 |> put_req_header("accept", "application/json")
333 |> delete(
334 "/api/pleroma/admin/users/tag?nicknames[]=#{user1.nickname}&nicknames[]=#{
335 user2.nickname
336 }&tags[]=x&tags[]=z"
337 )
338
339 %{conn: conn, admin: admin, user1: user1, user2: user2, user3: user3}
340 end
341
342 test "it removes specified tags from users with specified nicknames", %{
343 conn: conn,
344 admin: admin,
345 user1: user1,
346 user2: user2
347 } do
348 assert json_response(conn, :no_content)
349 assert User.get_cached_by_id(user1.id).tags == []
350 assert User.get_cached_by_id(user2.id).tags == ["y"]
351
352 log_entry = Repo.one(ModerationLog)
353
354 users =
355 [user1.nickname, user2.nickname]
356 |> Enum.map(&"@#{&1}")
357 |> Enum.join(", ")
358
359 tags = ["x", "z"] |> Enum.join(", ")
360
361 assert ModerationLog.get_log_entry_message(log_entry) ==
362 "@#{admin.nickname} removed tags: #{tags} from users: #{users}"
363 end
364
365 test "it does not modify tags of not specified users", %{conn: conn, user3: user3} do
366 assert json_response(conn, :no_content)
367 assert User.get_cached_by_id(user3.id).tags == ["unchanged"]
368 end
369 end
370
371 describe "/api/pleroma/admin/users/:nickname/permission_group" do
372 test "GET is giving user_info" do
373 admin = insert(:user, info: %{is_admin: true})
374
375 conn =
376 build_conn()
377 |> assign(:user, admin)
378 |> put_req_header("accept", "application/json")
379 |> get("/api/pleroma/admin/users/#{admin.nickname}/permission_group/")
380
381 assert json_response(conn, 200) == %{
382 "is_admin" => true,
383 "is_moderator" => false
384 }
385 end
386
387 test "/:right POST, can add to a permission group" do
388 admin = insert(:user, info: %{is_admin: true})
389 user = insert(:user)
390
391 conn =
392 build_conn()
393 |> assign(:user, admin)
394 |> put_req_header("accept", "application/json")
395 |> post("/api/pleroma/admin/users/#{user.nickname}/permission_group/admin")
396
397 assert json_response(conn, 200) == %{
398 "is_admin" => true
399 }
400
401 log_entry = Repo.one(ModerationLog)
402
403 assert ModerationLog.get_log_entry_message(log_entry) ==
404 "@#{admin.nickname} made @#{user.nickname} admin"
405 end
406
407 test "/:right DELETE, can remove from a permission group" do
408 admin = insert(:user, info: %{is_admin: true})
409 user = insert(:user, info: %{is_admin: true})
410
411 conn =
412 build_conn()
413 |> assign(:user, admin)
414 |> put_req_header("accept", "application/json")
415 |> delete("/api/pleroma/admin/users/#{user.nickname}/permission_group/admin")
416
417 assert json_response(conn, 200) == %{
418 "is_admin" => false
419 }
420
421 log_entry = Repo.one(ModerationLog)
422
423 assert ModerationLog.get_log_entry_message(log_entry) ==
424 "@#{admin.nickname} revoked admin role from @#{user.nickname}"
425 end
426 end
427
428 describe "PUT /api/pleroma/admin/users/:nickname/activation_status" do
429 setup %{conn: conn} do
430 admin = insert(:user, info: %{is_admin: true})
431
432 conn =
433 conn
434 |> assign(:user, admin)
435 |> put_req_header("accept", "application/json")
436
437 %{conn: conn, admin: admin}
438 end
439
440 test "deactivates the user", %{conn: conn, admin: admin} do
441 user = insert(:user)
442
443 conn =
444 conn
445 |> put("/api/pleroma/admin/users/#{user.nickname}/activation_status", %{status: false})
446
447 user = User.get_cached_by_id(user.id)
448 assert user.info.deactivated == true
449 assert json_response(conn, :no_content)
450
451 log_entry = Repo.one(ModerationLog)
452
453 assert ModerationLog.get_log_entry_message(log_entry) ==
454 "@#{admin.nickname} deactivated user @#{user.nickname}"
455 end
456
457 test "activates the user", %{conn: conn, admin: admin} do
458 user = insert(:user, info: %{deactivated: true})
459
460 conn =
461 conn
462 |> put("/api/pleroma/admin/users/#{user.nickname}/activation_status", %{status: true})
463
464 user = User.get_cached_by_id(user.id)
465 assert user.info.deactivated == false
466 assert json_response(conn, :no_content)
467
468 log_entry = Repo.one(ModerationLog)
469
470 assert ModerationLog.get_log_entry_message(log_entry) ==
471 "@#{admin.nickname} activated user @#{user.nickname}"
472 end
473
474 test "returns 403 when requested by a non-admin", %{conn: conn} do
475 user = insert(:user)
476
477 conn =
478 conn
479 |> assign(:user, user)
480 |> put("/api/pleroma/admin/users/#{user.nickname}/activation_status", %{status: false})
481
482 assert json_response(conn, :forbidden)
483 end
484 end
485
486 describe "POST /api/pleroma/admin/email_invite, with valid config" do
487 setup do
488 [user: insert(:user, info: %{is_admin: true})]
489 end
490
491 clear_config([:instance, :registrations_open]) do
492 Pleroma.Config.put([:instance, :registrations_open], false)
493 end
494
495 clear_config([:instance, :invites_enabled]) do
496 Pleroma.Config.put([:instance, :invites_enabled], true)
497 end
498
499 test "sends invitation and returns 204", %{conn: conn, user: user} do
500 recipient_email = "foo@bar.com"
501 recipient_name = "J. D."
502
503 conn =
504 conn
505 |> assign(:user, user)
506 |> post(
507 "/api/pleroma/admin/users/email_invite?email=#{recipient_email}&name=#{recipient_name}"
508 )
509
510 assert json_response(conn, :no_content)
511
512 token_record = List.last(Pleroma.Repo.all(Pleroma.UserInviteToken))
513 assert token_record
514 refute token_record.used
515
516 notify_email = Pleroma.Config.get([:instance, :notify_email])
517 instance_name = Pleroma.Config.get([:instance, :name])
518
519 email =
520 Pleroma.Emails.UserEmail.user_invitation_email(
521 user,
522 token_record,
523 recipient_email,
524 recipient_name
525 )
526
527 Swoosh.TestAssertions.assert_email_sent(
528 from: {instance_name, notify_email},
529 to: {recipient_name, recipient_email},
530 html_body: email.html_body
531 )
532 end
533
534 test "it returns 403 if requested by a non-admin", %{conn: conn} do
535 non_admin_user = insert(:user)
536
537 conn =
538 conn
539 |> assign(:user, non_admin_user)
540 |> post("/api/pleroma/admin/users/email_invite?email=foo@bar.com&name=JD")
541
542 assert json_response(conn, :forbidden)
543 end
544 end
545
546 describe "POST /api/pleroma/admin/users/email_invite, with invalid config" do
547 setup do
548 [user: insert(:user, info: %{is_admin: true})]
549 end
550
551 clear_config([:instance, :registrations_open])
552 clear_config([:instance, :invites_enabled])
553
554 test "it returns 500 if `invites_enabled` is not enabled", %{conn: conn, user: user} do
555 Pleroma.Config.put([:instance, :registrations_open], false)
556 Pleroma.Config.put([:instance, :invites_enabled], false)
557
558 conn =
559 conn
560 |> assign(:user, user)
561 |> post("/api/pleroma/admin/users/email_invite?email=foo@bar.com&name=JD")
562
563 assert json_response(conn, :internal_server_error)
564 end
565
566 test "it returns 500 if `registrations_open` is enabled", %{conn: conn, user: user} do
567 Pleroma.Config.put([:instance, :registrations_open], true)
568 Pleroma.Config.put([:instance, :invites_enabled], true)
569
570 conn =
571 conn
572 |> assign(:user, user)
573 |> post("/api/pleroma/admin/users/email_invite?email=foo@bar.com&name=JD")
574
575 assert json_response(conn, :internal_server_error)
576 end
577 end
578
579 test "/api/pleroma/admin/users/:nickname/password_reset" do
580 admin = insert(:user, info: %{is_admin: true})
581 user = insert(:user)
582
583 conn =
584 build_conn()
585 |> assign(:user, admin)
586 |> put_req_header("accept", "application/json")
587 |> get("/api/pleroma/admin/users/#{user.nickname}/password_reset")
588
589 resp = json_response(conn, 200)
590
591 assert Regex.match?(~r/(http:\/\/|https:\/\/)/, resp["link"])
592 end
593
594 describe "GET /api/pleroma/admin/users" do
595 setup do
596 admin = insert(:user, info: %{is_admin: true})
597
598 conn =
599 build_conn()
600 |> assign(:user, admin)
601
602 {:ok, conn: conn, admin: admin}
603 end
604
605 test "renders users array for the first page", %{conn: conn, admin: admin} do
606 user = insert(:user, local: false, tags: ["foo", "bar"])
607 conn = get(conn, "/api/pleroma/admin/users?page=1")
608
609 users =
610 [
611 %{
612 "deactivated" => admin.info.deactivated,
613 "id" => admin.id,
614 "nickname" => admin.nickname,
615 "roles" => %{"admin" => true, "moderator" => false},
616 "local" => true,
617 "tags" => [],
618 "avatar" => User.avatar_url(admin) |> MediaProxy.url(),
619 "display_name" => HTML.strip_tags(admin.name || admin.nickname)
620 },
621 %{
622 "deactivated" => user.info.deactivated,
623 "id" => user.id,
624 "nickname" => user.nickname,
625 "roles" => %{"admin" => false, "moderator" => false},
626 "local" => false,
627 "tags" => ["foo", "bar"],
628 "avatar" => User.avatar_url(user) |> MediaProxy.url(),
629 "display_name" => HTML.strip_tags(user.name || user.nickname)
630 }
631 ]
632 |> Enum.sort_by(& &1["nickname"])
633
634 assert json_response(conn, 200) == %{
635 "count" => 2,
636 "page_size" => 50,
637 "users" => users
638 }
639 end
640
641 test "renders empty array for the second page", %{conn: conn} do
642 insert(:user)
643
644 conn = get(conn, "/api/pleroma/admin/users?page=2")
645
646 assert json_response(conn, 200) == %{
647 "count" => 2,
648 "page_size" => 50,
649 "users" => []
650 }
651 end
652
653 test "regular search", %{conn: conn} do
654 user = insert(:user, nickname: "bob")
655
656 conn = get(conn, "/api/pleroma/admin/users?query=bo")
657
658 assert json_response(conn, 200) == %{
659 "count" => 1,
660 "page_size" => 50,
661 "users" => [
662 %{
663 "deactivated" => user.info.deactivated,
664 "id" => user.id,
665 "nickname" => user.nickname,
666 "roles" => %{"admin" => false, "moderator" => false},
667 "local" => true,
668 "tags" => [],
669 "avatar" => User.avatar_url(user) |> MediaProxy.url(),
670 "display_name" => HTML.strip_tags(user.name || user.nickname)
671 }
672 ]
673 }
674 end
675
676 test "search by domain", %{conn: conn} do
677 user = insert(:user, nickname: "nickname@domain.com")
678 insert(:user)
679
680 conn = get(conn, "/api/pleroma/admin/users?query=domain.com")
681
682 assert json_response(conn, 200) == %{
683 "count" => 1,
684 "page_size" => 50,
685 "users" => [
686 %{
687 "deactivated" => user.info.deactivated,
688 "id" => user.id,
689 "nickname" => user.nickname,
690 "roles" => %{"admin" => false, "moderator" => false},
691 "local" => true,
692 "tags" => [],
693 "avatar" => User.avatar_url(user) |> MediaProxy.url(),
694 "display_name" => HTML.strip_tags(user.name || user.nickname)
695 }
696 ]
697 }
698 end
699
700 test "search by full nickname", %{conn: conn} do
701 user = insert(:user, nickname: "nickname@domain.com")
702 insert(:user)
703
704 conn = get(conn, "/api/pleroma/admin/users?query=nickname@domain.com")
705
706 assert json_response(conn, 200) == %{
707 "count" => 1,
708 "page_size" => 50,
709 "users" => [
710 %{
711 "deactivated" => user.info.deactivated,
712 "id" => user.id,
713 "nickname" => user.nickname,
714 "roles" => %{"admin" => false, "moderator" => false},
715 "local" => true,
716 "tags" => [],
717 "avatar" => User.avatar_url(user) |> MediaProxy.url(),
718 "display_name" => HTML.strip_tags(user.name || user.nickname)
719 }
720 ]
721 }
722 end
723
724 test "search by display name", %{conn: conn} do
725 user = insert(:user, name: "Display name")
726 insert(:user)
727
728 conn = get(conn, "/api/pleroma/admin/users?name=display")
729
730 assert json_response(conn, 200) == %{
731 "count" => 1,
732 "page_size" => 50,
733 "users" => [
734 %{
735 "deactivated" => user.info.deactivated,
736 "id" => user.id,
737 "nickname" => user.nickname,
738 "roles" => %{"admin" => false, "moderator" => false},
739 "local" => true,
740 "tags" => [],
741 "avatar" => User.avatar_url(user) |> MediaProxy.url(),
742 "display_name" => HTML.strip_tags(user.name || user.nickname)
743 }
744 ]
745 }
746 end
747
748 test "search by email", %{conn: conn} do
749 user = insert(:user, email: "email@example.com")
750 insert(:user)
751
752 conn = get(conn, "/api/pleroma/admin/users?email=email@example.com")
753
754 assert json_response(conn, 200) == %{
755 "count" => 1,
756 "page_size" => 50,
757 "users" => [
758 %{
759 "deactivated" => user.info.deactivated,
760 "id" => user.id,
761 "nickname" => user.nickname,
762 "roles" => %{"admin" => false, "moderator" => false},
763 "local" => true,
764 "tags" => [],
765 "avatar" => User.avatar_url(user) |> MediaProxy.url(),
766 "display_name" => HTML.strip_tags(user.name || user.nickname)
767 }
768 ]
769 }
770 end
771
772 test "regular search with page size", %{conn: conn} do
773 user = insert(:user, nickname: "aalice")
774 user2 = insert(:user, nickname: "alice")
775
776 conn1 = get(conn, "/api/pleroma/admin/users?query=a&page_size=1&page=1")
777
778 assert json_response(conn1, 200) == %{
779 "count" => 2,
780 "page_size" => 1,
781 "users" => [
782 %{
783 "deactivated" => user.info.deactivated,
784 "id" => user.id,
785 "nickname" => user.nickname,
786 "roles" => %{"admin" => false, "moderator" => false},
787 "local" => true,
788 "tags" => [],
789 "avatar" => User.avatar_url(user) |> MediaProxy.url(),
790 "display_name" => HTML.strip_tags(user.name || user.nickname)
791 }
792 ]
793 }
794
795 conn2 = get(conn, "/api/pleroma/admin/users?query=a&page_size=1&page=2")
796
797 assert json_response(conn2, 200) == %{
798 "count" => 2,
799 "page_size" => 1,
800 "users" => [
801 %{
802 "deactivated" => user2.info.deactivated,
803 "id" => user2.id,
804 "nickname" => user2.nickname,
805 "roles" => %{"admin" => false, "moderator" => false},
806 "local" => true,
807 "tags" => [],
808 "avatar" => User.avatar_url(user2) |> MediaProxy.url(),
809 "display_name" => HTML.strip_tags(user2.name || user2.nickname)
810 }
811 ]
812 }
813 end
814
815 test "only local users" do
816 admin = insert(:user, info: %{is_admin: true}, nickname: "john")
817 user = insert(:user, nickname: "bob")
818
819 insert(:user, nickname: "bobb", local: false)
820
821 conn =
822 build_conn()
823 |> assign(:user, admin)
824 |> get("/api/pleroma/admin/users?query=bo&filters=local")
825
826 assert json_response(conn, 200) == %{
827 "count" => 1,
828 "page_size" => 50,
829 "users" => [
830 %{
831 "deactivated" => user.info.deactivated,
832 "id" => user.id,
833 "nickname" => user.nickname,
834 "roles" => %{"admin" => false, "moderator" => false},
835 "local" => true,
836 "tags" => [],
837 "avatar" => User.avatar_url(user) |> MediaProxy.url(),
838 "display_name" => HTML.strip_tags(user.name || user.nickname)
839 }
840 ]
841 }
842 end
843
844 test "only local users with no query", %{admin: old_admin} do
845 admin = insert(:user, info: %{is_admin: true}, nickname: "john")
846 user = insert(:user, nickname: "bob")
847
848 insert(:user, nickname: "bobb", local: false)
849
850 conn =
851 build_conn()
852 |> assign(:user, admin)
853 |> get("/api/pleroma/admin/users?filters=local")
854
855 users =
856 [
857 %{
858 "deactivated" => user.info.deactivated,
859 "id" => user.id,
860 "nickname" => user.nickname,
861 "roles" => %{"admin" => false, "moderator" => false},
862 "local" => true,
863 "tags" => [],
864 "avatar" => User.avatar_url(user) |> MediaProxy.url(),
865 "display_name" => HTML.strip_tags(user.name || user.nickname)
866 },
867 %{
868 "deactivated" => admin.info.deactivated,
869 "id" => admin.id,
870 "nickname" => admin.nickname,
871 "roles" => %{"admin" => true, "moderator" => false},
872 "local" => true,
873 "tags" => [],
874 "avatar" => User.avatar_url(admin) |> MediaProxy.url(),
875 "display_name" => HTML.strip_tags(admin.name || admin.nickname)
876 },
877 %{
878 "deactivated" => false,
879 "id" => old_admin.id,
880 "local" => true,
881 "nickname" => old_admin.nickname,
882 "roles" => %{"admin" => true, "moderator" => false},
883 "tags" => [],
884 "avatar" => User.avatar_url(old_admin) |> MediaProxy.url(),
885 "display_name" => HTML.strip_tags(old_admin.name || old_admin.nickname)
886 }
887 ]
888 |> Enum.sort_by(& &1["nickname"])
889
890 assert json_response(conn, 200) == %{
891 "count" => 3,
892 "page_size" => 50,
893 "users" => users
894 }
895 end
896
897 test "load only admins", %{conn: conn, admin: admin} do
898 second_admin = insert(:user, info: %{is_admin: true})
899 insert(:user)
900 insert(:user)
901
902 conn = get(conn, "/api/pleroma/admin/users?filters=is_admin")
903
904 users =
905 [
906 %{
907 "deactivated" => false,
908 "id" => admin.id,
909 "nickname" => admin.nickname,
910 "roles" => %{"admin" => true, "moderator" => false},
911 "local" => admin.local,
912 "tags" => [],
913 "avatar" => User.avatar_url(admin) |> MediaProxy.url(),
914 "display_name" => HTML.strip_tags(admin.name || admin.nickname)
915 },
916 %{
917 "deactivated" => false,
918 "id" => second_admin.id,
919 "nickname" => second_admin.nickname,
920 "roles" => %{"admin" => true, "moderator" => false},
921 "local" => second_admin.local,
922 "tags" => [],
923 "avatar" => User.avatar_url(second_admin) |> MediaProxy.url(),
924 "display_name" => HTML.strip_tags(second_admin.name || second_admin.nickname)
925 }
926 ]
927 |> Enum.sort_by(& &1["nickname"])
928
929 assert json_response(conn, 200) == %{
930 "count" => 2,
931 "page_size" => 50,
932 "users" => users
933 }
934 end
935
936 test "load only moderators", %{conn: conn} do
937 moderator = insert(:user, info: %{is_moderator: true})
938 insert(:user)
939 insert(:user)
940
941 conn = get(conn, "/api/pleroma/admin/users?filters=is_moderator")
942
943 assert json_response(conn, 200) == %{
944 "count" => 1,
945 "page_size" => 50,
946 "users" => [
947 %{
948 "deactivated" => false,
949 "id" => moderator.id,
950 "nickname" => moderator.nickname,
951 "roles" => %{"admin" => false, "moderator" => true},
952 "local" => moderator.local,
953 "tags" => [],
954 "avatar" => User.avatar_url(moderator) |> MediaProxy.url(),
955 "display_name" => HTML.strip_tags(moderator.name || moderator.nickname)
956 }
957 ]
958 }
959 end
960
961 test "load users with tags list", %{conn: conn} do
962 user1 = insert(:user, tags: ["first"])
963 user2 = insert(:user, tags: ["second"])
964 insert(:user)
965 insert(:user)
966
967 conn = get(conn, "/api/pleroma/admin/users?tags[]=first&tags[]=second")
968
969 users =
970 [
971 %{
972 "deactivated" => false,
973 "id" => user1.id,
974 "nickname" => user1.nickname,
975 "roles" => %{"admin" => false, "moderator" => false},
976 "local" => user1.local,
977 "tags" => ["first"],
978 "avatar" => User.avatar_url(user1) |> MediaProxy.url(),
979 "display_name" => HTML.strip_tags(user1.name || user1.nickname)
980 },
981 %{
982 "deactivated" => false,
983 "id" => user2.id,
984 "nickname" => user2.nickname,
985 "roles" => %{"admin" => false, "moderator" => false},
986 "local" => user2.local,
987 "tags" => ["second"],
988 "avatar" => User.avatar_url(user2) |> MediaProxy.url(),
989 "display_name" => HTML.strip_tags(user2.name || user2.nickname)
990 }
991 ]
992 |> Enum.sort_by(& &1["nickname"])
993
994 assert json_response(conn, 200) == %{
995 "count" => 2,
996 "page_size" => 50,
997 "users" => users
998 }
999 end
1000
1001 test "it works with multiple filters" do
1002 admin = insert(:user, nickname: "john", info: %{is_admin: true})
1003 user = insert(:user, nickname: "bob", local: false, info: %{deactivated: true})
1004
1005 insert(:user, nickname: "ken", local: true, info: %{deactivated: true})
1006 insert(:user, nickname: "bobb", local: false, info: %{deactivated: false})
1007
1008 conn =
1009 build_conn()
1010 |> assign(:user, admin)
1011 |> get("/api/pleroma/admin/users?filters=deactivated,external")
1012
1013 assert json_response(conn, 200) == %{
1014 "count" => 1,
1015 "page_size" => 50,
1016 "users" => [
1017 %{
1018 "deactivated" => user.info.deactivated,
1019 "id" => user.id,
1020 "nickname" => user.nickname,
1021 "roles" => %{"admin" => false, "moderator" => false},
1022 "local" => user.local,
1023 "tags" => [],
1024 "avatar" => User.avatar_url(user) |> MediaProxy.url(),
1025 "display_name" => HTML.strip_tags(user.name || user.nickname)
1026 }
1027 ]
1028 }
1029 end
1030 end
1031
1032 test "PATCH /api/pleroma/admin/users/:nickname/toggle_activation" do
1033 admin = insert(:user, info: %{is_admin: true})
1034 user = insert(:user)
1035
1036 conn =
1037 build_conn()
1038 |> assign(:user, admin)
1039 |> patch("/api/pleroma/admin/users/#{user.nickname}/toggle_activation")
1040
1041 assert json_response(conn, 200) ==
1042 %{
1043 "deactivated" => !user.info.deactivated,
1044 "id" => user.id,
1045 "nickname" => user.nickname,
1046 "roles" => %{"admin" => false, "moderator" => false},
1047 "local" => true,
1048 "tags" => [],
1049 "avatar" => User.avatar_url(user) |> MediaProxy.url(),
1050 "display_name" => HTML.strip_tags(user.name || user.nickname)
1051 }
1052
1053 log_entry = Repo.one(ModerationLog)
1054
1055 assert ModerationLog.get_log_entry_message(log_entry) ==
1056 "@#{admin.nickname} deactivated user @#{user.nickname}"
1057 end
1058
1059 describe "POST /api/pleroma/admin/users/invite_token" do
1060 setup do
1061 admin = insert(:user, info: %{is_admin: true})
1062
1063 conn =
1064 build_conn()
1065 |> assign(:user, admin)
1066
1067 {:ok, conn: conn}
1068 end
1069
1070 test "without options", %{conn: conn} do
1071 conn = post(conn, "/api/pleroma/admin/users/invite_token")
1072
1073 invite_json = json_response(conn, 200)
1074 invite = UserInviteToken.find_by_token!(invite_json["token"])
1075 refute invite.used
1076 refute invite.expires_at
1077 refute invite.max_use
1078 assert invite.invite_type == "one_time"
1079 end
1080
1081 test "with expires_at", %{conn: conn} do
1082 conn =
1083 post(conn, "/api/pleroma/admin/users/invite_token", %{
1084 "expires_at" => Date.to_string(Date.utc_today())
1085 })
1086
1087 invite_json = json_response(conn, 200)
1088 invite = UserInviteToken.find_by_token!(invite_json["token"])
1089
1090 refute invite.used
1091 assert invite.expires_at == Date.utc_today()
1092 refute invite.max_use
1093 assert invite.invite_type == "date_limited"
1094 end
1095
1096 test "with max_use", %{conn: conn} do
1097 conn = post(conn, "/api/pleroma/admin/users/invite_token", %{"max_use" => 150})
1098
1099 invite_json = json_response(conn, 200)
1100 invite = UserInviteToken.find_by_token!(invite_json["token"])
1101 refute invite.used
1102 refute invite.expires_at
1103 assert invite.max_use == 150
1104 assert invite.invite_type == "reusable"
1105 end
1106
1107 test "with max use and expires_at", %{conn: conn} do
1108 conn =
1109 post(conn, "/api/pleroma/admin/users/invite_token", %{
1110 "max_use" => 150,
1111 "expires_at" => Date.to_string(Date.utc_today())
1112 })
1113
1114 invite_json = json_response(conn, 200)
1115 invite = UserInviteToken.find_by_token!(invite_json["token"])
1116 refute invite.used
1117 assert invite.expires_at == Date.utc_today()
1118 assert invite.max_use == 150
1119 assert invite.invite_type == "reusable_date_limited"
1120 end
1121 end
1122
1123 describe "GET /api/pleroma/admin/users/invites" do
1124 setup do
1125 admin = insert(:user, info: %{is_admin: true})
1126
1127 conn =
1128 build_conn()
1129 |> assign(:user, admin)
1130
1131 {:ok, conn: conn}
1132 end
1133
1134 test "no invites", %{conn: conn} do
1135 conn = get(conn, "/api/pleroma/admin/users/invites")
1136
1137 assert json_response(conn, 200) == %{"invites" => []}
1138 end
1139
1140 test "with invite", %{conn: conn} do
1141 {:ok, invite} = UserInviteToken.create_invite()
1142
1143 conn = get(conn, "/api/pleroma/admin/users/invites")
1144
1145 assert json_response(conn, 200) == %{
1146 "invites" => [
1147 %{
1148 "expires_at" => nil,
1149 "id" => invite.id,
1150 "invite_type" => "one_time",
1151 "max_use" => nil,
1152 "token" => invite.token,
1153 "used" => false,
1154 "uses" => 0
1155 }
1156 ]
1157 }
1158 end
1159 end
1160
1161 describe "POST /api/pleroma/admin/users/revoke_invite" do
1162 test "with token" do
1163 admin = insert(:user, info: %{is_admin: true})
1164 {:ok, invite} = UserInviteToken.create_invite()
1165
1166 conn =
1167 build_conn()
1168 |> assign(:user, admin)
1169 |> post("/api/pleroma/admin/users/revoke_invite", %{"token" => invite.token})
1170
1171 assert json_response(conn, 200) == %{
1172 "expires_at" => nil,
1173 "id" => invite.id,
1174 "invite_type" => "one_time",
1175 "max_use" => nil,
1176 "token" => invite.token,
1177 "used" => true,
1178 "uses" => 0
1179 }
1180 end
1181
1182 test "with invalid token" do
1183 admin = insert(:user, info: %{is_admin: true})
1184
1185 conn =
1186 build_conn()
1187 |> assign(:user, admin)
1188 |> post("/api/pleroma/admin/users/revoke_invite", %{"token" => "foo"})
1189
1190 assert json_response(conn, :not_found) == "Not found"
1191 end
1192 end
1193
1194 describe "GET /api/pleroma/admin/reports/:id" do
1195 setup %{conn: conn} do
1196 admin = insert(:user, info: %{is_admin: true})
1197
1198 %{conn: assign(conn, :user, admin)}
1199 end
1200
1201 test "returns report by its id", %{conn: conn} do
1202 [reporter, target_user] = insert_pair(:user)
1203 activity = insert(:note_activity, user: target_user)
1204
1205 {:ok, %{id: report_id}} =
1206 CommonAPI.report(reporter, %{
1207 "account_id" => target_user.id,
1208 "comment" => "I feel offended",
1209 "status_ids" => [activity.id]
1210 })
1211
1212 response =
1213 conn
1214 |> get("/api/pleroma/admin/reports/#{report_id}")
1215 |> json_response(:ok)
1216
1217 assert response["id"] == report_id
1218 end
1219
1220 test "returns 404 when report id is invalid", %{conn: conn} do
1221 conn = get(conn, "/api/pleroma/admin/reports/test")
1222
1223 assert json_response(conn, :not_found) == "Not found"
1224 end
1225 end
1226
1227 describe "PATCH /api/pleroma/admin/reports" do
1228 setup %{conn: conn} do
1229 admin = insert(:user, info: %{is_admin: true})
1230 [reporter, target_user] = insert_pair(:user)
1231 activity = insert(:note_activity, user: target_user)
1232
1233 {:ok, %{id: report_id}} =
1234 CommonAPI.report(reporter, %{
1235 "account_id" => target_user.id,
1236 "comment" => "I feel offended",
1237 "status_ids" => [activity.id]
1238 })
1239
1240 {:ok, %{id: second_report_id}} =
1241 CommonAPI.report(reporter, %{
1242 "account_id" => target_user.id,
1243 "comment" => "I feel very offended",
1244 "status_ids" => [activity.id]
1245 })
1246
1247 %{
1248 conn: assign(conn, :user, admin),
1249 id: report_id,
1250 admin: admin,
1251 second_report_id: second_report_id
1252 }
1253 end
1254
1255 test "mark report as resolved", %{conn: conn, id: id, admin: admin} do
1256 conn
1257 |> patch("/api/pleroma/admin/reports", %{
1258 "reports" => [
1259 %{"state" => "resolved", "id" => id}
1260 ]
1261 })
1262 |> json_response(:no_content)
1263
1264 activity = Activity.get_by_id(id)
1265 assert activity.data["state"] == "resolved"
1266
1267 log_entry = Repo.one(ModerationLog)
1268
1269 assert ModerationLog.get_log_entry_message(log_entry) ==
1270 "@#{admin.nickname} updated report ##{id} with 'resolved' state"
1271 end
1272
1273 test "closes report", %{conn: conn, id: id, admin: admin} do
1274 conn
1275 |> patch("/api/pleroma/admin/reports", %{
1276 "reports" => [
1277 %{"state" => "closed", "id" => id}
1278 ]
1279 })
1280 |> json_response(:no_content)
1281
1282 activity = Activity.get_by_id(id)
1283 assert activity.data["state"] == "closed"
1284
1285 log_entry = Repo.one(ModerationLog)
1286
1287 assert ModerationLog.get_log_entry_message(log_entry) ==
1288 "@#{admin.nickname} updated report ##{id} with 'closed' state"
1289 end
1290
1291 test "returns 400 when state is unknown", %{conn: conn, id: id} do
1292 conn =
1293 conn
1294 |> patch("/api/pleroma/admin/reports", %{
1295 "reports" => [
1296 %{"state" => "test", "id" => id}
1297 ]
1298 })
1299
1300 assert hd(json_response(conn, :bad_request))["error"] == "Unsupported state"
1301 end
1302
1303 test "returns 404 when report is not exist", %{conn: conn} do
1304 conn =
1305 conn
1306 |> patch("/api/pleroma/admin/reports", %{
1307 "reports" => [
1308 %{"state" => "closed", "id" => "test"}
1309 ]
1310 })
1311
1312 assert hd(json_response(conn, :bad_request))["error"] == "not_found"
1313 end
1314
1315 test "updates state of multiple reports", %{
1316 conn: conn,
1317 id: id,
1318 admin: admin,
1319 second_report_id: second_report_id
1320 } do
1321 conn
1322 |> patch("/api/pleroma/admin/reports", %{
1323 "reports" => [
1324 %{"state" => "resolved", "id" => id},
1325 %{"state" => "closed", "id" => second_report_id}
1326 ]
1327 })
1328 |> json_response(:no_content)
1329
1330 activity = Activity.get_by_id(id)
1331 second_activity = Activity.get_by_id(second_report_id)
1332 assert activity.data["state"] == "resolved"
1333 assert second_activity.data["state"] == "closed"
1334
1335 [first_log_entry, second_log_entry] = Repo.all(ModerationLog)
1336
1337 assert ModerationLog.get_log_entry_message(first_log_entry) ==
1338 "@#{admin.nickname} updated report ##{id} with 'resolved' state"
1339
1340 assert ModerationLog.get_log_entry_message(second_log_entry) ==
1341 "@#{admin.nickname} updated report ##{second_report_id} with 'closed' state"
1342 end
1343 end
1344
1345 describe "GET /api/pleroma/admin/reports" do
1346 setup %{conn: conn} do
1347 admin = insert(:user, info: %{is_admin: true})
1348
1349 %{conn: assign(conn, :user, admin)}
1350 end
1351
1352 test "returns empty response when no reports created", %{conn: conn} do
1353 response =
1354 conn
1355 |> get("/api/pleroma/admin/reports")
1356 |> json_response(:ok)
1357
1358 assert Enum.empty?(response["reports"])
1359 assert response["total"] == 0
1360 end
1361
1362 test "returns reports", %{conn: conn} do
1363 [reporter, target_user] = insert_pair(:user)
1364 activity = insert(:note_activity, user: target_user)
1365
1366 {:ok, %{id: report_id}} =
1367 CommonAPI.report(reporter, %{
1368 "account_id" => target_user.id,
1369 "comment" => "I feel offended",
1370 "status_ids" => [activity.id]
1371 })
1372
1373 response =
1374 conn
1375 |> get("/api/pleroma/admin/reports")
1376 |> json_response(:ok)
1377
1378 [report] = response["reports"]
1379
1380 assert length(response["reports"]) == 1
1381 assert report["id"] == report_id
1382
1383 assert response["total"] == 1
1384 end
1385
1386 test "returns reports with specified state", %{conn: conn} do
1387 [reporter, target_user] = insert_pair(:user)
1388 activity = insert(:note_activity, user: target_user)
1389
1390 {:ok, %{id: first_report_id}} =
1391 CommonAPI.report(reporter, %{
1392 "account_id" => target_user.id,
1393 "comment" => "I feel offended",
1394 "status_ids" => [activity.id]
1395 })
1396
1397 {:ok, %{id: second_report_id}} =
1398 CommonAPI.report(reporter, %{
1399 "account_id" => target_user.id,
1400 "comment" => "I don't like this user"
1401 })
1402
1403 CommonAPI.update_report_state(second_report_id, "closed")
1404
1405 response =
1406 conn
1407 |> get("/api/pleroma/admin/reports", %{
1408 "state" => "open"
1409 })
1410 |> json_response(:ok)
1411
1412 [open_report] = response["reports"]
1413
1414 assert length(response["reports"]) == 1
1415 assert open_report["id"] == first_report_id
1416
1417 assert response["total"] == 1
1418
1419 response =
1420 conn
1421 |> get("/api/pleroma/admin/reports", %{
1422 "state" => "closed"
1423 })
1424 |> json_response(:ok)
1425
1426 [closed_report] = response["reports"]
1427
1428 assert length(response["reports"]) == 1
1429 assert closed_report["id"] == second_report_id
1430
1431 assert response["total"] == 1
1432
1433 response =
1434 conn
1435 |> get("/api/pleroma/admin/reports", %{
1436 "state" => "resolved"
1437 })
1438 |> json_response(:ok)
1439
1440 assert Enum.empty?(response["reports"])
1441 assert response["total"] == 0
1442 end
1443
1444 test "returns 403 when requested by a non-admin" do
1445 user = insert(:user)
1446
1447 conn =
1448 build_conn()
1449 |> assign(:user, user)
1450 |> get("/api/pleroma/admin/reports")
1451
1452 assert json_response(conn, :forbidden) == %{"error" => "User is not admin."}
1453 end
1454
1455 test "returns 403 when requested by anonymous" do
1456 conn =
1457 build_conn()
1458 |> get("/api/pleroma/admin/reports")
1459
1460 assert json_response(conn, :forbidden) == %{"error" => "Invalid credentials."}
1461 end
1462 end
1463
1464 #
1465 describe "POST /api/pleroma/admin/reports/:id/respond" do
1466 setup %{conn: conn} do
1467 admin = insert(:user, info: %{is_admin: true})
1468
1469 %{conn: assign(conn, :user, admin), admin: admin}
1470 end
1471
1472 test "returns created dm", %{conn: conn, admin: admin} do
1473 [reporter, target_user] = insert_pair(:user)
1474 activity = insert(:note_activity, user: target_user)
1475
1476 {:ok, %{id: report_id}} =
1477 CommonAPI.report(reporter, %{
1478 "account_id" => target_user.id,
1479 "comment" => "I feel offended",
1480 "status_ids" => [activity.id]
1481 })
1482
1483 response =
1484 conn
1485 |> post("/api/pleroma/admin/reports/#{report_id}/respond", %{
1486 "status" => "I will check it out"
1487 })
1488 |> json_response(:ok)
1489
1490 recipients = Enum.map(response["mentions"], & &1["username"])
1491
1492 assert reporter.nickname in recipients
1493 assert response["content"] == "I will check it out"
1494 assert response["visibility"] == "direct"
1495
1496 log_entry = Repo.one(ModerationLog)
1497
1498 assert ModerationLog.get_log_entry_message(log_entry) ==
1499 "@#{admin.nickname} responded with 'I will check it out' to report ##{
1500 response["id"]
1501 }"
1502 end
1503
1504 test "returns 400 when status is missing", %{conn: conn} do
1505 conn = post(conn, "/api/pleroma/admin/reports/test/respond")
1506
1507 assert json_response(conn, :bad_request) == "Invalid parameters"
1508 end
1509
1510 test "returns 404 when report id is invalid", %{conn: conn} do
1511 conn =
1512 post(conn, "/api/pleroma/admin/reports/test/respond", %{
1513 "status" => "foo"
1514 })
1515
1516 assert json_response(conn, :not_found) == "Not found"
1517 end
1518 end
1519
1520 describe "PUT /api/pleroma/admin/statuses/:id" do
1521 setup %{conn: conn} do
1522 admin = insert(:user, info: %{is_admin: true})
1523 activity = insert(:note_activity)
1524
1525 %{conn: assign(conn, :user, admin), id: activity.id, admin: admin}
1526 end
1527
1528 test "toggle sensitive flag", %{conn: conn, id: id, admin: admin} do
1529 response =
1530 conn
1531 |> put("/api/pleroma/admin/statuses/#{id}", %{"sensitive" => "true"})
1532 |> json_response(:ok)
1533
1534 assert response["sensitive"]
1535
1536 log_entry = Repo.one(ModerationLog)
1537
1538 assert ModerationLog.get_log_entry_message(log_entry) ==
1539 "@#{admin.nickname} updated status ##{id}, set sensitive: 'true'"
1540
1541 response =
1542 conn
1543 |> put("/api/pleroma/admin/statuses/#{id}", %{"sensitive" => "false"})
1544 |> json_response(:ok)
1545
1546 refute response["sensitive"]
1547 end
1548
1549 test "change visibility flag", %{conn: conn, id: id, admin: admin} do
1550 response =
1551 conn
1552 |> put("/api/pleroma/admin/statuses/#{id}", %{"visibility" => "public"})
1553 |> json_response(:ok)
1554
1555 assert response["visibility"] == "public"
1556
1557 log_entry = Repo.one(ModerationLog)
1558
1559 assert ModerationLog.get_log_entry_message(log_entry) ==
1560 "@#{admin.nickname} updated status ##{id}, set visibility: 'public'"
1561
1562 response =
1563 conn
1564 |> put("/api/pleroma/admin/statuses/#{id}", %{"visibility" => "private"})
1565 |> json_response(:ok)
1566
1567 assert response["visibility"] == "private"
1568
1569 response =
1570 conn
1571 |> put("/api/pleroma/admin/statuses/#{id}", %{"visibility" => "unlisted"})
1572 |> json_response(:ok)
1573
1574 assert response["visibility"] == "unlisted"
1575 end
1576
1577 test "returns 400 when visibility is unknown", %{conn: conn, id: id} do
1578 conn =
1579 conn
1580 |> put("/api/pleroma/admin/statuses/#{id}", %{"visibility" => "test"})
1581
1582 assert json_response(conn, :bad_request) == "Unsupported visibility"
1583 end
1584 end
1585
1586 describe "DELETE /api/pleroma/admin/statuses/:id" do
1587 setup %{conn: conn} do
1588 admin = insert(:user, info: %{is_admin: true})
1589 activity = insert(:note_activity)
1590
1591 %{conn: assign(conn, :user, admin), id: activity.id, admin: admin}
1592 end
1593
1594 test "deletes status", %{conn: conn, id: id, admin: admin} do
1595 conn
1596 |> delete("/api/pleroma/admin/statuses/#{id}")
1597 |> json_response(:ok)
1598
1599 refute Activity.get_by_id(id)
1600
1601 log_entry = Repo.one(ModerationLog)
1602
1603 assert ModerationLog.get_log_entry_message(log_entry) ==
1604 "@#{admin.nickname} deleted status ##{id}"
1605 end
1606
1607 test "returns error when status is not exist", %{conn: conn} do
1608 conn =
1609 conn
1610 |> delete("/api/pleroma/admin/statuses/test")
1611
1612 assert json_response(conn, :bad_request) == "Could not delete"
1613 end
1614 end
1615
1616 describe "GET /api/pleroma/admin/config" do
1617 setup %{conn: conn} do
1618 admin = insert(:user, info: %{is_admin: true})
1619
1620 %{conn: assign(conn, :user, admin)}
1621 end
1622
1623 test "without any settings in db", %{conn: conn} do
1624 conn = get(conn, "/api/pleroma/admin/config")
1625
1626 assert json_response(conn, 200) == %{"configs" => []}
1627 end
1628
1629 test "with settings in db", %{conn: conn} do
1630 config1 = insert(:config)
1631 config2 = insert(:config)
1632
1633 conn = get(conn, "/api/pleroma/admin/config")
1634
1635 %{
1636 "configs" => [
1637 %{
1638 "key" => key1,
1639 "value" => _
1640 },
1641 %{
1642 "key" => key2,
1643 "value" => _
1644 }
1645 ]
1646 } = json_response(conn, 200)
1647
1648 assert key1 == config1.key
1649 assert key2 == config2.key
1650 end
1651 end
1652
1653 describe "POST /api/pleroma/admin/config" do
1654 setup %{conn: conn} do
1655 admin = insert(:user, info: %{is_admin: true})
1656
1657 temp_file = "config/test.exported_from_db.secret.exs"
1658
1659 on_exit(fn ->
1660 Application.delete_env(:pleroma, :key1)
1661 Application.delete_env(:pleroma, :key2)
1662 Application.delete_env(:pleroma, :key3)
1663 Application.delete_env(:pleroma, :key4)
1664 Application.delete_env(:pleroma, :keyaa1)
1665 Application.delete_env(:pleroma, :keyaa2)
1666 Application.delete_env(:pleroma, Pleroma.Web.Endpoint.NotReal)
1667 Application.delete_env(:pleroma, Pleroma.Captcha.NotReal)
1668 :ok = File.rm(temp_file)
1669 end)
1670
1671 %{conn: assign(conn, :user, admin)}
1672 end
1673
1674 clear_config([:instance, :dynamic_configuration]) do
1675 Pleroma.Config.put([:instance, :dynamic_configuration], true)
1676 end
1677
1678 test "create new config setting in db", %{conn: conn} do
1679 conn =
1680 post(conn, "/api/pleroma/admin/config", %{
1681 configs: [
1682 %{group: "pleroma", key: "key1", value: "value1"},
1683 %{
1684 group: "ueberauth",
1685 key: "Ueberauth.Strategy.Twitter.OAuth",
1686 value: [%{"tuple" => [":consumer_secret", "aaaa"]}]
1687 },
1688 %{
1689 group: "pleroma",
1690 key: "key2",
1691 value: %{
1692 ":nested_1" => "nested_value1",
1693 ":nested_2" => [
1694 %{":nested_22" => "nested_value222"},
1695 %{":nested_33" => %{":nested_44" => "nested_444"}}
1696 ]
1697 }
1698 },
1699 %{
1700 group: "pleroma",
1701 key: "key3",
1702 value: [
1703 %{"nested_3" => ":nested_3", "nested_33" => "nested_33"},
1704 %{"nested_4" => true}
1705 ]
1706 },
1707 %{
1708 group: "pleroma",
1709 key: "key4",
1710 value: %{":nested_5" => ":upload", "endpoint" => "https://example.com"}
1711 },
1712 %{
1713 group: "idna",
1714 key: "key5",
1715 value: %{"tuple" => ["string", "Pleroma.Captcha.NotReal", []]}
1716 }
1717 ]
1718 })
1719
1720 assert json_response(conn, 200) == %{
1721 "configs" => [
1722 %{
1723 "group" => "pleroma",
1724 "key" => "key1",
1725 "value" => "value1"
1726 },
1727 %{
1728 "group" => "ueberauth",
1729 "key" => "Ueberauth.Strategy.Twitter.OAuth",
1730 "value" => [%{"tuple" => [":consumer_secret", "aaaa"]}]
1731 },
1732 %{
1733 "group" => "pleroma",
1734 "key" => "key2",
1735 "value" => %{
1736 ":nested_1" => "nested_value1",
1737 ":nested_2" => [
1738 %{":nested_22" => "nested_value222"},
1739 %{":nested_33" => %{":nested_44" => "nested_444"}}
1740 ]
1741 }
1742 },
1743 %{
1744 "group" => "pleroma",
1745 "key" => "key3",
1746 "value" => [
1747 %{"nested_3" => ":nested_3", "nested_33" => "nested_33"},
1748 %{"nested_4" => true}
1749 ]
1750 },
1751 %{
1752 "group" => "pleroma",
1753 "key" => "key4",
1754 "value" => %{"endpoint" => "https://example.com", ":nested_5" => ":upload"}
1755 },
1756 %{
1757 "group" => "idna",
1758 "key" => "key5",
1759 "value" => %{"tuple" => ["string", "Pleroma.Captcha.NotReal", []]}
1760 }
1761 ]
1762 }
1763
1764 assert Application.get_env(:pleroma, :key1) == "value1"
1765
1766 assert Application.get_env(:pleroma, :key2) == %{
1767 nested_1: "nested_value1",
1768 nested_2: [
1769 %{nested_22: "nested_value222"},
1770 %{nested_33: %{nested_44: "nested_444"}}
1771 ]
1772 }
1773
1774 assert Application.get_env(:pleroma, :key3) == [
1775 %{"nested_3" => :nested_3, "nested_33" => "nested_33"},
1776 %{"nested_4" => true}
1777 ]
1778
1779 assert Application.get_env(:pleroma, :key4) == %{
1780 "endpoint" => "https://example.com",
1781 nested_5: :upload
1782 }
1783
1784 assert Application.get_env(:idna, :key5) == {"string", Pleroma.Captcha.NotReal, []}
1785 end
1786
1787 test "update config setting & delete", %{conn: conn} do
1788 config1 = insert(:config, key: "keyaa1")
1789 config2 = insert(:config, key: "keyaa2")
1790
1791 insert(:config,
1792 group: "ueberauth",
1793 key: "Ueberauth.Strategy.Microsoft.OAuth",
1794 value: :erlang.term_to_binary([])
1795 )
1796
1797 conn =
1798 post(conn, "/api/pleroma/admin/config", %{
1799 configs: [
1800 %{group: config1.group, key: config1.key, value: "another_value"},
1801 %{group: config2.group, key: config2.key, delete: "true"},
1802 %{
1803 group: "ueberauth",
1804 key: "Ueberauth.Strategy.Microsoft.OAuth",
1805 delete: "true"
1806 }
1807 ]
1808 })
1809
1810 assert json_response(conn, 200) == %{
1811 "configs" => [
1812 %{
1813 "group" => "pleroma",
1814 "key" => config1.key,
1815 "value" => "another_value"
1816 }
1817 ]
1818 }
1819
1820 assert Application.get_env(:pleroma, :keyaa1) == "another_value"
1821 refute Application.get_env(:pleroma, :keyaa2)
1822 end
1823
1824 test "common config example", %{conn: conn} do
1825 conn =
1826 post(conn, "/api/pleroma/admin/config", %{
1827 configs: [
1828 %{
1829 "group" => "pleroma",
1830 "key" => "Pleroma.Captcha.NotReal",
1831 "value" => [
1832 %{"tuple" => [":enabled", false]},
1833 %{"tuple" => [":method", "Pleroma.Captcha.Kocaptcha"]},
1834 %{"tuple" => [":seconds_valid", 60]},
1835 %{"tuple" => [":path", ""]},
1836 %{"tuple" => [":key1", nil]},
1837 %{"tuple" => [":partial_chain", "&:hackney_connect.partial_chain/1"]},
1838 %{"tuple" => [":regex1", "~r/https:\/\/example.com/"]},
1839 %{"tuple" => [":regex2", "~r/https:\/\/example.com/u"]},
1840 %{"tuple" => [":regex3", "~r/https:\/\/example.com/i"]},
1841 %{"tuple" => [":regex4", "~r/https:\/\/example.com/s"]}
1842 ]
1843 }
1844 ]
1845 })
1846
1847 assert json_response(conn, 200) == %{
1848 "configs" => [
1849 %{
1850 "group" => "pleroma",
1851 "key" => "Pleroma.Captcha.NotReal",
1852 "value" => [
1853 %{"tuple" => [":enabled", false]},
1854 %{"tuple" => [":method", "Pleroma.Captcha.Kocaptcha"]},
1855 %{"tuple" => [":seconds_valid", 60]},
1856 %{"tuple" => [":path", ""]},
1857 %{"tuple" => [":key1", nil]},
1858 %{"tuple" => [":partial_chain", "&:hackney_connect.partial_chain/1"]},
1859 %{"tuple" => [":regex1", "~r/https:\\/\\/example.com/"]},
1860 %{"tuple" => [":regex2", "~r/https:\\/\\/example.com/u"]},
1861 %{"tuple" => [":regex3", "~r/https:\\/\\/example.com/i"]},
1862 %{"tuple" => [":regex4", "~r/https:\\/\\/example.com/s"]}
1863 ]
1864 }
1865 ]
1866 }
1867 end
1868
1869 test "tuples with more than two values", %{conn: conn} do
1870 conn =
1871 post(conn, "/api/pleroma/admin/config", %{
1872 configs: [
1873 %{
1874 "group" => "pleroma",
1875 "key" => "Pleroma.Web.Endpoint.NotReal",
1876 "value" => [
1877 %{
1878 "tuple" => [
1879 ":http",
1880 [
1881 %{
1882 "tuple" => [
1883 ":key2",
1884 [
1885 %{
1886 "tuple" => [
1887 ":_",
1888 [
1889 %{
1890 "tuple" => [
1891 "/api/v1/streaming",
1892 "Pleroma.Web.MastodonAPI.WebsocketHandler",
1893 []
1894 ]
1895 },
1896 %{
1897 "tuple" => [
1898 "/websocket",
1899 "Phoenix.Endpoint.CowboyWebSocket",
1900 %{
1901 "tuple" => [
1902 "Phoenix.Transports.WebSocket",
1903 %{
1904 "tuple" => [
1905 "Pleroma.Web.Endpoint",
1906 "Pleroma.Web.UserSocket",
1907 []
1908 ]
1909 }
1910 ]
1911 }
1912 ]
1913 },
1914 %{
1915 "tuple" => [
1916 ":_",
1917 "Phoenix.Endpoint.Cowboy2Handler",
1918 %{"tuple" => ["Pleroma.Web.Endpoint", []]}
1919 ]
1920 }
1921 ]
1922 ]
1923 }
1924 ]
1925 ]
1926 }
1927 ]
1928 ]
1929 }
1930 ]
1931 }
1932 ]
1933 })
1934
1935 assert json_response(conn, 200) == %{
1936 "configs" => [
1937 %{
1938 "group" => "pleroma",
1939 "key" => "Pleroma.Web.Endpoint.NotReal",
1940 "value" => [
1941 %{
1942 "tuple" => [
1943 ":http",
1944 [
1945 %{
1946 "tuple" => [
1947 ":key2",
1948 [
1949 %{
1950 "tuple" => [
1951 ":_",
1952 [
1953 %{
1954 "tuple" => [
1955 "/api/v1/streaming",
1956 "Pleroma.Web.MastodonAPI.WebsocketHandler",
1957 []
1958 ]
1959 },
1960 %{
1961 "tuple" => [
1962 "/websocket",
1963 "Phoenix.Endpoint.CowboyWebSocket",
1964 %{
1965 "tuple" => [
1966 "Phoenix.Transports.WebSocket",
1967 %{
1968 "tuple" => [
1969 "Pleroma.Web.Endpoint",
1970 "Pleroma.Web.UserSocket",
1971 []
1972 ]
1973 }
1974 ]
1975 }
1976 ]
1977 },
1978 %{
1979 "tuple" => [
1980 ":_",
1981 "Phoenix.Endpoint.Cowboy2Handler",
1982 %{"tuple" => ["Pleroma.Web.Endpoint", []]}
1983 ]
1984 }
1985 ]
1986 ]
1987 }
1988 ]
1989 ]
1990 }
1991 ]
1992 ]
1993 }
1994 ]
1995 }
1996 ]
1997 }
1998 end
1999
2000 test "settings with nesting map", %{conn: conn} do
2001 conn =
2002 post(conn, "/api/pleroma/admin/config", %{
2003 configs: [
2004 %{
2005 "group" => "pleroma",
2006 "key" => ":key1",
2007 "value" => [
2008 %{"tuple" => [":key2", "some_val"]},
2009 %{
2010 "tuple" => [
2011 ":key3",
2012 %{
2013 ":max_options" => 20,
2014 ":max_option_chars" => 200,
2015 ":min_expiration" => 0,
2016 ":max_expiration" => 31_536_000,
2017 "nested" => %{
2018 ":max_options" => 20,
2019 ":max_option_chars" => 200,
2020 ":min_expiration" => 0,
2021 ":max_expiration" => 31_536_000
2022 }
2023 }
2024 ]
2025 }
2026 ]
2027 }
2028 ]
2029 })
2030
2031 assert json_response(conn, 200) ==
2032 %{
2033 "configs" => [
2034 %{
2035 "group" => "pleroma",
2036 "key" => ":key1",
2037 "value" => [
2038 %{"tuple" => [":key2", "some_val"]},
2039 %{
2040 "tuple" => [
2041 ":key3",
2042 %{
2043 ":max_expiration" => 31_536_000,
2044 ":max_option_chars" => 200,
2045 ":max_options" => 20,
2046 ":min_expiration" => 0,
2047 "nested" => %{
2048 ":max_expiration" => 31_536_000,
2049 ":max_option_chars" => 200,
2050 ":max_options" => 20,
2051 ":min_expiration" => 0
2052 }
2053 }
2054 ]
2055 }
2056 ]
2057 }
2058 ]
2059 }
2060 end
2061
2062 test "value as map", %{conn: conn} do
2063 conn =
2064 post(conn, "/api/pleroma/admin/config", %{
2065 configs: [
2066 %{
2067 "group" => "pleroma",
2068 "key" => ":key1",
2069 "value" => %{"key" => "some_val"}
2070 }
2071 ]
2072 })
2073
2074 assert json_response(conn, 200) ==
2075 %{
2076 "configs" => [
2077 %{
2078 "group" => "pleroma",
2079 "key" => ":key1",
2080 "value" => %{"key" => "some_val"}
2081 }
2082 ]
2083 }
2084 end
2085
2086 test "dispatch setting", %{conn: conn} do
2087 conn =
2088 post(conn, "/api/pleroma/admin/config", %{
2089 configs: [
2090 %{
2091 "group" => "pleroma",
2092 "key" => "Pleroma.Web.Endpoint.NotReal",
2093 "value" => [
2094 %{
2095 "tuple" => [
2096 ":http",
2097 [
2098 %{"tuple" => [":ip", %{"tuple" => [127, 0, 0, 1]}]},
2099 %{"tuple" => [":dispatch", ["{:_,
2100 [
2101 {\"/api/v1/streaming\", Pleroma.Web.MastodonAPI.WebsocketHandler, []},
2102 {\"/websocket\", Phoenix.Endpoint.CowboyWebSocket,
2103 {Phoenix.Transports.WebSocket,
2104 {Pleroma.Web.Endpoint, Pleroma.Web.UserSocket, [path: \"/websocket\"]}}},
2105 {:_, Phoenix.Endpoint.Cowboy2Handler, {Pleroma.Web.Endpoint, []}}
2106 ]}"]]}
2107 ]
2108 ]
2109 }
2110 ]
2111 }
2112 ]
2113 })
2114
2115 dispatch_string =
2116 "{:_, [{\"/api/v1/streaming\", Pleroma.Web.MastodonAPI.WebsocketHandler, []}, " <>
2117 "{\"/websocket\", Phoenix.Endpoint.CowboyWebSocket, {Phoenix.Transports.WebSocket, " <>
2118 "{Pleroma.Web.Endpoint, Pleroma.Web.UserSocket, [path: \"/websocket\"]}}}, " <>
2119 "{:_, Phoenix.Endpoint.Cowboy2Handler, {Pleroma.Web.Endpoint, []}}]}"
2120
2121 assert json_response(conn, 200) == %{
2122 "configs" => [
2123 %{
2124 "group" => "pleroma",
2125 "key" => "Pleroma.Web.Endpoint.NotReal",
2126 "value" => [
2127 %{
2128 "tuple" => [
2129 ":http",
2130 [
2131 %{"tuple" => [":ip", %{"tuple" => [127, 0, 0, 1]}]},
2132 %{
2133 "tuple" => [
2134 ":dispatch",
2135 [
2136 dispatch_string
2137 ]
2138 ]
2139 }
2140 ]
2141 ]
2142 }
2143 ]
2144 }
2145 ]
2146 }
2147 end
2148
2149 test "queues key as atom", %{conn: conn} do
2150 conn =
2151 post(conn, "/api/pleroma/admin/config", %{
2152 configs: [
2153 %{
2154 "group" => "oban",
2155 "key" => ":queues",
2156 "value" => [
2157 %{"tuple" => [":federator_incoming", 50]},
2158 %{"tuple" => [":federator_outgoing", 50]},
2159 %{"tuple" => [":web_push", 50]},
2160 %{"tuple" => [":mailer", 10]},
2161 %{"tuple" => [":transmogrifier", 20]},
2162 %{"tuple" => [":scheduled_activities", 10]},
2163 %{"tuple" => [":background", 5]}
2164 ]
2165 }
2166 ]
2167 })
2168
2169 assert json_response(conn, 200) == %{
2170 "configs" => [
2171 %{
2172 "group" => "oban",
2173 "key" => ":queues",
2174 "value" => [
2175 %{"tuple" => [":federator_incoming", 50]},
2176 %{"tuple" => [":federator_outgoing", 50]},
2177 %{"tuple" => [":web_push", 50]},
2178 %{"tuple" => [":mailer", 10]},
2179 %{"tuple" => [":transmogrifier", 20]},
2180 %{"tuple" => [":scheduled_activities", 10]},
2181 %{"tuple" => [":background", 5]}
2182 ]
2183 }
2184 ]
2185 }
2186 end
2187
2188 test "delete part of settings by atom subkeys", %{conn: conn} do
2189 config =
2190 insert(:config,
2191 key: "keyaa1",
2192 value: :erlang.term_to_binary(subkey1: "val1", subkey2: "val2", subkey3: "val3")
2193 )
2194
2195 conn =
2196 post(conn, "/api/pleroma/admin/config", %{
2197 configs: [
2198 %{
2199 group: config.group,
2200 key: config.key,
2201 subkeys: [":subkey1", ":subkey3"],
2202 delete: "true"
2203 }
2204 ]
2205 })
2206
2207 assert(
2208 json_response(conn, 200) == %{
2209 "configs" => [
2210 %{
2211 "group" => "pleroma",
2212 "key" => "keyaa1",
2213 "value" => [%{"tuple" => [":subkey2", "val2"]}]
2214 }
2215 ]
2216 }
2217 )
2218 end
2219 end
2220
2221 describe "config mix tasks run" do
2222 setup %{conn: conn} do
2223 admin = insert(:user, info: %{is_admin: true})
2224
2225 temp_file = "config/test.exported_from_db.secret.exs"
2226
2227 Mix.shell(Mix.Shell.Quiet)
2228
2229 on_exit(fn ->
2230 Mix.shell(Mix.Shell.IO)
2231 :ok = File.rm(temp_file)
2232 end)
2233
2234 %{conn: assign(conn, :user, admin), admin: admin}
2235 end
2236
2237 clear_config([:instance, :dynamic_configuration]) do
2238 Pleroma.Config.put([:instance, :dynamic_configuration], true)
2239 end
2240
2241 test "transfer settings to DB and to file", %{conn: conn, admin: admin} do
2242 assert Pleroma.Repo.all(Pleroma.Web.AdminAPI.Config) == []
2243 conn = get(conn, "/api/pleroma/admin/config/migrate_to_db")
2244 assert json_response(conn, 200) == %{}
2245 assert Pleroma.Repo.all(Pleroma.Web.AdminAPI.Config) > 0
2246
2247 conn =
2248 build_conn()
2249 |> assign(:user, admin)
2250 |> get("/api/pleroma/admin/config/migrate_from_db")
2251
2252 assert json_response(conn, 200) == %{}
2253 assert Pleroma.Repo.all(Pleroma.Web.AdminAPI.Config) == []
2254 end
2255 end
2256
2257 describe "GET /api/pleroma/admin/users/:nickname/statuses" do
2258 setup do
2259 admin = insert(:user, info: %{is_admin: true})
2260 user = insert(:user)
2261
2262 date1 = (DateTime.to_unix(DateTime.utc_now()) + 2000) |> DateTime.from_unix!()
2263 date2 = (DateTime.to_unix(DateTime.utc_now()) + 1000) |> DateTime.from_unix!()
2264 date3 = (DateTime.to_unix(DateTime.utc_now()) + 3000) |> DateTime.from_unix!()
2265
2266 insert(:note_activity, user: user, published: date1)
2267 insert(:note_activity, user: user, published: date2)
2268 insert(:note_activity, user: user, published: date3)
2269
2270 conn =
2271 build_conn()
2272 |> assign(:user, admin)
2273
2274 {:ok, conn: conn, user: user}
2275 end
2276
2277 test "renders user's statuses", %{conn: conn, user: user} do
2278 conn = get(conn, "/api/pleroma/admin/users/#{user.nickname}/statuses")
2279
2280 assert json_response(conn, 200) |> length() == 3
2281 end
2282
2283 test "renders user's statuses with a limit", %{conn: conn, user: user} do
2284 conn = get(conn, "/api/pleroma/admin/users/#{user.nickname}/statuses?page_size=2")
2285
2286 assert json_response(conn, 200) |> length() == 2
2287 end
2288
2289 test "doesn't return private statuses by default", %{conn: conn, user: user} do
2290 {:ok, _private_status} =
2291 CommonAPI.post(user, %{"status" => "private", "visibility" => "private"})
2292
2293 {:ok, _public_status} =
2294 CommonAPI.post(user, %{"status" => "public", "visibility" => "public"})
2295
2296 conn = get(conn, "/api/pleroma/admin/users/#{user.nickname}/statuses")
2297
2298 assert json_response(conn, 200) |> length() == 4
2299 end
2300
2301 test "returns private statuses with godmode on", %{conn: conn, user: user} do
2302 {:ok, _private_status} =
2303 CommonAPI.post(user, %{"status" => "private", "visibility" => "private"})
2304
2305 {:ok, _public_status} =
2306 CommonAPI.post(user, %{"status" => "public", "visibility" => "public"})
2307
2308 conn = get(conn, "/api/pleroma/admin/users/#{user.nickname}/statuses?godmode=true")
2309
2310 assert json_response(conn, 200) |> length() == 5
2311 end
2312 end
2313
2314 describe "GET /api/pleroma/admin/moderation_log" do
2315 setup %{conn: conn} do
2316 admin = insert(:user, info: %{is_admin: true})
2317 moderator = insert(:user, info: %{is_moderator: true})
2318
2319 %{conn: assign(conn, :user, admin), admin: admin, moderator: moderator}
2320 end
2321
2322 test "returns the log", %{conn: conn, admin: admin} do
2323 Repo.insert(%ModerationLog{
2324 data: %{
2325 actor: %{
2326 "id" => admin.id,
2327 "nickname" => admin.nickname,
2328 "type" => "user"
2329 },
2330 action: "relay_follow",
2331 target: "https://example.org/relay"
2332 },
2333 inserted_at: NaiveDateTime.truncate(~N[2017-08-15 15:47:06.597036], :second)
2334 })
2335
2336 Repo.insert(%ModerationLog{
2337 data: %{
2338 actor: %{
2339 "id" => admin.id,
2340 "nickname" => admin.nickname,
2341 "type" => "user"
2342 },
2343 action: "relay_unfollow",
2344 target: "https://example.org/relay"
2345 },
2346 inserted_at: NaiveDateTime.truncate(~N[2017-08-16 15:47:06.597036], :second)
2347 })
2348
2349 conn = get(conn, "/api/pleroma/admin/moderation_log")
2350
2351 response = json_response(conn, 200)
2352 [first_entry, second_entry] = response["items"]
2353
2354 assert response["total"] == 2
2355 assert first_entry["data"]["action"] == "relay_unfollow"
2356
2357 assert first_entry["message"] ==
2358 "@#{admin.nickname} unfollowed relay: https://example.org/relay"
2359
2360 assert second_entry["data"]["action"] == "relay_follow"
2361
2362 assert second_entry["message"] ==
2363 "@#{admin.nickname} followed relay: https://example.org/relay"
2364 end
2365
2366 test "returns the log with pagination", %{conn: conn, admin: admin} do
2367 Repo.insert(%ModerationLog{
2368 data: %{
2369 actor: %{
2370 "id" => admin.id,
2371 "nickname" => admin.nickname,
2372 "type" => "user"
2373 },
2374 action: "relay_follow",
2375 target: "https://example.org/relay"
2376 },
2377 inserted_at: NaiveDateTime.truncate(~N[2017-08-15 15:47:06.597036], :second)
2378 })
2379
2380 Repo.insert(%ModerationLog{
2381 data: %{
2382 actor: %{
2383 "id" => admin.id,
2384 "nickname" => admin.nickname,
2385 "type" => "user"
2386 },
2387 action: "relay_unfollow",
2388 target: "https://example.org/relay"
2389 },
2390 inserted_at: NaiveDateTime.truncate(~N[2017-08-16 15:47:06.597036], :second)
2391 })
2392
2393 conn1 = get(conn, "/api/pleroma/admin/moderation_log?page_size=1&page=1")
2394
2395 response1 = json_response(conn1, 200)
2396 [first_entry] = response1["items"]
2397
2398 assert response1["total"] == 2
2399 assert response1["items"] |> length() == 1
2400 assert first_entry["data"]["action"] == "relay_unfollow"
2401
2402 assert first_entry["message"] ==
2403 "@#{admin.nickname} unfollowed relay: https://example.org/relay"
2404
2405 conn2 = get(conn, "/api/pleroma/admin/moderation_log?page_size=1&page=2")
2406
2407 response2 = json_response(conn2, 200)
2408 [second_entry] = response2["items"]
2409
2410 assert response2["total"] == 2
2411 assert response2["items"] |> length() == 1
2412 assert second_entry["data"]["action"] == "relay_follow"
2413
2414 assert second_entry["message"] ==
2415 "@#{admin.nickname} followed relay: https://example.org/relay"
2416 end
2417
2418 test "filters log by date", %{conn: conn, admin: admin} do
2419 first_date = "2017-08-15T15:47:06Z"
2420 second_date = "2017-08-20T15:47:06Z"
2421
2422 Repo.insert(%ModerationLog{
2423 data: %{
2424 actor: %{
2425 "id" => admin.id,
2426 "nickname" => admin.nickname,
2427 "type" => "user"
2428 },
2429 action: "relay_follow",
2430 target: "https://example.org/relay"
2431 },
2432 inserted_at: NaiveDateTime.from_iso8601!(first_date)
2433 })
2434
2435 Repo.insert(%ModerationLog{
2436 data: %{
2437 actor: %{
2438 "id" => admin.id,
2439 "nickname" => admin.nickname,
2440 "type" => "user"
2441 },
2442 action: "relay_unfollow",
2443 target: "https://example.org/relay"
2444 },
2445 inserted_at: NaiveDateTime.from_iso8601!(second_date)
2446 })
2447
2448 conn1 =
2449 get(
2450 conn,
2451 "/api/pleroma/admin/moderation_log?start_date=#{second_date}"
2452 )
2453
2454 response1 = json_response(conn1, 200)
2455 [first_entry] = response1["items"]
2456
2457 assert response1["total"] == 1
2458 assert first_entry["data"]["action"] == "relay_unfollow"
2459
2460 assert first_entry["message"] ==
2461 "@#{admin.nickname} unfollowed relay: https://example.org/relay"
2462 end
2463
2464 test "returns log filtered by user", %{conn: conn, admin: admin, moderator: moderator} do
2465 Repo.insert(%ModerationLog{
2466 data: %{
2467 actor: %{
2468 "id" => admin.id,
2469 "nickname" => admin.nickname,
2470 "type" => "user"
2471 },
2472 action: "relay_follow",
2473 target: "https://example.org/relay"
2474 }
2475 })
2476
2477 Repo.insert(%ModerationLog{
2478 data: %{
2479 actor: %{
2480 "id" => moderator.id,
2481 "nickname" => moderator.nickname,
2482 "type" => "user"
2483 },
2484 action: "relay_unfollow",
2485 target: "https://example.org/relay"
2486 }
2487 })
2488
2489 conn1 = get(conn, "/api/pleroma/admin/moderation_log?user_id=#{moderator.id}")
2490
2491 response1 = json_response(conn1, 200)
2492 [first_entry] = response1["items"]
2493
2494 assert response1["total"] == 1
2495 assert get_in(first_entry, ["data", "actor", "id"]) == moderator.id
2496 end
2497
2498 test "returns log filtered by search", %{conn: conn, moderator: moderator} do
2499 ModerationLog.insert_log(%{
2500 actor: moderator,
2501 action: "relay_follow",
2502 target: "https://example.org/relay"
2503 })
2504
2505 ModerationLog.insert_log(%{
2506 actor: moderator,
2507 action: "relay_unfollow",
2508 target: "https://example.org/relay"
2509 })
2510
2511 conn1 = get(conn, "/api/pleroma/admin/moderation_log?search=unfo")
2512
2513 response1 = json_response(conn1, 200)
2514 [first_entry] = response1["items"]
2515
2516 assert response1["total"] == 1
2517
2518 assert get_in(first_entry, ["data", "message"]) ==
2519 "@#{moderator.nickname} unfollowed relay: https://example.org/relay"
2520 end
2521 end
2522
2523 describe "PATCH /users/:nickname/force_password_reset" do
2524 setup %{conn: conn} do
2525 admin = insert(:user, info: %{is_admin: true})
2526 user = insert(:user)
2527
2528 %{conn: assign(conn, :user, admin), admin: admin, user: user}
2529 end
2530
2531 test "sets password_reset_pending to true", %{admin: admin, user: user} do
2532 assert user.info.password_reset_pending == false
2533
2534 conn =
2535 build_conn()
2536 |> assign(:user, admin)
2537 |> patch("/api/pleroma/admin/users/#{user.nickname}/force_password_reset")
2538
2539 assert json_response(conn, 204) == ""
2540
2541 ObanHelpers.perform_all()
2542
2543 assert User.get_by_id(user.id).info.password_reset_pending == true
2544 end
2545 end
2546 end
2547
2548 # Needed for testing
2549 defmodule Pleroma.Web.Endpoint.NotReal do
2550 end
2551
2552 defmodule Pleroma.Captcha.NotReal do
2553 end