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