1 # Pleroma: A lightweight social networking server
2 # Copyright © 2017-2019 Pleroma Authors <https://pleroma.social/>
3 # SPDX-License-Identifier: AGPL-3.0-only
5 defmodule Pleroma.Web.AdminAPI.AdminAPIControllerTest do
6 use Pleroma.Web.ConnCase
7 use Oban.Testing, repo: Pleroma.Repo
11 alias Pleroma.ModerationLog
13 alias Pleroma.Tests.ObanHelpers
15 alias Pleroma.UserInviteToken
16 alias Pleroma.Web.CommonAPI
17 alias Pleroma.Web.MediaProxy
18 import Pleroma.Factory
21 Tesla.Mock.mock_global(fn env -> apply(HttpRequestMock, :request, [env]) end)
26 describe "/api/pleroma/admin/users" do
28 admin = insert(:user, info: %{is_admin: true})
33 |> assign(:user, admin)
34 |> put_req_header("accept", "application/json")
35 |> delete("/api/pleroma/admin/users?nickname=#{user.nickname}")
37 log_entry = Repo.one(ModerationLog)
39 assert log_entry.data["subject"]["nickname"] == user.nickname
40 assert log_entry.data["action"] == "delete"
42 assert ModerationLog.get_log_entry_message(log_entry) ==
43 "@#{admin.nickname} deleted user @#{user.nickname}"
45 assert json_response(conn, 200) == user.nickname
49 admin = insert(:user, info: %{is_admin: true})
53 |> assign(:user, admin)
54 |> put_req_header("accept", "application/json")
55 |> post("/api/pleroma/admin/users", %{
59 "email" => "lain@example.org",
63 "nickname" => "lain2",
64 "email" => "lain2@example.org",
70 response = json_response(conn, 200) |> Enum.map(&Map.get(&1, "type"))
71 assert response == ["success", "success"]
73 log_entry = Repo.one(ModerationLog)
75 assert ["lain", "lain2"] -- Enum.map(log_entry.data["subjects"], & &1["nickname"]) == []
78 test "Cannot create user with exisiting email" do
79 admin = insert(:user, info: %{is_admin: true})
84 |> assign(:user, admin)
85 |> put_req_header("accept", "application/json")
86 |> post("/api/pleroma/admin/users", %{
90 "email" => user.email,
96 assert json_response(conn, 409) == [
100 "email" => user.email,
103 "error" => "email has already been taken",
109 test "Cannot create user with exisiting nickname" do
110 admin = insert(:user, info: %{is_admin: true})
115 |> assign(:user, admin)
116 |> put_req_header("accept", "application/json")
117 |> post("/api/pleroma/admin/users", %{
120 "nickname" => user.nickname,
121 "email" => "someuser@plerama.social",
127 assert json_response(conn, 409) == [
131 "email" => "someuser@plerama.social",
132 "nickname" => user.nickname
134 "error" => "nickname has already been taken",
140 test "Multiple user creation works in transaction" do
141 admin = insert(:user, info: %{is_admin: true})
146 |> assign(:user, admin)
147 |> put_req_header("accept", "application/json")
148 |> post("/api/pleroma/admin/users", %{
151 "nickname" => "newuser",
152 "email" => "newuser@pleroma.social",
156 "nickname" => "lain",
157 "email" => user.email,
163 assert json_response(conn, 409) == [
167 "email" => user.email,
170 "error" => "email has already been taken",
176 "email" => "newuser@pleroma.social",
177 "nickname" => "newuser"
184 assert User.get_by_nickname("newuser") === nil
188 describe "/api/pleroma/admin/users/:nickname" do
189 test "Show", %{conn: conn} do
190 admin = insert(:user, info: %{is_admin: true})
195 |> assign(:user, admin)
196 |> get("/api/pleroma/admin/users/#{user.nickname}")
199 "deactivated" => false,
200 "id" => to_string(user.id),
202 "nickname" => user.nickname,
203 "roles" => %{"admin" => false, "moderator" => false},
205 "avatar" => User.avatar_url(user) |> MediaProxy.url(),
206 "display_name" => HTML.strip_tags(user.name || user.nickname)
209 assert expected == json_response(conn, 200)
212 test "when the user doesn't exist", %{conn: conn} do
213 admin = insert(:user, info: %{is_admin: true})
218 |> assign(:user, admin)
219 |> get("/api/pleroma/admin/users/#{user.nickname}")
221 assert "Not found" == json_response(conn, 404)
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})
229 follower = insert(:user)
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
239 user = User.get_cached_by_id(user.id)
240 follower = User.get_cached_by_id(follower.id)
242 assert User.following?(follower, user)
244 log_entry = Repo.one(ModerationLog)
246 assert ModerationLog.get_log_entry_message(log_entry) ==
247 "@#{admin.nickname} made @#{follower.nickname} follow @#{user.nickname}"
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})
255 follower = insert(:user)
257 User.follow(follower, user)
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
267 user = User.get_cached_by_id(user.id)
268 follower = User.get_cached_by_id(follower.id)
270 refute User.following?(follower, user)
272 log_entry = Repo.one(ModerationLog)
274 assert ModerationLog.get_log_entry_message(log_entry) ==
275 "@#{admin.nickname} made @#{follower.nickname} unfollow @#{user.nickname}"
279 describe "PUT /api/pleroma/admin/users/tag" 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"]})
288 |> assign(:user, admin)
289 |> put_req_header("accept", "application/json")
291 "/api/pleroma/admin/users/tag?nicknames[]=#{user1.nickname}&nicknames[]=#{
293 }&tags[]=foo&tags[]=bar"
296 %{conn: conn, admin: admin, user1: user1, user2: user2, user3: user3}
299 test "it appends specified tags to users with specified nicknames", %{
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"]
309 log_entry = Repo.one(ModerationLog)
312 [user1.nickname, user2.nickname]
313 |> Enum.map(&"@#{&1}")
316 tags = ["foo", "bar"] |> Enum.join(", ")
318 assert ModerationLog.get_log_entry_message(log_entry) ==
319 "@#{admin.nickname} added tags: #{tags} to users: #{users}"
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"]
328 describe "DELETE /api/pleroma/admin/users/tag" 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"]})
337 |> assign(:user, admin)
338 |> put_req_header("accept", "application/json")
340 "/api/pleroma/admin/users/tag?nicknames[]=#{user1.nickname}&nicknames[]=#{
345 %{conn: conn, admin: admin, user1: user1, user2: user2, user3: user3}
348 test "it removes specified tags from users with specified nicknames", %{
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"]
358 log_entry = Repo.one(ModerationLog)
361 [user1.nickname, user2.nickname]
362 |> Enum.map(&"@#{&1}")
365 tags = ["x", "z"] |> Enum.join(", ")
367 assert ModerationLog.get_log_entry_message(log_entry) ==
368 "@#{admin.nickname} removed tags: #{tags} from users: #{users}"
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"]
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})
383 |> assign(:user, admin)
384 |> put_req_header("accept", "application/json")
385 |> get("/api/pleroma/admin/users/#{admin.nickname}/permission_group/")
387 assert json_response(conn, 200) == %{
389 "is_moderator" => false
393 test "/:right POST, can add to a permission group" do
394 admin = insert(:user, info: %{is_admin: true})
399 |> assign(:user, admin)
400 |> put_req_header("accept", "application/json")
401 |> post("/api/pleroma/admin/users/#{user.nickname}/permission_group/admin")
403 assert json_response(conn, 200) == %{
407 log_entry = Repo.one(ModerationLog)
409 assert ModerationLog.get_log_entry_message(log_entry) ==
410 "@#{admin.nickname} made @#{user.nickname} admin"
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})
419 |> assign(:user, admin)
420 |> put_req_header("accept", "application/json")
421 |> delete("/api/pleroma/admin/users/#{user.nickname}/permission_group/admin")
423 assert json_response(conn, 200) == %{
427 log_entry = Repo.one(ModerationLog)
429 assert ModerationLog.get_log_entry_message(log_entry) ==
430 "@#{admin.nickname} revoked admin role from @#{user.nickname}"
434 describe "PUT /api/pleroma/admin/users/:nickname/activation_status" do
435 setup %{conn: conn} do
436 admin = insert(:user, info: %{is_admin: true})
440 |> assign(:user, admin)
441 |> put_req_header("accept", "application/json")
443 %{conn: conn, admin: admin}
446 test "deactivates the user", %{conn: conn, admin: admin} do
451 |> put("/api/pleroma/admin/users/#{user.nickname}/activation_status", %{status: false})
453 user = User.get_cached_by_id(user.id)
454 assert user.info.deactivated == true
455 assert json_response(conn, :no_content)
457 log_entry = Repo.one(ModerationLog)
459 assert ModerationLog.get_log_entry_message(log_entry) ==
460 "@#{admin.nickname} deactivated user @#{user.nickname}"
463 test "activates the user", %{conn: conn, admin: admin} do
464 user = insert(:user, info: %{deactivated: true})
468 |> put("/api/pleroma/admin/users/#{user.nickname}/activation_status", %{status: true})
470 user = User.get_cached_by_id(user.id)
471 assert user.info.deactivated == false
472 assert json_response(conn, :no_content)
474 log_entry = Repo.one(ModerationLog)
476 assert ModerationLog.get_log_entry_message(log_entry) ==
477 "@#{admin.nickname} activated user @#{user.nickname}"
480 test "returns 403 when requested by a non-admin", %{conn: conn} do
485 |> assign(:user, user)
486 |> put("/api/pleroma/admin/users/#{user.nickname}/activation_status", %{status: false})
488 assert json_response(conn, :forbidden)
492 describe "POST /api/pleroma/admin/email_invite, with valid config" do
494 [user: insert(:user, info: %{is_admin: true})]
497 clear_config([:instance, :registrations_open]) do
498 Pleroma.Config.put([:instance, :registrations_open], false)
501 clear_config([:instance, :invites_enabled]) do
502 Pleroma.Config.put([:instance, :invites_enabled], true)
505 test "sends invitation and returns 204", %{conn: conn, user: user} do
506 recipient_email = "foo@bar.com"
507 recipient_name = "J. D."
511 |> assign(:user, user)
513 "/api/pleroma/admin/users/email_invite?email=#{recipient_email}&name=#{recipient_name}"
516 assert json_response(conn, :no_content)
518 token_record = List.last(Pleroma.Repo.all(Pleroma.UserInviteToken))
520 refute token_record.used
522 notify_email = Pleroma.Config.get([:instance, :notify_email])
523 instance_name = Pleroma.Config.get([:instance, :name])
526 Pleroma.Emails.UserEmail.user_invitation_email(
533 Swoosh.TestAssertions.assert_email_sent(
534 from: {instance_name, notify_email},
535 to: {recipient_name, recipient_email},
536 html_body: email.html_body
540 test "it returns 403 if requested by a non-admin", %{conn: conn} do
541 non_admin_user = insert(:user)
545 |> assign(:user, non_admin_user)
546 |> post("/api/pleroma/admin/users/email_invite?email=foo@bar.com&name=JD")
548 assert json_response(conn, :forbidden)
552 describe "POST /api/pleroma/admin/users/email_invite, with invalid config" do
554 [user: insert(:user, info: %{is_admin: true})]
557 clear_config([:instance, :registrations_open])
558 clear_config([:instance, :invites_enabled])
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)
566 |> assign(:user, user)
567 |> post("/api/pleroma/admin/users/email_invite?email=foo@bar.com&name=JD")
569 assert json_response(conn, :internal_server_error)
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)
578 |> assign(:user, user)
579 |> post("/api/pleroma/admin/users/email_invite?email=foo@bar.com&name=JD")
581 assert json_response(conn, :internal_server_error)
585 test "/api/pleroma/admin/users/:nickname/password_reset" do
586 admin = insert(:user, info: %{is_admin: true})
591 |> assign(:user, admin)
592 |> put_req_header("accept", "application/json")
593 |> get("/api/pleroma/admin/users/#{user.nickname}/password_reset")
595 resp = json_response(conn, 200)
597 assert Regex.match?(~r/(http:\/\/|https:\/\/)/, resp["link"])
600 describe "GET /api/pleroma/admin/users" do
602 admin = insert(:user, info: %{is_admin: true})
606 |> assign(:user, admin)
608 {:ok, conn: conn, admin: admin}
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")
618 "deactivated" => admin.info.deactivated,
620 "nickname" => admin.nickname,
621 "roles" => %{"admin" => true, "moderator" => false},
624 "avatar" => User.avatar_url(admin) |> MediaProxy.url(),
625 "display_name" => HTML.strip_tags(admin.name || admin.nickname)
628 "deactivated" => user.info.deactivated,
630 "nickname" => user.nickname,
631 "roles" => %{"admin" => false, "moderator" => false},
633 "tags" => ["foo", "bar"],
634 "avatar" => User.avatar_url(user) |> MediaProxy.url(),
635 "display_name" => HTML.strip_tags(user.name || user.nickname)
638 |> Enum.sort_by(& &1["nickname"])
640 assert json_response(conn, 200) == %{
647 test "renders empty array for the second page", %{conn: conn} do
650 conn = get(conn, "/api/pleroma/admin/users?page=2")
652 assert json_response(conn, 200) == %{
659 test "regular search", %{conn: conn} do
660 user = insert(:user, nickname: "bob")
662 conn = get(conn, "/api/pleroma/admin/users?query=bo")
664 assert json_response(conn, 200) == %{
669 "deactivated" => user.info.deactivated,
671 "nickname" => user.nickname,
672 "roles" => %{"admin" => false, "moderator" => false},
675 "avatar" => User.avatar_url(user) |> MediaProxy.url(),
676 "display_name" => HTML.strip_tags(user.name || user.nickname)
682 test "search by domain", %{conn: conn} do
683 user = insert(:user, nickname: "nickname@domain.com")
686 conn = get(conn, "/api/pleroma/admin/users?query=domain.com")
688 assert json_response(conn, 200) == %{
693 "deactivated" => user.info.deactivated,
695 "nickname" => user.nickname,
696 "roles" => %{"admin" => false, "moderator" => false},
699 "avatar" => User.avatar_url(user) |> MediaProxy.url(),
700 "display_name" => HTML.strip_tags(user.name || user.nickname)
706 test "search by full nickname", %{conn: conn} do
707 user = insert(:user, nickname: "nickname@domain.com")
710 conn = get(conn, "/api/pleroma/admin/users?query=nickname@domain.com")
712 assert json_response(conn, 200) == %{
717 "deactivated" => user.info.deactivated,
719 "nickname" => user.nickname,
720 "roles" => %{"admin" => false, "moderator" => false},
723 "avatar" => User.avatar_url(user) |> MediaProxy.url(),
724 "display_name" => HTML.strip_tags(user.name || user.nickname)
730 test "search by display name", %{conn: conn} do
731 user = insert(:user, name: "Display name")
734 conn = get(conn, "/api/pleroma/admin/users?name=display")
736 assert json_response(conn, 200) == %{
741 "deactivated" => user.info.deactivated,
743 "nickname" => user.nickname,
744 "roles" => %{"admin" => false, "moderator" => false},
747 "avatar" => User.avatar_url(user) |> MediaProxy.url(),
748 "display_name" => HTML.strip_tags(user.name || user.nickname)
754 test "search by email", %{conn: conn} do
755 user = insert(:user, email: "email@example.com")
758 conn = get(conn, "/api/pleroma/admin/users?email=email@example.com")
760 assert json_response(conn, 200) == %{
765 "deactivated" => user.info.deactivated,
767 "nickname" => user.nickname,
768 "roles" => %{"admin" => false, "moderator" => false},
771 "avatar" => User.avatar_url(user) |> MediaProxy.url(),
772 "display_name" => HTML.strip_tags(user.name || user.nickname)
778 test "regular search with page size", %{conn: conn} do
779 user = insert(:user, nickname: "aalice")
780 user2 = insert(:user, nickname: "alice")
782 conn1 = get(conn, "/api/pleroma/admin/users?query=a&page_size=1&page=1")
784 assert json_response(conn1, 200) == %{
789 "deactivated" => user.info.deactivated,
791 "nickname" => user.nickname,
792 "roles" => %{"admin" => false, "moderator" => false},
795 "avatar" => User.avatar_url(user) |> MediaProxy.url(),
796 "display_name" => HTML.strip_tags(user.name || user.nickname)
801 conn2 = get(conn, "/api/pleroma/admin/users?query=a&page_size=1&page=2")
803 assert json_response(conn2, 200) == %{
808 "deactivated" => user2.info.deactivated,
810 "nickname" => user2.nickname,
811 "roles" => %{"admin" => false, "moderator" => false},
814 "avatar" => User.avatar_url(user2) |> MediaProxy.url(),
815 "display_name" => HTML.strip_tags(user2.name || user2.nickname)
821 test "only local users" do
822 admin = insert(:user, info: %{is_admin: true}, nickname: "john")
823 user = insert(:user, nickname: "bob")
825 insert(:user, nickname: "bobb", local: false)
829 |> assign(:user, admin)
830 |> get("/api/pleroma/admin/users?query=bo&filters=local")
832 assert json_response(conn, 200) == %{
837 "deactivated" => user.info.deactivated,
839 "nickname" => user.nickname,
840 "roles" => %{"admin" => false, "moderator" => false},
843 "avatar" => User.avatar_url(user) |> MediaProxy.url(),
844 "display_name" => HTML.strip_tags(user.name || user.nickname)
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")
854 insert(:user, nickname: "bobb", local: false)
858 |> assign(:user, admin)
859 |> get("/api/pleroma/admin/users?filters=local")
864 "deactivated" => user.info.deactivated,
866 "nickname" => user.nickname,
867 "roles" => %{"admin" => false, "moderator" => false},
870 "avatar" => User.avatar_url(user) |> MediaProxy.url(),
871 "display_name" => HTML.strip_tags(user.name || user.nickname)
874 "deactivated" => admin.info.deactivated,
876 "nickname" => admin.nickname,
877 "roles" => %{"admin" => true, "moderator" => false},
880 "avatar" => User.avatar_url(admin) |> MediaProxy.url(),
881 "display_name" => HTML.strip_tags(admin.name || admin.nickname)
884 "deactivated" => false,
885 "id" => old_admin.id,
887 "nickname" => old_admin.nickname,
888 "roles" => %{"admin" => true, "moderator" => false},
890 "avatar" => User.avatar_url(old_admin) |> MediaProxy.url(),
891 "display_name" => HTML.strip_tags(old_admin.name || old_admin.nickname)
894 |> Enum.sort_by(& &1["nickname"])
896 assert json_response(conn, 200) == %{
903 test "load only admins", %{conn: conn, admin: admin} do
904 second_admin = insert(:user, info: %{is_admin: true})
908 conn = get(conn, "/api/pleroma/admin/users?filters=is_admin")
913 "deactivated" => false,
915 "nickname" => admin.nickname,
916 "roles" => %{"admin" => true, "moderator" => false},
917 "local" => admin.local,
919 "avatar" => User.avatar_url(admin) |> MediaProxy.url(),
920 "display_name" => HTML.strip_tags(admin.name || admin.nickname)
923 "deactivated" => false,
924 "id" => second_admin.id,
925 "nickname" => second_admin.nickname,
926 "roles" => %{"admin" => true, "moderator" => false},
927 "local" => second_admin.local,
929 "avatar" => User.avatar_url(second_admin) |> MediaProxy.url(),
930 "display_name" => HTML.strip_tags(second_admin.name || second_admin.nickname)
933 |> Enum.sort_by(& &1["nickname"])
935 assert json_response(conn, 200) == %{
942 test "load only moderators", %{conn: conn} do
943 moderator = insert(:user, info: %{is_moderator: true})
947 conn = get(conn, "/api/pleroma/admin/users?filters=is_moderator")
949 assert json_response(conn, 200) == %{
954 "deactivated" => false,
955 "id" => moderator.id,
956 "nickname" => moderator.nickname,
957 "roles" => %{"admin" => false, "moderator" => true},
958 "local" => moderator.local,
960 "avatar" => User.avatar_url(moderator) |> MediaProxy.url(),
961 "display_name" => HTML.strip_tags(moderator.name || moderator.nickname)
967 test "load users with tags list", %{conn: conn} do
968 user1 = insert(:user, tags: ["first"])
969 user2 = insert(:user, tags: ["second"])
973 conn = get(conn, "/api/pleroma/admin/users?tags[]=first&tags[]=second")
978 "deactivated" => false,
980 "nickname" => user1.nickname,
981 "roles" => %{"admin" => false, "moderator" => false},
982 "local" => user1.local,
984 "avatar" => User.avatar_url(user1) |> MediaProxy.url(),
985 "display_name" => HTML.strip_tags(user1.name || user1.nickname)
988 "deactivated" => false,
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)
998 |> Enum.sort_by(& &1["nickname"])
1000 assert json_response(conn, 200) == %{
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})
1011 insert(:user, nickname: "ken", local: true, info: %{deactivated: true})
1012 insert(:user, nickname: "bobb", local: false, info: %{deactivated: false})
1016 |> assign(:user, admin)
1017 |> get("/api/pleroma/admin/users?filters=deactivated,external")
1019 assert json_response(conn, 200) == %{
1024 "deactivated" => user.info.deactivated,
1026 "nickname" => user.nickname,
1027 "roles" => %{"admin" => false, "moderator" => false},
1028 "local" => user.local,
1030 "avatar" => User.avatar_url(user) |> MediaProxy.url(),
1031 "display_name" => HTML.strip_tags(user.name || user.nickname)
1038 test "PATCH /api/pleroma/admin/users/:nickname/toggle_activation" do
1039 admin = insert(:user, info: %{is_admin: true})
1040 user = insert(:user)
1044 |> assign(:user, admin)
1045 |> patch("/api/pleroma/admin/users/#{user.nickname}/toggle_activation")
1047 assert json_response(conn, 200) ==
1049 "deactivated" => !user.info.deactivated,
1051 "nickname" => user.nickname,
1052 "roles" => %{"admin" => false, "moderator" => false},
1055 "avatar" => User.avatar_url(user) |> MediaProxy.url(),
1056 "display_name" => HTML.strip_tags(user.name || user.nickname)
1059 log_entry = Repo.one(ModerationLog)
1061 assert ModerationLog.get_log_entry_message(log_entry) ==
1062 "@#{admin.nickname} deactivated user @#{user.nickname}"
1065 describe "POST /api/pleroma/admin/users/invite_token" do
1067 admin = insert(:user, info: %{is_admin: true})
1071 |> assign(:user, admin)
1076 test "without options", %{conn: conn} do
1077 conn = post(conn, "/api/pleroma/admin/users/invite_token")
1079 invite_json = json_response(conn, 200)
1080 invite = UserInviteToken.find_by_token!(invite_json["token"])
1082 refute invite.expires_at
1083 refute invite.max_use
1084 assert invite.invite_type == "one_time"
1087 test "with expires_at", %{conn: conn} do
1089 post(conn, "/api/pleroma/admin/users/invite_token", %{
1090 "expires_at" => Date.to_string(Date.utc_today())
1093 invite_json = json_response(conn, 200)
1094 invite = UserInviteToken.find_by_token!(invite_json["token"])
1097 assert invite.expires_at == Date.utc_today()
1098 refute invite.max_use
1099 assert invite.invite_type == "date_limited"
1102 test "with max_use", %{conn: conn} do
1103 conn = post(conn, "/api/pleroma/admin/users/invite_token", %{"max_use" => 150})
1105 invite_json = json_response(conn, 200)
1106 invite = UserInviteToken.find_by_token!(invite_json["token"])
1108 refute invite.expires_at
1109 assert invite.max_use == 150
1110 assert invite.invite_type == "reusable"
1113 test "with max use and expires_at", %{conn: conn} do
1115 post(conn, "/api/pleroma/admin/users/invite_token", %{
1117 "expires_at" => Date.to_string(Date.utc_today())
1120 invite_json = json_response(conn, 200)
1121 invite = UserInviteToken.find_by_token!(invite_json["token"])
1123 assert invite.expires_at == Date.utc_today()
1124 assert invite.max_use == 150
1125 assert invite.invite_type == "reusable_date_limited"
1129 describe "GET /api/pleroma/admin/users/invites" do
1131 admin = insert(:user, info: %{is_admin: true})
1135 |> assign(:user, admin)
1140 test "no invites", %{conn: conn} do
1141 conn = get(conn, "/api/pleroma/admin/users/invites")
1143 assert json_response(conn, 200) == %{"invites" => []}
1146 test "with invite", %{conn: conn} do
1147 {:ok, invite} = UserInviteToken.create_invite()
1149 conn = get(conn, "/api/pleroma/admin/users/invites")
1151 assert json_response(conn, 200) == %{
1154 "expires_at" => nil,
1156 "invite_type" => "one_time",
1158 "token" => invite.token,
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()
1174 |> assign(:user, admin)
1175 |> post("/api/pleroma/admin/users/revoke_invite", %{"token" => invite.token})
1177 assert json_response(conn, 200) == %{
1178 "expires_at" => nil,
1180 "invite_type" => "one_time",
1182 "token" => invite.token,
1188 test "with invalid token" do
1189 admin = insert(:user, info: %{is_admin: true})
1193 |> assign(:user, admin)
1194 |> post("/api/pleroma/admin/users/revoke_invite", %{"token" => "foo"})
1196 assert json_response(conn, :not_found) == "Not found"
1200 describe "GET /api/pleroma/admin/reports/:id" do
1201 setup %{conn: conn} do
1202 admin = insert(:user, info: %{is_admin: true})
1204 %{conn: assign(conn, :user, admin)}
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)
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]
1220 |> get("/api/pleroma/admin/reports/#{report_id}")
1221 |> json_response(:ok)
1223 assert response["id"] == report_id
1226 test "returns 404 when report id is invalid", %{conn: conn} do
1227 conn = get(conn, "/api/pleroma/admin/reports/test")
1229 assert json_response(conn, :not_found) == "Not found"
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)
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]
1246 %{conn: assign(conn, :user, admin), id: report_id, admin: admin}
1249 test "mark report as resolved", %{conn: conn, id: id, admin: admin} do
1252 |> put("/api/pleroma/admin/reports/#{id}", %{"state" => "resolved"})
1253 |> json_response(:ok)
1255 assert response["state"] == "resolved"
1257 log_entry = Repo.one(ModerationLog)
1259 assert ModerationLog.get_log_entry_message(log_entry) ==
1260 "@#{admin.nickname} updated report ##{id} with 'resolved' state"
1263 test "closes report", %{conn: conn, id: id, admin: admin} do
1266 |> put("/api/pleroma/admin/reports/#{id}", %{"state" => "closed"})
1267 |> json_response(:ok)
1269 assert response["state"] == "closed"
1271 log_entry = Repo.one(ModerationLog)
1273 assert ModerationLog.get_log_entry_message(log_entry) ==
1274 "@#{admin.nickname} updated report ##{id} with 'closed' state"
1277 test "returns 400 when state is unknown", %{conn: conn, id: id} do
1280 |> put("/api/pleroma/admin/reports/#{id}", %{"state" => "test"})
1282 assert json_response(conn, :bad_request) == "Unsupported state"
1285 test "returns 404 when report is not exist", %{conn: conn} do
1288 |> put("/api/pleroma/admin/reports/test", %{"state" => "closed"})
1290 assert json_response(conn, :not_found) == "Not found"
1294 describe "GET /api/pleroma/admin/reports" do
1295 setup %{conn: conn} do
1296 admin = insert(:user, info: %{is_admin: true})
1298 %{conn: assign(conn, :user, admin)}
1301 test "returns empty response when no reports created", %{conn: conn} do
1304 |> get("/api/pleroma/admin/reports")
1305 |> json_response(:ok)
1307 assert Enum.empty?(response["reports"])
1308 assert response["total"] == 0
1311 test "returns reports", %{conn: conn} do
1312 [reporter, target_user] = insert_pair(:user)
1313 activity = insert(:note_activity, user: target_user)
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]
1324 |> get("/api/pleroma/admin/reports")
1325 |> json_response(:ok)
1327 [report] = response["reports"]
1329 assert length(response["reports"]) == 1
1330 assert report["id"] == report_id
1332 assert response["total"] == 1
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)
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]
1346 {:ok, %{id: second_report_id}} =
1347 CommonAPI.report(reporter, %{
1348 "account_id" => target_user.id,
1349 "comment" => "I don't like this user"
1352 CommonAPI.update_report_state(second_report_id, "closed")
1356 |> get("/api/pleroma/admin/reports", %{
1359 |> json_response(:ok)
1361 [open_report] = response["reports"]
1363 assert length(response["reports"]) == 1
1364 assert open_report["id"] == first_report_id
1366 assert response["total"] == 1
1370 |> get("/api/pleroma/admin/reports", %{
1373 |> json_response(:ok)
1375 [closed_report] = response["reports"]
1377 assert length(response["reports"]) == 1
1378 assert closed_report["id"] == second_report_id
1380 assert response["total"] == 1
1384 |> get("/api/pleroma/admin/reports", %{
1385 "state" => "resolved"
1387 |> json_response(:ok)
1389 assert Enum.empty?(response["reports"])
1390 assert response["total"] == 0
1393 test "returns 403 when requested by a non-admin" do
1394 user = insert(:user)
1398 |> assign(:user, user)
1399 |> get("/api/pleroma/admin/reports")
1401 assert json_response(conn, :forbidden) == %{"error" => "User is not admin."}
1404 test "returns 403 when requested by anonymous" do
1407 |> get("/api/pleroma/admin/reports")
1409 assert json_response(conn, :forbidden) == %{"error" => "Invalid credentials."}
1414 describe "POST /api/pleroma/admin/reports/:id/respond" do
1415 setup %{conn: conn} do
1416 admin = insert(:user, info: %{is_admin: true})
1418 %{conn: assign(conn, :user, admin), admin: admin}
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)
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]
1434 |> post("/api/pleroma/admin/reports/#{report_id}/respond", %{
1435 "status" => "I will check it out"
1437 |> json_response(:ok)
1439 recipients = Enum.map(response["mentions"], & &1["username"])
1441 assert reporter.nickname in recipients
1442 assert response["content"] == "I will check it out"
1443 assert response["visibility"] == "direct"
1445 log_entry = Repo.one(ModerationLog)
1447 assert ModerationLog.get_log_entry_message(log_entry) ==
1448 "@#{admin.nickname} responded with 'I will check it out' to report ##{
1453 test "returns 400 when status is missing", %{conn: conn} do
1454 conn = post(conn, "/api/pleroma/admin/reports/test/respond")
1456 assert json_response(conn, :bad_request) == "Invalid parameters"
1459 test "returns 404 when report id is invalid", %{conn: conn} do
1461 post(conn, "/api/pleroma/admin/reports/test/respond", %{
1465 assert json_response(conn, :not_found) == "Not found"
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)
1474 %{conn: assign(conn, :user, admin), id: activity.id, admin: admin}
1477 test "toggle sensitive flag", %{conn: conn, id: id, admin: admin} do
1480 |> put("/api/pleroma/admin/statuses/#{id}", %{"sensitive" => "true"})
1481 |> json_response(:ok)
1483 assert response["sensitive"]
1485 log_entry = Repo.one(ModerationLog)
1487 assert ModerationLog.get_log_entry_message(log_entry) ==
1488 "@#{admin.nickname} updated status ##{id}, set sensitive: 'true'"
1492 |> put("/api/pleroma/admin/statuses/#{id}", %{"sensitive" => "false"})
1493 |> json_response(:ok)
1495 refute response["sensitive"]
1498 test "change visibility flag", %{conn: conn, id: id, admin: admin} do
1501 |> put("/api/pleroma/admin/statuses/#{id}", %{"visibility" => "public"})
1502 |> json_response(:ok)
1504 assert response["visibility"] == "public"
1506 log_entry = Repo.one(ModerationLog)
1508 assert ModerationLog.get_log_entry_message(log_entry) ==
1509 "@#{admin.nickname} updated status ##{id}, set visibility: 'public'"
1513 |> put("/api/pleroma/admin/statuses/#{id}", %{"visibility" => "private"})
1514 |> json_response(:ok)
1516 assert response["visibility"] == "private"
1520 |> put("/api/pleroma/admin/statuses/#{id}", %{"visibility" => "unlisted"})
1521 |> json_response(:ok)
1523 assert response["visibility"] == "unlisted"
1526 test "returns 400 when visibility is unknown", %{conn: conn, id: id} do
1529 |> put("/api/pleroma/admin/statuses/#{id}", %{"visibility" => "test"})
1531 assert json_response(conn, :bad_request) == "Unsupported visibility"
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)
1540 %{conn: assign(conn, :user, admin), id: activity.id, admin: admin}
1543 test "deletes status", %{conn: conn, id: id, admin: admin} do
1545 |> delete("/api/pleroma/admin/statuses/#{id}")
1546 |> json_response(:ok)
1548 refute Activity.get_by_id(id)
1550 log_entry = Repo.one(ModerationLog)
1552 assert ModerationLog.get_log_entry_message(log_entry) ==
1553 "@#{admin.nickname} deleted status ##{id}"
1556 test "returns error when status is not exist", %{conn: conn} do
1559 |> delete("/api/pleroma/admin/statuses/test")
1561 assert json_response(conn, :bad_request) == "Could not delete"
1565 describe "GET /api/pleroma/admin/config" do
1566 setup %{conn: conn} do
1567 admin = insert(:user, info: %{is_admin: true})
1569 %{conn: assign(conn, :user, admin)}
1572 test "without any settings in db", %{conn: conn} do
1573 conn = get(conn, "/api/pleroma/admin/config")
1575 assert json_response(conn, 200) == %{"configs" => []}
1578 test "with settings in db", %{conn: conn} do
1579 config1 = insert(:config)
1580 config2 = insert(:config)
1582 conn = get(conn, "/api/pleroma/admin/config")
1595 } = json_response(conn, 200)
1597 assert key1 == config1.key
1598 assert key2 == config2.key
1602 describe "POST /api/pleroma/admin/config" do
1603 setup %{conn: conn} do
1604 admin = insert(:user, info: %{is_admin: true})
1606 temp_file = "config/test.exported_from_db.secret.exs"
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)
1620 %{conn: assign(conn, :user, admin)}
1623 clear_config([:instance, :dynamic_configuration]) do
1624 Pleroma.Config.put([:instance, :dynamic_configuration], true)
1627 test "create new config setting in db", %{conn: conn} do
1629 post(conn, "/api/pleroma/admin/config", %{
1631 %{group: "pleroma", key: "key1", value: "value1"},
1634 key: "Ueberauth.Strategy.Twitter.OAuth",
1635 value: [%{"tuple" => [":consumer_secret", "aaaa"]}]
1641 ":nested_1" => "nested_value1",
1643 %{":nested_22" => "nested_value222"},
1644 %{":nested_33" => %{":nested_44" => "nested_444"}}
1652 %{"nested_3" => ":nested_3", "nested_33" => "nested_33"},
1653 %{"nested_4" => true}
1659 value: %{":nested_5" => ":upload", "endpoint" => "https://example.com"}
1664 value: %{"tuple" => ["string", "Pleroma.Captcha.NotReal", []]}
1669 assert json_response(conn, 200) == %{
1672 "group" => "pleroma",
1677 "group" => "ueberauth",
1678 "key" => "Ueberauth.Strategy.Twitter.OAuth",
1679 "value" => [%{"tuple" => [":consumer_secret", "aaaa"]}]
1682 "group" => "pleroma",
1685 ":nested_1" => "nested_value1",
1687 %{":nested_22" => "nested_value222"},
1688 %{":nested_33" => %{":nested_44" => "nested_444"}}
1693 "group" => "pleroma",
1696 %{"nested_3" => ":nested_3", "nested_33" => "nested_33"},
1697 %{"nested_4" => true}
1701 "group" => "pleroma",
1703 "value" => %{"endpoint" => "https://example.com", ":nested_5" => ":upload"}
1708 "value" => %{"tuple" => ["string", "Pleroma.Captcha.NotReal", []]}
1713 assert Application.get_env(:pleroma, :key1) == "value1"
1715 assert Application.get_env(:pleroma, :key2) == %{
1716 nested_1: "nested_value1",
1718 %{nested_22: "nested_value222"},
1719 %{nested_33: %{nested_44: "nested_444"}}
1723 assert Application.get_env(:pleroma, :key3) == [
1724 %{"nested_3" => :nested_3, "nested_33" => "nested_33"},
1725 %{"nested_4" => true}
1728 assert Application.get_env(:pleroma, :key4) == %{
1729 "endpoint" => "https://example.com",
1733 assert Application.get_env(:idna, :key5) == {"string", Pleroma.Captcha.NotReal, []}
1736 test "update config setting & delete", %{conn: conn} do
1737 config1 = insert(:config, key: "keyaa1")
1738 config2 = insert(:config, key: "keyaa2")
1742 key: "Ueberauth.Strategy.Microsoft.OAuth",
1743 value: :erlang.term_to_binary([])
1747 post(conn, "/api/pleroma/admin/config", %{
1749 %{group: config1.group, key: config1.key, value: "another_value"},
1750 %{group: config2.group, key: config2.key, delete: "true"},
1753 key: "Ueberauth.Strategy.Microsoft.OAuth",
1759 assert json_response(conn, 200) == %{
1762 "group" => "pleroma",
1763 "key" => config1.key,
1764 "value" => "another_value"
1769 assert Application.get_env(:pleroma, :keyaa1) == "another_value"
1770 refute Application.get_env(:pleroma, :keyaa2)
1773 test "common config example", %{conn: conn} do
1775 post(conn, "/api/pleroma/admin/config", %{
1778 "group" => "pleroma",
1779 "key" => "Pleroma.Captcha.NotReal",
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"]}
1796 assert json_response(conn, 200) == %{
1799 "group" => "pleroma",
1800 "key" => "Pleroma.Captcha.NotReal",
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"]}
1818 test "tuples with more than two values", %{conn: conn} do
1820 post(conn, "/api/pleroma/admin/config", %{
1823 "group" => "pleroma",
1824 "key" => "Pleroma.Web.Endpoint.NotReal",
1840 "/api/v1/streaming",
1841 "Pleroma.Web.MastodonAPI.WebsocketHandler",
1848 "Phoenix.Endpoint.CowboyWebSocket",
1851 "Phoenix.Transports.WebSocket",
1854 "Pleroma.Web.Endpoint",
1855 "Pleroma.Web.UserSocket",
1866 "Phoenix.Endpoint.Cowboy2Handler",
1867 %{"tuple" => ["Pleroma.Web.Endpoint", []]}
1884 assert json_response(conn, 200) == %{
1887 "group" => "pleroma",
1888 "key" => "Pleroma.Web.Endpoint.NotReal",
1904 "/api/v1/streaming",
1905 "Pleroma.Web.MastodonAPI.WebsocketHandler",
1912 "Phoenix.Endpoint.CowboyWebSocket",
1915 "Phoenix.Transports.WebSocket",
1918 "Pleroma.Web.Endpoint",
1919 "Pleroma.Web.UserSocket",
1930 "Phoenix.Endpoint.Cowboy2Handler",
1931 %{"tuple" => ["Pleroma.Web.Endpoint", []]}
1949 test "settings with nesting map", %{conn: conn} do
1951 post(conn, "/api/pleroma/admin/config", %{
1954 "group" => "pleroma",
1957 %{"tuple" => [":key2", "some_val"]},
1962 ":max_options" => 20,
1963 ":max_option_chars" => 200,
1964 ":min_expiration" => 0,
1965 ":max_expiration" => 31_536_000,
1967 ":max_options" => 20,
1968 ":max_option_chars" => 200,
1969 ":min_expiration" => 0,
1970 ":max_expiration" => 31_536_000
1980 assert json_response(conn, 200) ==
1984 "group" => "pleroma",
1987 %{"tuple" => [":key2", "some_val"]},
1992 ":max_expiration" => 31_536_000,
1993 ":max_option_chars" => 200,
1994 ":max_options" => 20,
1995 ":min_expiration" => 0,
1997 ":max_expiration" => 31_536_000,
1998 ":max_option_chars" => 200,
1999 ":max_options" => 20,
2000 ":min_expiration" => 0
2011 test "value as map", %{conn: conn} do
2013 post(conn, "/api/pleroma/admin/config", %{
2016 "group" => "pleroma",
2018 "value" => %{"key" => "some_val"}
2023 assert json_response(conn, 200) ==
2027 "group" => "pleroma",
2029 "value" => %{"key" => "some_val"}
2035 test "dispatch setting", %{conn: conn} do
2037 post(conn, "/api/pleroma/admin/config", %{
2040 "group" => "pleroma",
2041 "key" => "Pleroma.Web.Endpoint.NotReal",
2047 %{"tuple" => [":ip", %{"tuple" => [127, 0, 0, 1]}]},
2048 %{"tuple" => [":dispatch", ["{:_,
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, []}}
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, []}}]}"
2070 assert json_response(conn, 200) == %{
2073 "group" => "pleroma",
2074 "key" => "Pleroma.Web.Endpoint.NotReal",
2080 %{"tuple" => [":ip", %{"tuple" => [127, 0, 0, 1]}]},
2098 test "queues key as atom", %{conn: conn} do
2100 post(conn, "/api/pleroma/admin/config", %{
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]}
2118 assert json_response(conn, 200) == %{
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]}
2137 test "delete part of settings by atom subkeys", %{conn: conn} do
2141 value: :erlang.term_to_binary(subkey1: "val1", subkey2: "val2", subkey3: "val3")
2145 post(conn, "/api/pleroma/admin/config", %{
2148 group: config.group,
2150 subkeys: [":subkey1", ":subkey3"],
2157 json_response(conn, 200) == %{
2160 "group" => "pleroma",
2162 "value" => [%{"tuple" => [":subkey2", "val2"]}]
2170 describe "config mix tasks run" do
2171 setup %{conn: conn} do
2172 admin = insert(:user, info: %{is_admin: true})
2174 temp_file = "config/test.exported_from_db.secret.exs"
2176 Mix.shell(Mix.Shell.Quiet)
2179 Mix.shell(Mix.Shell.IO)
2180 :ok = File.rm(temp_file)
2183 %{conn: assign(conn, :user, admin), admin: admin}
2186 clear_config([:instance, :dynamic_configuration]) do
2187 Pleroma.Config.put([:instance, :dynamic_configuration], true)
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
2198 |> assign(:user, admin)
2199 |> get("/api/pleroma/admin/config/migrate_from_db")
2201 assert json_response(conn, 200) == %{}
2202 assert Pleroma.Repo.all(Pleroma.Web.AdminAPI.Config) == []
2206 describe "GET /api/pleroma/admin/users/:nickname/statuses" do
2208 admin = insert(:user, info: %{is_admin: true})
2209 user = insert(:user)
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!()
2215 insert(:note_activity, user: user, published: date1)
2216 insert(:note_activity, user: user, published: date2)
2217 insert(:note_activity, user: user, published: date3)
2221 |> assign(:user, admin)
2223 {:ok, conn: conn, user: user}
2226 test "renders user's statuses", %{conn: conn, user: user} do
2227 conn = get(conn, "/api/pleroma/admin/users/#{user.nickname}/statuses")
2229 assert json_response(conn, 200) |> length() == 3
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")
2235 assert json_response(conn, 200) |> length() == 2
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"})
2242 {:ok, _public_status} =
2243 CommonAPI.post(user, %{"status" => "public", "visibility" => "public"})
2245 conn = get(conn, "/api/pleroma/admin/users/#{user.nickname}/statuses")
2247 assert json_response(conn, 200) |> length() == 4
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"})
2254 {:ok, _public_status} =
2255 CommonAPI.post(user, %{"status" => "public", "visibility" => "public"})
2257 conn = get(conn, "/api/pleroma/admin/users/#{user.nickname}/statuses?godmode=true")
2259 assert json_response(conn, 200) |> length() == 5
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})
2268 %{conn: assign(conn, :user, admin), admin: admin, moderator: moderator}
2271 test "returns the log", %{conn: conn, admin: admin} do
2272 Repo.insert(%ModerationLog{
2276 "nickname" => admin.nickname,
2279 action: "relay_follow",
2280 target: "https://example.org/relay"
2282 inserted_at: NaiveDateTime.truncate(~N[2017-08-15 15:47:06.597036], :second)
2285 Repo.insert(%ModerationLog{
2289 "nickname" => admin.nickname,
2292 action: "relay_unfollow",
2293 target: "https://example.org/relay"
2295 inserted_at: NaiveDateTime.truncate(~N[2017-08-16 15:47:06.597036], :second)
2298 conn = get(conn, "/api/pleroma/admin/moderation_log")
2300 response = json_response(conn, 200)
2301 [first_entry, second_entry] = response["items"]
2303 assert response["total"] == 2
2304 assert first_entry["data"]["action"] == "relay_unfollow"
2306 assert first_entry["message"] ==
2307 "@#{admin.nickname} unfollowed relay: https://example.org/relay"
2309 assert second_entry["data"]["action"] == "relay_follow"
2311 assert second_entry["message"] ==
2312 "@#{admin.nickname} followed relay: https://example.org/relay"
2315 test "returns the log with pagination", %{conn: conn, admin: admin} do
2316 Repo.insert(%ModerationLog{
2320 "nickname" => admin.nickname,
2323 action: "relay_follow",
2324 target: "https://example.org/relay"
2326 inserted_at: NaiveDateTime.truncate(~N[2017-08-15 15:47:06.597036], :second)
2329 Repo.insert(%ModerationLog{
2333 "nickname" => admin.nickname,
2336 action: "relay_unfollow",
2337 target: "https://example.org/relay"
2339 inserted_at: NaiveDateTime.truncate(~N[2017-08-16 15:47:06.597036], :second)
2342 conn1 = get(conn, "/api/pleroma/admin/moderation_log?page_size=1&page=1")
2344 response1 = json_response(conn1, 200)
2345 [first_entry] = response1["items"]
2347 assert response1["total"] == 2
2348 assert response1["items"] |> length() == 1
2349 assert first_entry["data"]["action"] == "relay_unfollow"
2351 assert first_entry["message"] ==
2352 "@#{admin.nickname} unfollowed relay: https://example.org/relay"
2354 conn2 = get(conn, "/api/pleroma/admin/moderation_log?page_size=1&page=2")
2356 response2 = json_response(conn2, 200)
2357 [second_entry] = response2["items"]
2359 assert response2["total"] == 2
2360 assert response2["items"] |> length() == 1
2361 assert second_entry["data"]["action"] == "relay_follow"
2363 assert second_entry["message"] ==
2364 "@#{admin.nickname} followed relay: https://example.org/relay"
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"
2371 Repo.insert(%ModerationLog{
2375 "nickname" => admin.nickname,
2378 action: "relay_follow",
2379 target: "https://example.org/relay"
2381 inserted_at: NaiveDateTime.from_iso8601!(first_date)
2384 Repo.insert(%ModerationLog{
2388 "nickname" => admin.nickname,
2391 action: "relay_unfollow",
2392 target: "https://example.org/relay"
2394 inserted_at: NaiveDateTime.from_iso8601!(second_date)
2400 "/api/pleroma/admin/moderation_log?start_date=#{second_date}"
2403 response1 = json_response(conn1, 200)
2404 [first_entry] = response1["items"]
2406 assert response1["total"] == 1
2407 assert first_entry["data"]["action"] == "relay_unfollow"
2409 assert first_entry["message"] ==
2410 "@#{admin.nickname} unfollowed relay: https://example.org/relay"
2413 test "returns log filtered by user", %{conn: conn, admin: admin, moderator: moderator} do
2414 Repo.insert(%ModerationLog{
2418 "nickname" => admin.nickname,
2421 action: "relay_follow",
2422 target: "https://example.org/relay"
2426 Repo.insert(%ModerationLog{
2429 "id" => moderator.id,
2430 "nickname" => moderator.nickname,
2433 action: "relay_unfollow",
2434 target: "https://example.org/relay"
2438 conn1 = get(conn, "/api/pleroma/admin/moderation_log?user_id=#{moderator.id}")
2440 response1 = json_response(conn1, 200)
2441 [first_entry] = response1["items"]
2443 assert response1["total"] == 1
2444 assert get_in(first_entry, ["data", "actor", "id"]) == moderator.id
2447 test "returns log filtered by search", %{conn: conn, moderator: moderator} do
2448 ModerationLog.insert_log(%{
2450 action: "relay_follow",
2451 target: "https://example.org/relay"
2454 ModerationLog.insert_log(%{
2456 action: "relay_unfollow",
2457 target: "https://example.org/relay"
2460 conn1 = get(conn, "/api/pleroma/admin/moderation_log?search=unfo")
2462 response1 = json_response(conn1, 200)
2463 [first_entry] = response1["items"]
2465 assert response1["total"] == 1
2467 assert get_in(first_entry, ["data", "message"]) ==
2468 "@#{moderator.nickname} unfollowed relay: https://example.org/relay"
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)
2477 %{conn: assign(conn, :user, admin), admin: admin, user: user}
2480 test "sets password_reset_pending to true", %{admin: admin, user: user} do
2481 assert user.info.password_reset_pending == false
2485 |> assign(:user, admin)
2486 |> patch("/api/pleroma/admin/users/#{user.nickname}/force_password_reset")
2488 assert json_response(conn, 204) == ""
2490 ObanHelpers.perform_all()
2492 assert User.get_by_id(user.id).info.password_reset_pending == true
2496 describe "relays" do
2497 setup %{conn: conn} do
2498 admin = insert(:user, info: %{is_admin: true})
2500 %{conn: assign(conn, :user, admin), admin: admin}
2503 test "POST /relay", %{admin: admin} do
2506 |> assign(:user, admin)
2507 |> post("/api/pleroma/admin/relay", %{
2508 relay_url: "http://mastodon.example.org/users/admin"
2511 assert json_response(conn, 200) == "http://mastodon.example.org/users/admin"
2513 log_entry = Repo.one(ModerationLog)
2515 assert ModerationLog.get_log_entry_message(log_entry) ==
2516 "@#{admin.nickname} followed relay: http://mastodon.example.org/users/admin"
2519 test "GET /relay", %{admin: admin} do
2520 Pleroma.Web.ActivityPub.Relay.get_actor()
2521 |> Ecto.Changeset.change(
2523 "http://test-app.com/user/test1",
2524 "http://test-app.com/user/test1",
2525 "http://test-app-42.com/user/test1"
2528 |> Pleroma.User.update_and_set_cache()
2532 |> assign(:user, admin)
2533 |> get("/api/pleroma/admin/relay")
2535 assert json_response(conn, 200)["relays"] -- ["test-app.com", "test-app-42.com"] == []
2538 test "DELETE /relay", %{admin: admin} do
2540 |> assign(:user, admin)
2541 |> post("/api/pleroma/admin/relay", %{
2542 relay_url: "http://mastodon.example.org/users/admin"
2547 |> assign(:user, admin)
2548 |> delete("/api/pleroma/admin/relay", %{
2549 relay_url: "http://mastodon.example.org/users/admin"
2552 assert json_response(conn, 200) == "http://mastodon.example.org/users/admin"
2554 [log_entry_one, log_entry_two] = Repo.all(ModerationLog)
2556 assert ModerationLog.get_log_entry_message(log_entry_one) ==
2557 "@#{admin.nickname} followed relay: http://mastodon.example.org/users/admin"
2559 assert ModerationLog.get_log_entry_message(log_entry_two) ==
2560 "@#{admin.nickname} unfollowed relay: http://mastodon.example.org/users/admin"
2565 # Needed for testing
2566 defmodule Pleroma.Web.Endpoint.NotReal do
2569 defmodule Pleroma.Captcha.NotReal do