Add a view for the move notification
[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 "PUT /api/pleroma/admin/reports/:id" 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 %{conn: assign(conn, :user, admin), id: report_id, admin: admin}
1329 end
1330
1331 test "mark report as resolved", %{conn: conn, id: id, admin: admin} do
1332 response =
1333 conn
1334 |> put("/api/pleroma/admin/reports/#{id}", %{"state" => "resolved"})
1335 |> json_response(:ok)
1336
1337 assert response["state"] == "resolved"
1338
1339 log_entry = Repo.one(ModerationLog)
1340
1341 assert ModerationLog.get_log_entry_message(log_entry) ==
1342 "@#{admin.nickname} updated report ##{id} with 'resolved' state"
1343 end
1344
1345 test "closes report", %{conn: conn, id: id, admin: admin} do
1346 response =
1347 conn
1348 |> put("/api/pleroma/admin/reports/#{id}", %{"state" => "closed"})
1349 |> json_response(:ok)
1350
1351 assert response["state"] == "closed"
1352
1353 log_entry = Repo.one(ModerationLog)
1354
1355 assert ModerationLog.get_log_entry_message(log_entry) ==
1356 "@#{admin.nickname} updated report ##{id} with 'closed' state"
1357 end
1358
1359 test "returns 400 when state is unknown", %{conn: conn, id: id} do
1360 conn =
1361 conn
1362 |> put("/api/pleroma/admin/reports/#{id}", %{"state" => "test"})
1363
1364 assert json_response(conn, :bad_request) == "Unsupported state"
1365 end
1366
1367 test "returns 404 when report is not exist", %{conn: conn} do
1368 conn =
1369 conn
1370 |> put("/api/pleroma/admin/reports/test", %{"state" => "closed"})
1371
1372 assert json_response(conn, :not_found) == "Not found"
1373 end
1374 end
1375
1376 describe "GET /api/pleroma/admin/reports" do
1377 setup %{conn: conn} do
1378 admin = insert(:user, is_admin: true)
1379
1380 %{conn: assign(conn, :user, admin)}
1381 end
1382
1383 test "returns empty response when no reports created", %{conn: conn} do
1384 response =
1385 conn
1386 |> get("/api/pleroma/admin/reports")
1387 |> json_response(:ok)
1388
1389 assert Enum.empty?(response["reports"])
1390 assert response["total"] == 0
1391 end
1392
1393 test "returns reports", %{conn: conn} do
1394 [reporter, target_user] = insert_pair(:user)
1395 activity = insert(:note_activity, user: target_user)
1396
1397 {:ok, %{id: report_id}} =
1398 CommonAPI.report(reporter, %{
1399 "account_id" => target_user.id,
1400 "comment" => "I feel offended",
1401 "status_ids" => [activity.id]
1402 })
1403
1404 response =
1405 conn
1406 |> get("/api/pleroma/admin/reports")
1407 |> json_response(:ok)
1408
1409 [report] = response["reports"]
1410
1411 assert length(response["reports"]) == 1
1412 assert report["id"] == report_id
1413
1414 assert response["total"] == 1
1415 end
1416
1417 test "returns reports with specified state", %{conn: conn} do
1418 [reporter, target_user] = insert_pair(:user)
1419 activity = insert(:note_activity, user: target_user)
1420
1421 {:ok, %{id: first_report_id}} =
1422 CommonAPI.report(reporter, %{
1423 "account_id" => target_user.id,
1424 "comment" => "I feel offended",
1425 "status_ids" => [activity.id]
1426 })
1427
1428 {:ok, %{id: second_report_id}} =
1429 CommonAPI.report(reporter, %{
1430 "account_id" => target_user.id,
1431 "comment" => "I don't like this user"
1432 })
1433
1434 CommonAPI.update_report_state(second_report_id, "closed")
1435
1436 response =
1437 conn
1438 |> get("/api/pleroma/admin/reports", %{
1439 "state" => "open"
1440 })
1441 |> json_response(:ok)
1442
1443 [open_report] = response["reports"]
1444
1445 assert length(response["reports"]) == 1
1446 assert open_report["id"] == first_report_id
1447
1448 assert response["total"] == 1
1449
1450 response =
1451 conn
1452 |> get("/api/pleroma/admin/reports", %{
1453 "state" => "closed"
1454 })
1455 |> json_response(:ok)
1456
1457 [closed_report] = response["reports"]
1458
1459 assert length(response["reports"]) == 1
1460 assert closed_report["id"] == second_report_id
1461
1462 assert response["total"] == 1
1463
1464 response =
1465 conn
1466 |> get("/api/pleroma/admin/reports", %{
1467 "state" => "resolved"
1468 })
1469 |> json_response(:ok)
1470
1471 assert Enum.empty?(response["reports"])
1472 assert response["total"] == 0
1473 end
1474
1475 test "returns 403 when requested by a non-admin" do
1476 user = insert(:user)
1477
1478 conn =
1479 build_conn()
1480 |> assign(:user, user)
1481 |> get("/api/pleroma/admin/reports")
1482
1483 assert json_response(conn, :forbidden) == %{"error" => "User is not admin."}
1484 end
1485
1486 test "returns 403 when requested by anonymous" do
1487 conn =
1488 build_conn()
1489 |> get("/api/pleroma/admin/reports")
1490
1491 assert json_response(conn, :forbidden) == %{"error" => "Invalid credentials."}
1492 end
1493 end
1494
1495 #
1496 describe "POST /api/pleroma/admin/reports/:id/respond" do
1497 setup %{conn: conn} do
1498 admin = insert(:user, is_admin: true)
1499
1500 %{conn: assign(conn, :user, admin), admin: admin}
1501 end
1502
1503 test "returns created dm", %{conn: conn, admin: admin} do
1504 [reporter, target_user] = insert_pair(:user)
1505 activity = insert(:note_activity, user: target_user)
1506
1507 {:ok, %{id: report_id}} =
1508 CommonAPI.report(reporter, %{
1509 "account_id" => target_user.id,
1510 "comment" => "I feel offended",
1511 "status_ids" => [activity.id]
1512 })
1513
1514 response =
1515 conn
1516 |> post("/api/pleroma/admin/reports/#{report_id}/respond", %{
1517 "status" => "I will check it out"
1518 })
1519 |> json_response(:ok)
1520
1521 recipients = Enum.map(response["mentions"], & &1["username"])
1522
1523 assert reporter.nickname in recipients
1524 assert response["content"] == "I will check it out"
1525 assert response["visibility"] == "direct"
1526
1527 log_entry = Repo.one(ModerationLog)
1528
1529 assert ModerationLog.get_log_entry_message(log_entry) ==
1530 "@#{admin.nickname} responded with 'I will check it out' to report ##{
1531 response["id"]
1532 }"
1533 end
1534
1535 test "returns 400 when status is missing", %{conn: conn} do
1536 conn = post(conn, "/api/pleroma/admin/reports/test/respond")
1537
1538 assert json_response(conn, :bad_request) == "Invalid parameters"
1539 end
1540
1541 test "returns 404 when report id is invalid", %{conn: conn} do
1542 conn =
1543 post(conn, "/api/pleroma/admin/reports/test/respond", %{
1544 "status" => "foo"
1545 })
1546
1547 assert json_response(conn, :not_found) == "Not found"
1548 end
1549 end
1550
1551 describe "PUT /api/pleroma/admin/statuses/:id" do
1552 setup %{conn: conn} do
1553 admin = insert(:user, is_admin: true)
1554 activity = insert(:note_activity)
1555
1556 %{conn: assign(conn, :user, admin), id: activity.id, admin: admin}
1557 end
1558
1559 test "toggle sensitive flag", %{conn: conn, id: id, admin: admin} do
1560 response =
1561 conn
1562 |> put("/api/pleroma/admin/statuses/#{id}", %{"sensitive" => "true"})
1563 |> json_response(:ok)
1564
1565 assert response["sensitive"]
1566
1567 log_entry = Repo.one(ModerationLog)
1568
1569 assert ModerationLog.get_log_entry_message(log_entry) ==
1570 "@#{admin.nickname} updated status ##{id}, set sensitive: 'true'"
1571
1572 response =
1573 conn
1574 |> put("/api/pleroma/admin/statuses/#{id}", %{"sensitive" => "false"})
1575 |> json_response(:ok)
1576
1577 refute response["sensitive"]
1578 end
1579
1580 test "change visibility flag", %{conn: conn, id: id, admin: admin} do
1581 response =
1582 conn
1583 |> put("/api/pleroma/admin/statuses/#{id}", %{"visibility" => "public"})
1584 |> json_response(:ok)
1585
1586 assert response["visibility"] == "public"
1587
1588 log_entry = Repo.one(ModerationLog)
1589
1590 assert ModerationLog.get_log_entry_message(log_entry) ==
1591 "@#{admin.nickname} updated status ##{id}, set visibility: 'public'"
1592
1593 response =
1594 conn
1595 |> put("/api/pleroma/admin/statuses/#{id}", %{"visibility" => "private"})
1596 |> json_response(:ok)
1597
1598 assert response["visibility"] == "private"
1599
1600 response =
1601 conn
1602 |> put("/api/pleroma/admin/statuses/#{id}", %{"visibility" => "unlisted"})
1603 |> json_response(:ok)
1604
1605 assert response["visibility"] == "unlisted"
1606 end
1607
1608 test "returns 400 when visibility is unknown", %{conn: conn, id: id} do
1609 conn =
1610 conn
1611 |> put("/api/pleroma/admin/statuses/#{id}", %{"visibility" => "test"})
1612
1613 assert json_response(conn, :bad_request) == "Unsupported visibility"
1614 end
1615 end
1616
1617 describe "DELETE /api/pleroma/admin/statuses/:id" do
1618 setup %{conn: conn} do
1619 admin = insert(:user, is_admin: true)
1620 activity = insert(:note_activity)
1621
1622 %{conn: assign(conn, :user, admin), id: activity.id, admin: admin}
1623 end
1624
1625 test "deletes status", %{conn: conn, id: id, admin: admin} do
1626 conn
1627 |> delete("/api/pleroma/admin/statuses/#{id}")
1628 |> json_response(:ok)
1629
1630 refute Activity.get_by_id(id)
1631
1632 log_entry = Repo.one(ModerationLog)
1633
1634 assert ModerationLog.get_log_entry_message(log_entry) ==
1635 "@#{admin.nickname} deleted status ##{id}"
1636 end
1637
1638 test "returns error when status is not exist", %{conn: conn} do
1639 conn =
1640 conn
1641 |> delete("/api/pleroma/admin/statuses/test")
1642
1643 assert json_response(conn, :bad_request) == "Could not delete"
1644 end
1645 end
1646
1647 describe "GET /api/pleroma/admin/config" do
1648 setup %{conn: conn} do
1649 admin = insert(:user, is_admin: true)
1650
1651 %{conn: assign(conn, :user, admin)}
1652 end
1653
1654 test "without any settings in db", %{conn: conn} do
1655 conn = get(conn, "/api/pleroma/admin/config")
1656
1657 assert json_response(conn, 200) == %{"configs" => []}
1658 end
1659
1660 test "with settings in db", %{conn: conn} do
1661 config1 = insert(:config)
1662 config2 = insert(:config)
1663
1664 conn = get(conn, "/api/pleroma/admin/config")
1665
1666 %{
1667 "configs" => [
1668 %{
1669 "key" => key1,
1670 "value" => _
1671 },
1672 %{
1673 "key" => key2,
1674 "value" => _
1675 }
1676 ]
1677 } = json_response(conn, 200)
1678
1679 assert key1 == config1.key
1680 assert key2 == config2.key
1681 end
1682 end
1683
1684 describe "POST /api/pleroma/admin/config" do
1685 setup %{conn: conn} do
1686 admin = insert(:user, is_admin: true)
1687
1688 temp_file = "config/test.exported_from_db.secret.exs"
1689
1690 on_exit(fn ->
1691 Application.delete_env(:pleroma, :key1)
1692 Application.delete_env(:pleroma, :key2)
1693 Application.delete_env(:pleroma, :key3)
1694 Application.delete_env(:pleroma, :key4)
1695 Application.delete_env(:pleroma, :keyaa1)
1696 Application.delete_env(:pleroma, :keyaa2)
1697 Application.delete_env(:pleroma, Pleroma.Web.Endpoint.NotReal)
1698 Application.delete_env(:pleroma, Pleroma.Captcha.NotReal)
1699 :ok = File.rm(temp_file)
1700 end)
1701
1702 %{conn: assign(conn, :user, admin)}
1703 end
1704
1705 clear_config([:instance, :dynamic_configuration]) do
1706 Pleroma.Config.put([:instance, :dynamic_configuration], true)
1707 end
1708
1709 test "create new config setting in db", %{conn: conn} do
1710 conn =
1711 post(conn, "/api/pleroma/admin/config", %{
1712 configs: [
1713 %{group: "pleroma", key: "key1", value: "value1"},
1714 %{
1715 group: "ueberauth",
1716 key: "Ueberauth.Strategy.Twitter.OAuth",
1717 value: [%{"tuple" => [":consumer_secret", "aaaa"]}]
1718 },
1719 %{
1720 group: "pleroma",
1721 key: "key2",
1722 value: %{
1723 ":nested_1" => "nested_value1",
1724 ":nested_2" => [
1725 %{":nested_22" => "nested_value222"},
1726 %{":nested_33" => %{":nested_44" => "nested_444"}}
1727 ]
1728 }
1729 },
1730 %{
1731 group: "pleroma",
1732 key: "key3",
1733 value: [
1734 %{"nested_3" => ":nested_3", "nested_33" => "nested_33"},
1735 %{"nested_4" => true}
1736 ]
1737 },
1738 %{
1739 group: "pleroma",
1740 key: "key4",
1741 value: %{":nested_5" => ":upload", "endpoint" => "https://example.com"}
1742 },
1743 %{
1744 group: "idna",
1745 key: "key5",
1746 value: %{"tuple" => ["string", "Pleroma.Captcha.NotReal", []]}
1747 }
1748 ]
1749 })
1750
1751 assert json_response(conn, 200) == %{
1752 "configs" => [
1753 %{
1754 "group" => "pleroma",
1755 "key" => "key1",
1756 "value" => "value1"
1757 },
1758 %{
1759 "group" => "ueberauth",
1760 "key" => "Ueberauth.Strategy.Twitter.OAuth",
1761 "value" => [%{"tuple" => [":consumer_secret", "aaaa"]}]
1762 },
1763 %{
1764 "group" => "pleroma",
1765 "key" => "key2",
1766 "value" => %{
1767 ":nested_1" => "nested_value1",
1768 ":nested_2" => [
1769 %{":nested_22" => "nested_value222"},
1770 %{":nested_33" => %{":nested_44" => "nested_444"}}
1771 ]
1772 }
1773 },
1774 %{
1775 "group" => "pleroma",
1776 "key" => "key3",
1777 "value" => [
1778 %{"nested_3" => ":nested_3", "nested_33" => "nested_33"},
1779 %{"nested_4" => true}
1780 ]
1781 },
1782 %{
1783 "group" => "pleroma",
1784 "key" => "key4",
1785 "value" => %{"endpoint" => "https://example.com", ":nested_5" => ":upload"}
1786 },
1787 %{
1788 "group" => "idna",
1789 "key" => "key5",
1790 "value" => %{"tuple" => ["string", "Pleroma.Captcha.NotReal", []]}
1791 }
1792 ]
1793 }
1794
1795 assert Application.get_env(:pleroma, :key1) == "value1"
1796
1797 assert Application.get_env(:pleroma, :key2) == %{
1798 nested_1: "nested_value1",
1799 nested_2: [
1800 %{nested_22: "nested_value222"},
1801 %{nested_33: %{nested_44: "nested_444"}}
1802 ]
1803 }
1804
1805 assert Application.get_env(:pleroma, :key3) == [
1806 %{"nested_3" => :nested_3, "nested_33" => "nested_33"},
1807 %{"nested_4" => true}
1808 ]
1809
1810 assert Application.get_env(:pleroma, :key4) == %{
1811 "endpoint" => "https://example.com",
1812 nested_5: :upload
1813 }
1814
1815 assert Application.get_env(:idna, :key5) == {"string", Pleroma.Captcha.NotReal, []}
1816 end
1817
1818 test "update config setting & delete", %{conn: conn} do
1819 config1 = insert(:config, key: "keyaa1")
1820 config2 = insert(:config, key: "keyaa2")
1821
1822 insert(:config,
1823 group: "ueberauth",
1824 key: "Ueberauth.Strategy.Microsoft.OAuth",
1825 value: :erlang.term_to_binary([])
1826 )
1827
1828 conn =
1829 post(conn, "/api/pleroma/admin/config", %{
1830 configs: [
1831 %{group: config1.group, key: config1.key, value: "another_value"},
1832 %{group: config2.group, key: config2.key, delete: "true"},
1833 %{
1834 group: "ueberauth",
1835 key: "Ueberauth.Strategy.Microsoft.OAuth",
1836 delete: "true"
1837 }
1838 ]
1839 })
1840
1841 assert json_response(conn, 200) == %{
1842 "configs" => [
1843 %{
1844 "group" => "pleroma",
1845 "key" => config1.key,
1846 "value" => "another_value"
1847 }
1848 ]
1849 }
1850
1851 assert Application.get_env(:pleroma, :keyaa1) == "another_value"
1852 refute Application.get_env(:pleroma, :keyaa2)
1853 end
1854
1855 test "common config example", %{conn: conn} do
1856 conn =
1857 post(conn, "/api/pleroma/admin/config", %{
1858 configs: [
1859 %{
1860 "group" => "pleroma",
1861 "key" => "Pleroma.Captcha.NotReal",
1862 "value" => [
1863 %{"tuple" => [":enabled", false]},
1864 %{"tuple" => [":method", "Pleroma.Captcha.Kocaptcha"]},
1865 %{"tuple" => [":seconds_valid", 60]},
1866 %{"tuple" => [":path", ""]},
1867 %{"tuple" => [":key1", nil]},
1868 %{"tuple" => [":partial_chain", "&:hackney_connect.partial_chain/1"]},
1869 %{"tuple" => [":regex1", "~r/https:\/\/example.com/"]},
1870 %{"tuple" => [":regex2", "~r/https:\/\/example.com/u"]},
1871 %{"tuple" => [":regex3", "~r/https:\/\/example.com/i"]},
1872 %{"tuple" => [":regex4", "~r/https:\/\/example.com/s"]}
1873 ]
1874 }
1875 ]
1876 })
1877
1878 assert json_response(conn, 200) == %{
1879 "configs" => [
1880 %{
1881 "group" => "pleroma",
1882 "key" => "Pleroma.Captcha.NotReal",
1883 "value" => [
1884 %{"tuple" => [":enabled", false]},
1885 %{"tuple" => [":method", "Pleroma.Captcha.Kocaptcha"]},
1886 %{"tuple" => [":seconds_valid", 60]},
1887 %{"tuple" => [":path", ""]},
1888 %{"tuple" => [":key1", nil]},
1889 %{"tuple" => [":partial_chain", "&:hackney_connect.partial_chain/1"]},
1890 %{"tuple" => [":regex1", "~r/https:\\/\\/example.com/"]},
1891 %{"tuple" => [":regex2", "~r/https:\\/\\/example.com/u"]},
1892 %{"tuple" => [":regex3", "~r/https:\\/\\/example.com/i"]},
1893 %{"tuple" => [":regex4", "~r/https:\\/\\/example.com/s"]}
1894 ]
1895 }
1896 ]
1897 }
1898 end
1899
1900 test "tuples with more than two values", %{conn: conn} do
1901 conn =
1902 post(conn, "/api/pleroma/admin/config", %{
1903 configs: [
1904 %{
1905 "group" => "pleroma",
1906 "key" => "Pleroma.Web.Endpoint.NotReal",
1907 "value" => [
1908 %{
1909 "tuple" => [
1910 ":http",
1911 [
1912 %{
1913 "tuple" => [
1914 ":key2",
1915 [
1916 %{
1917 "tuple" => [
1918 ":_",
1919 [
1920 %{
1921 "tuple" => [
1922 "/api/v1/streaming",
1923 "Pleroma.Web.MastodonAPI.WebsocketHandler",
1924 []
1925 ]
1926 },
1927 %{
1928 "tuple" => [
1929 "/websocket",
1930 "Phoenix.Endpoint.CowboyWebSocket",
1931 %{
1932 "tuple" => [
1933 "Phoenix.Transports.WebSocket",
1934 %{
1935 "tuple" => [
1936 "Pleroma.Web.Endpoint",
1937 "Pleroma.Web.UserSocket",
1938 []
1939 ]
1940 }
1941 ]
1942 }
1943 ]
1944 },
1945 %{
1946 "tuple" => [
1947 ":_",
1948 "Phoenix.Endpoint.Cowboy2Handler",
1949 %{"tuple" => ["Pleroma.Web.Endpoint", []]}
1950 ]
1951 }
1952 ]
1953 ]
1954 }
1955 ]
1956 ]
1957 }
1958 ]
1959 ]
1960 }
1961 ]
1962 }
1963 ]
1964 })
1965
1966 assert json_response(conn, 200) == %{
1967 "configs" => [
1968 %{
1969 "group" => "pleroma",
1970 "key" => "Pleroma.Web.Endpoint.NotReal",
1971 "value" => [
1972 %{
1973 "tuple" => [
1974 ":http",
1975 [
1976 %{
1977 "tuple" => [
1978 ":key2",
1979 [
1980 %{
1981 "tuple" => [
1982 ":_",
1983 [
1984 %{
1985 "tuple" => [
1986 "/api/v1/streaming",
1987 "Pleroma.Web.MastodonAPI.WebsocketHandler",
1988 []
1989 ]
1990 },
1991 %{
1992 "tuple" => [
1993 "/websocket",
1994 "Phoenix.Endpoint.CowboyWebSocket",
1995 %{
1996 "tuple" => [
1997 "Phoenix.Transports.WebSocket",
1998 %{
1999 "tuple" => [
2000 "Pleroma.Web.Endpoint",
2001 "Pleroma.Web.UserSocket",
2002 []
2003 ]
2004 }
2005 ]
2006 }
2007 ]
2008 },
2009 %{
2010 "tuple" => [
2011 ":_",
2012 "Phoenix.Endpoint.Cowboy2Handler",
2013 %{"tuple" => ["Pleroma.Web.Endpoint", []]}
2014 ]
2015 }
2016 ]
2017 ]
2018 }
2019 ]
2020 ]
2021 }
2022 ]
2023 ]
2024 }
2025 ]
2026 }
2027 ]
2028 }
2029 end
2030
2031 test "settings with nesting map", %{conn: conn} do
2032 conn =
2033 post(conn, "/api/pleroma/admin/config", %{
2034 configs: [
2035 %{
2036 "group" => "pleroma",
2037 "key" => ":key1",
2038 "value" => [
2039 %{"tuple" => [":key2", "some_val"]},
2040 %{
2041 "tuple" => [
2042 ":key3",
2043 %{
2044 ":max_options" => 20,
2045 ":max_option_chars" => 200,
2046 ":min_expiration" => 0,
2047 ":max_expiration" => 31_536_000,
2048 "nested" => %{
2049 ":max_options" => 20,
2050 ":max_option_chars" => 200,
2051 ":min_expiration" => 0,
2052 ":max_expiration" => 31_536_000
2053 }
2054 }
2055 ]
2056 }
2057 ]
2058 }
2059 ]
2060 })
2061
2062 assert json_response(conn, 200) ==
2063 %{
2064 "configs" => [
2065 %{
2066 "group" => "pleroma",
2067 "key" => ":key1",
2068 "value" => [
2069 %{"tuple" => [":key2", "some_val"]},
2070 %{
2071 "tuple" => [
2072 ":key3",
2073 %{
2074 ":max_expiration" => 31_536_000,
2075 ":max_option_chars" => 200,
2076 ":max_options" => 20,
2077 ":min_expiration" => 0,
2078 "nested" => %{
2079 ":max_expiration" => 31_536_000,
2080 ":max_option_chars" => 200,
2081 ":max_options" => 20,
2082 ":min_expiration" => 0
2083 }
2084 }
2085 ]
2086 }
2087 ]
2088 }
2089 ]
2090 }
2091 end
2092
2093 test "value as map", %{conn: conn} do
2094 conn =
2095 post(conn, "/api/pleroma/admin/config", %{
2096 configs: [
2097 %{
2098 "group" => "pleroma",
2099 "key" => ":key1",
2100 "value" => %{"key" => "some_val"}
2101 }
2102 ]
2103 })
2104
2105 assert json_response(conn, 200) ==
2106 %{
2107 "configs" => [
2108 %{
2109 "group" => "pleroma",
2110 "key" => ":key1",
2111 "value" => %{"key" => "some_val"}
2112 }
2113 ]
2114 }
2115 end
2116
2117 test "dispatch setting", %{conn: conn} do
2118 conn =
2119 post(conn, "/api/pleroma/admin/config", %{
2120 configs: [
2121 %{
2122 "group" => "pleroma",
2123 "key" => "Pleroma.Web.Endpoint.NotReal",
2124 "value" => [
2125 %{
2126 "tuple" => [
2127 ":http",
2128 [
2129 %{"tuple" => [":ip", %{"tuple" => [127, 0, 0, 1]}]},
2130 %{"tuple" => [":dispatch", ["{:_,
2131 [
2132 {\"/api/v1/streaming\", Pleroma.Web.MastodonAPI.WebsocketHandler, []},
2133 {\"/websocket\", Phoenix.Endpoint.CowboyWebSocket,
2134 {Phoenix.Transports.WebSocket,
2135 {Pleroma.Web.Endpoint, Pleroma.Web.UserSocket, [path: \"/websocket\"]}}},
2136 {:_, Phoenix.Endpoint.Cowboy2Handler, {Pleroma.Web.Endpoint, []}}
2137 ]}"]]}
2138 ]
2139 ]
2140 }
2141 ]
2142 }
2143 ]
2144 })
2145
2146 dispatch_string =
2147 "{:_, [{\"/api/v1/streaming\", Pleroma.Web.MastodonAPI.WebsocketHandler, []}, " <>
2148 "{\"/websocket\", Phoenix.Endpoint.CowboyWebSocket, {Phoenix.Transports.WebSocket, " <>
2149 "{Pleroma.Web.Endpoint, Pleroma.Web.UserSocket, [path: \"/websocket\"]}}}, " <>
2150 "{:_, Phoenix.Endpoint.Cowboy2Handler, {Pleroma.Web.Endpoint, []}}]}"
2151
2152 assert json_response(conn, 200) == %{
2153 "configs" => [
2154 %{
2155 "group" => "pleroma",
2156 "key" => "Pleroma.Web.Endpoint.NotReal",
2157 "value" => [
2158 %{
2159 "tuple" => [
2160 ":http",
2161 [
2162 %{"tuple" => [":ip", %{"tuple" => [127, 0, 0, 1]}]},
2163 %{
2164 "tuple" => [
2165 ":dispatch",
2166 [
2167 dispatch_string
2168 ]
2169 ]
2170 }
2171 ]
2172 ]
2173 }
2174 ]
2175 }
2176 ]
2177 }
2178 end
2179
2180 test "queues key as atom", %{conn: conn} do
2181 conn =
2182 post(conn, "/api/pleroma/admin/config", %{
2183 configs: [
2184 %{
2185 "group" => "oban",
2186 "key" => ":queues",
2187 "value" => [
2188 %{"tuple" => [":federator_incoming", 50]},
2189 %{"tuple" => [":federator_outgoing", 50]},
2190 %{"tuple" => [":web_push", 50]},
2191 %{"tuple" => [":mailer", 10]},
2192 %{"tuple" => [":transmogrifier", 20]},
2193 %{"tuple" => [":scheduled_activities", 10]},
2194 %{"tuple" => [":background", 5]}
2195 ]
2196 }
2197 ]
2198 })
2199
2200 assert json_response(conn, 200) == %{
2201 "configs" => [
2202 %{
2203 "group" => "oban",
2204 "key" => ":queues",
2205 "value" => [
2206 %{"tuple" => [":federator_incoming", 50]},
2207 %{"tuple" => [":federator_outgoing", 50]},
2208 %{"tuple" => [":web_push", 50]},
2209 %{"tuple" => [":mailer", 10]},
2210 %{"tuple" => [":transmogrifier", 20]},
2211 %{"tuple" => [":scheduled_activities", 10]},
2212 %{"tuple" => [":background", 5]}
2213 ]
2214 }
2215 ]
2216 }
2217 end
2218
2219 test "delete part of settings by atom subkeys", %{conn: conn} do
2220 config =
2221 insert(:config,
2222 key: "keyaa1",
2223 value: :erlang.term_to_binary(subkey1: "val1", subkey2: "val2", subkey3: "val3")
2224 )
2225
2226 conn =
2227 post(conn, "/api/pleroma/admin/config", %{
2228 configs: [
2229 %{
2230 group: config.group,
2231 key: config.key,
2232 subkeys: [":subkey1", ":subkey3"],
2233 delete: "true"
2234 }
2235 ]
2236 })
2237
2238 assert(
2239 json_response(conn, 200) == %{
2240 "configs" => [
2241 %{
2242 "group" => "pleroma",
2243 "key" => "keyaa1",
2244 "value" => [%{"tuple" => [":subkey2", "val2"]}]
2245 }
2246 ]
2247 }
2248 )
2249 end
2250 end
2251
2252 describe "config mix tasks run" do
2253 setup %{conn: conn} do
2254 admin = insert(:user, is_admin: true)
2255
2256 temp_file = "config/test.exported_from_db.secret.exs"
2257
2258 Mix.shell(Mix.Shell.Quiet)
2259
2260 on_exit(fn ->
2261 Mix.shell(Mix.Shell.IO)
2262 :ok = File.rm(temp_file)
2263 end)
2264
2265 %{conn: assign(conn, :user, admin), admin: admin}
2266 end
2267
2268 clear_config([:instance, :dynamic_configuration]) do
2269 Pleroma.Config.put([:instance, :dynamic_configuration], true)
2270 end
2271
2272 clear_config([:feed, :post_title]) do
2273 Pleroma.Config.put([:feed, :post_title], %{max_length: 100, omission: "…"})
2274 end
2275
2276 test "transfer settings to DB and to file", %{conn: conn, admin: admin} do
2277 assert Pleroma.Repo.all(Pleroma.Web.AdminAPI.Config) == []
2278 conn = get(conn, "/api/pleroma/admin/config/migrate_to_db")
2279 assert json_response(conn, 200) == %{}
2280 assert Pleroma.Repo.all(Pleroma.Web.AdminAPI.Config) > 0
2281
2282 conn =
2283 build_conn()
2284 |> assign(:user, admin)
2285 |> get("/api/pleroma/admin/config/migrate_from_db")
2286
2287 assert json_response(conn, 200) == %{}
2288 assert Pleroma.Repo.all(Pleroma.Web.AdminAPI.Config) == []
2289 end
2290 end
2291
2292 describe "GET /api/pleroma/admin/users/:nickname/statuses" do
2293 setup do
2294 admin = insert(:user, is_admin: true)
2295 user = insert(:user)
2296
2297 date1 = (DateTime.to_unix(DateTime.utc_now()) + 2000) |> DateTime.from_unix!()
2298 date2 = (DateTime.to_unix(DateTime.utc_now()) + 1000) |> DateTime.from_unix!()
2299 date3 = (DateTime.to_unix(DateTime.utc_now()) + 3000) |> DateTime.from_unix!()
2300
2301 insert(:note_activity, user: user, published: date1)
2302 insert(:note_activity, user: user, published: date2)
2303 insert(:note_activity, user: user, published: date3)
2304
2305 conn =
2306 build_conn()
2307 |> assign(:user, admin)
2308
2309 {:ok, conn: conn, user: user}
2310 end
2311
2312 test "renders user's statuses", %{conn: conn, user: user} do
2313 conn = get(conn, "/api/pleroma/admin/users/#{user.nickname}/statuses")
2314
2315 assert json_response(conn, 200) |> length() == 3
2316 end
2317
2318 test "renders user's statuses with a limit", %{conn: conn, user: user} do
2319 conn = get(conn, "/api/pleroma/admin/users/#{user.nickname}/statuses?page_size=2")
2320
2321 assert json_response(conn, 200) |> length() == 2
2322 end
2323
2324 test "doesn't return private statuses by default", %{conn: conn, user: user} do
2325 {:ok, _private_status} =
2326 CommonAPI.post(user, %{"status" => "private", "visibility" => "private"})
2327
2328 {:ok, _public_status} =
2329 CommonAPI.post(user, %{"status" => "public", "visibility" => "public"})
2330
2331 conn = get(conn, "/api/pleroma/admin/users/#{user.nickname}/statuses")
2332
2333 assert json_response(conn, 200) |> length() == 4
2334 end
2335
2336 test "returns private statuses with godmode on", %{conn: conn, user: user} do
2337 {:ok, _private_status} =
2338 CommonAPI.post(user, %{"status" => "private", "visibility" => "private"})
2339
2340 {:ok, _public_status} =
2341 CommonAPI.post(user, %{"status" => "public", "visibility" => "public"})
2342
2343 conn = get(conn, "/api/pleroma/admin/users/#{user.nickname}/statuses?godmode=true")
2344
2345 assert json_response(conn, 200) |> length() == 5
2346 end
2347 end
2348
2349 describe "GET /api/pleroma/admin/moderation_log" do
2350 setup %{conn: conn} do
2351 admin = insert(:user, is_admin: true)
2352 moderator = insert(:user, is_moderator: true)
2353
2354 %{conn: assign(conn, :user, admin), admin: admin, moderator: moderator}
2355 end
2356
2357 test "returns the log", %{conn: conn, admin: admin} do
2358 Repo.insert(%ModerationLog{
2359 data: %{
2360 actor: %{
2361 "id" => admin.id,
2362 "nickname" => admin.nickname,
2363 "type" => "user"
2364 },
2365 action: "relay_follow",
2366 target: "https://example.org/relay"
2367 },
2368 inserted_at: NaiveDateTime.truncate(~N[2017-08-15 15:47:06.597036], :second)
2369 })
2370
2371 Repo.insert(%ModerationLog{
2372 data: %{
2373 actor: %{
2374 "id" => admin.id,
2375 "nickname" => admin.nickname,
2376 "type" => "user"
2377 },
2378 action: "relay_unfollow",
2379 target: "https://example.org/relay"
2380 },
2381 inserted_at: NaiveDateTime.truncate(~N[2017-08-16 15:47:06.597036], :second)
2382 })
2383
2384 conn = get(conn, "/api/pleroma/admin/moderation_log")
2385
2386 response = json_response(conn, 200)
2387 [first_entry, second_entry] = response["items"]
2388
2389 assert response["total"] == 2
2390 assert first_entry["data"]["action"] == "relay_unfollow"
2391
2392 assert first_entry["message"] ==
2393 "@#{admin.nickname} unfollowed relay: https://example.org/relay"
2394
2395 assert second_entry["data"]["action"] == "relay_follow"
2396
2397 assert second_entry["message"] ==
2398 "@#{admin.nickname} followed relay: https://example.org/relay"
2399 end
2400
2401 test "returns the log with pagination", %{conn: conn, admin: admin} do
2402 Repo.insert(%ModerationLog{
2403 data: %{
2404 actor: %{
2405 "id" => admin.id,
2406 "nickname" => admin.nickname,
2407 "type" => "user"
2408 },
2409 action: "relay_follow",
2410 target: "https://example.org/relay"
2411 },
2412 inserted_at: NaiveDateTime.truncate(~N[2017-08-15 15:47:06.597036], :second)
2413 })
2414
2415 Repo.insert(%ModerationLog{
2416 data: %{
2417 actor: %{
2418 "id" => admin.id,
2419 "nickname" => admin.nickname,
2420 "type" => "user"
2421 },
2422 action: "relay_unfollow",
2423 target: "https://example.org/relay"
2424 },
2425 inserted_at: NaiveDateTime.truncate(~N[2017-08-16 15:47:06.597036], :second)
2426 })
2427
2428 conn1 = get(conn, "/api/pleroma/admin/moderation_log?page_size=1&page=1")
2429
2430 response1 = json_response(conn1, 200)
2431 [first_entry] = response1["items"]
2432
2433 assert response1["total"] == 2
2434 assert response1["items"] |> length() == 1
2435 assert first_entry["data"]["action"] == "relay_unfollow"
2436
2437 assert first_entry["message"] ==
2438 "@#{admin.nickname} unfollowed relay: https://example.org/relay"
2439
2440 conn2 = get(conn, "/api/pleroma/admin/moderation_log?page_size=1&page=2")
2441
2442 response2 = json_response(conn2, 200)
2443 [second_entry] = response2["items"]
2444
2445 assert response2["total"] == 2
2446 assert response2["items"] |> length() == 1
2447 assert second_entry["data"]["action"] == "relay_follow"
2448
2449 assert second_entry["message"] ==
2450 "@#{admin.nickname} followed relay: https://example.org/relay"
2451 end
2452
2453 test "filters log by date", %{conn: conn, admin: admin} do
2454 first_date = "2017-08-15T15:47:06Z"
2455 second_date = "2017-08-20T15:47:06Z"
2456
2457 Repo.insert(%ModerationLog{
2458 data: %{
2459 actor: %{
2460 "id" => admin.id,
2461 "nickname" => admin.nickname,
2462 "type" => "user"
2463 },
2464 action: "relay_follow",
2465 target: "https://example.org/relay"
2466 },
2467 inserted_at: NaiveDateTime.from_iso8601!(first_date)
2468 })
2469
2470 Repo.insert(%ModerationLog{
2471 data: %{
2472 actor: %{
2473 "id" => admin.id,
2474 "nickname" => admin.nickname,
2475 "type" => "user"
2476 },
2477 action: "relay_unfollow",
2478 target: "https://example.org/relay"
2479 },
2480 inserted_at: NaiveDateTime.from_iso8601!(second_date)
2481 })
2482
2483 conn1 =
2484 get(
2485 conn,
2486 "/api/pleroma/admin/moderation_log?start_date=#{second_date}"
2487 )
2488
2489 response1 = json_response(conn1, 200)
2490 [first_entry] = response1["items"]
2491
2492 assert response1["total"] == 1
2493 assert first_entry["data"]["action"] == "relay_unfollow"
2494
2495 assert first_entry["message"] ==
2496 "@#{admin.nickname} unfollowed relay: https://example.org/relay"
2497 end
2498
2499 test "returns log filtered by user", %{conn: conn, admin: admin, moderator: moderator} do
2500 Repo.insert(%ModerationLog{
2501 data: %{
2502 actor: %{
2503 "id" => admin.id,
2504 "nickname" => admin.nickname,
2505 "type" => "user"
2506 },
2507 action: "relay_follow",
2508 target: "https://example.org/relay"
2509 }
2510 })
2511
2512 Repo.insert(%ModerationLog{
2513 data: %{
2514 actor: %{
2515 "id" => moderator.id,
2516 "nickname" => moderator.nickname,
2517 "type" => "user"
2518 },
2519 action: "relay_unfollow",
2520 target: "https://example.org/relay"
2521 }
2522 })
2523
2524 conn1 = get(conn, "/api/pleroma/admin/moderation_log?user_id=#{moderator.id}")
2525
2526 response1 = json_response(conn1, 200)
2527 [first_entry] = response1["items"]
2528
2529 assert response1["total"] == 1
2530 assert get_in(first_entry, ["data", "actor", "id"]) == moderator.id
2531 end
2532
2533 test "returns log filtered by search", %{conn: conn, moderator: moderator} do
2534 ModerationLog.insert_log(%{
2535 actor: moderator,
2536 action: "relay_follow",
2537 target: "https://example.org/relay"
2538 })
2539
2540 ModerationLog.insert_log(%{
2541 actor: moderator,
2542 action: "relay_unfollow",
2543 target: "https://example.org/relay"
2544 })
2545
2546 conn1 = get(conn, "/api/pleroma/admin/moderation_log?search=unfo")
2547
2548 response1 = json_response(conn1, 200)
2549 [first_entry] = response1["items"]
2550
2551 assert response1["total"] == 1
2552
2553 assert get_in(first_entry, ["data", "message"]) ==
2554 "@#{moderator.nickname} unfollowed relay: https://example.org/relay"
2555 end
2556 end
2557
2558 describe "PATCH /users/:nickname/force_password_reset" do
2559 setup %{conn: conn} do
2560 admin = insert(:user, is_admin: true)
2561 user = insert(:user)
2562
2563 %{conn: assign(conn, :user, admin), admin: admin, user: user}
2564 end
2565
2566 test "sets password_reset_pending to true", %{admin: admin, user: user} do
2567 assert user.password_reset_pending == false
2568
2569 conn =
2570 build_conn()
2571 |> assign(:user, admin)
2572 |> patch("/api/pleroma/admin/users/force_password_reset", %{nicknames: [user.nickname]})
2573
2574 assert json_response(conn, 204) == ""
2575
2576 ObanHelpers.perform_all()
2577
2578 assert User.get_by_id(user.id).password_reset_pending == true
2579 end
2580 end
2581
2582 describe "relays" do
2583 setup %{conn: conn} do
2584 admin = insert(:user, is_admin: true)
2585
2586 %{conn: assign(conn, :user, admin), admin: admin}
2587 end
2588
2589 test "POST /relay", %{admin: admin} do
2590 conn =
2591 build_conn()
2592 |> assign(:user, admin)
2593 |> post("/api/pleroma/admin/relay", %{
2594 relay_url: "http://mastodon.example.org/users/admin"
2595 })
2596
2597 assert json_response(conn, 200) == "http://mastodon.example.org/users/admin"
2598
2599 log_entry = Repo.one(ModerationLog)
2600
2601 assert ModerationLog.get_log_entry_message(log_entry) ==
2602 "@#{admin.nickname} followed relay: http://mastodon.example.org/users/admin"
2603 end
2604
2605 test "GET /relay", %{admin: admin} do
2606 relay_user = Pleroma.Web.ActivityPub.Relay.get_actor()
2607
2608 ["http://mastodon.example.org/users/admin", "https://mstdn.io/users/mayuutann"]
2609 |> Enum.each(fn ap_id ->
2610 {:ok, user} = User.get_or_fetch_by_ap_id(ap_id)
2611 User.follow(relay_user, user)
2612 end)
2613
2614 conn =
2615 build_conn()
2616 |> assign(:user, admin)
2617 |> get("/api/pleroma/admin/relay")
2618
2619 assert json_response(conn, 200)["relays"] -- ["mastodon.example.org", "mstdn.io"] == []
2620 end
2621
2622 test "DELETE /relay", %{admin: admin} do
2623 build_conn()
2624 |> assign(:user, admin)
2625 |> post("/api/pleroma/admin/relay", %{
2626 relay_url: "http://mastodon.example.org/users/admin"
2627 })
2628
2629 conn =
2630 build_conn()
2631 |> assign(:user, admin)
2632 |> delete("/api/pleroma/admin/relay", %{
2633 relay_url: "http://mastodon.example.org/users/admin"
2634 })
2635
2636 assert json_response(conn, 200) == "http://mastodon.example.org/users/admin"
2637
2638 [log_entry_one, log_entry_two] = Repo.all(ModerationLog)
2639
2640 assert ModerationLog.get_log_entry_message(log_entry_one) ==
2641 "@#{admin.nickname} followed relay: http://mastodon.example.org/users/admin"
2642
2643 assert ModerationLog.get_log_entry_message(log_entry_two) ==
2644 "@#{admin.nickname} unfollowed relay: http://mastodon.example.org/users/admin"
2645 end
2646 end
2647 end
2648
2649 # Needed for testing
2650 defmodule Pleroma.Web.Endpoint.NotReal do
2651 end
2652
2653 defmodule Pleroma.Captcha.NotReal do
2654 end