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