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