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