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