1 # Pleroma: A lightweight social networking server
2 # Copyright © 2017-2018 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
9 alias Pleroma.UserInviteToken
10 import Pleroma.Factory
12 describe "/api/pleroma/admin/users" do
14 admin = insert(:user, info: %{is_admin: true})
19 |> assign(:user, admin)
20 |> put_req_header("accept", "application/json")
21 |> delete("/api/pleroma/admin/users?nickname=#{user.nickname}")
23 assert json_response(conn, 200) == user.nickname
27 admin = insert(:user, info: %{is_admin: true})
31 |> assign(:user, admin)
32 |> put_req_header("accept", "application/json")
33 |> post("/api/pleroma/admin/users", %{
37 "email" => "lain@example.org",
43 assert json_response(conn, 200) == [
47 "email" => "lain@example.org",
55 test "Cannot create user with exisiting email" do
56 admin = insert(:user, info: %{is_admin: true})
61 |> assign(:user, admin)
62 |> put_req_header("accept", "application/json")
63 |> post("/api/pleroma/admin/users", %{
67 "email" => user.email,
73 assert json_response(conn, 200) == [
77 "email" => user.email,
80 "error" => "email has already been taken",
86 test "Cannot create user with exisiting nickname" do
87 admin = insert(:user, info: %{is_admin: true})
92 |> assign(:user, admin)
93 |> put_req_header("accept", "application/json")
94 |> post("/api/pleroma/admin/users", %{
97 "nickname" => user.nickname,
98 "email" => "someuser@plerama.social",
104 assert json_response(conn, 200) == [
108 "email" => "someuser@plerama.social",
109 "nickname" => user.nickname
111 "error" => "nickname has already been taken",
118 describe "/api/pleroma/admin/users/:nickname" do
119 test "Show", %{conn: conn} do
120 admin = insert(:user, info: %{is_admin: true})
125 |> assign(:user, admin)
126 |> get("/api/pleroma/admin/users/#{user.nickname}")
129 "deactivated" => false,
130 "id" => to_string(user.id),
132 "nickname" => user.nickname,
133 "roles" => %{"admin" => false, "moderator" => false},
137 assert expected == json_response(conn, 200)
140 test "when the user doesn't exist", %{conn: conn} do
141 admin = insert(:user, info: %{is_admin: true})
146 |> assign(:user, admin)
147 |> get("/api/pleroma/admin/users/#{user.nickname}")
149 assert "Not found" == json_response(conn, 404)
153 describe "/api/pleroma/admin/users/follow" do
154 test "allows to force-follow another user" do
155 admin = insert(:user, info: %{is_admin: true})
157 follower = insert(:user)
160 |> assign(:user, admin)
161 |> put_req_header("accept", "application/json")
162 |> post("/api/pleroma/admin/users/follow", %{
163 "follower" => follower.nickname,
164 "followed" => user.nickname
167 user = User.get_cached_by_id(user.id)
168 follower = User.get_cached_by_id(follower.id)
170 assert User.following?(follower, user)
174 describe "/api/pleroma/admin/users/unfollow" do
175 test "allows to force-unfollow another user" do
176 admin = insert(:user, info: %{is_admin: true})
178 follower = insert(:user)
180 User.follow(follower, user)
183 |> assign(:user, admin)
184 |> put_req_header("accept", "application/json")
185 |> post("/api/pleroma/admin/users/unfollow", %{
186 "follower" => follower.nickname,
187 "followed" => user.nickname
190 user = User.get_cached_by_id(user.id)
191 follower = User.get_cached_by_id(follower.id)
193 refute User.following?(follower, user)
197 describe "PUT /api/pleroma/admin/users/tag" do
199 admin = insert(:user, info: %{is_admin: true})
200 user1 = insert(:user, %{tags: ["x"]})
201 user2 = insert(:user, %{tags: ["y"]})
202 user3 = insert(:user, %{tags: ["unchanged"]})
206 |> assign(:user, admin)
207 |> put_req_header("accept", "application/json")
209 "/api/pleroma/admin/users/tag?nicknames[]=#{user1.nickname}&nicknames[]=#{
211 }&tags[]=foo&tags[]=bar"
214 %{conn: conn, user1: user1, user2: user2, user3: user3}
217 test "it appends specified tags to users with specified nicknames", %{
222 assert json_response(conn, :no_content)
223 assert User.get_cached_by_id(user1.id).tags == ["x", "foo", "bar"]
224 assert User.get_cached_by_id(user2.id).tags == ["y", "foo", "bar"]
227 test "it does not modify tags of not specified users", %{conn: conn, user3: user3} do
228 assert json_response(conn, :no_content)
229 assert User.get_cached_by_id(user3.id).tags == ["unchanged"]
233 describe "DELETE /api/pleroma/admin/users/tag" do
235 admin = insert(:user, info: %{is_admin: true})
236 user1 = insert(:user, %{tags: ["x"]})
237 user2 = insert(:user, %{tags: ["y", "z"]})
238 user3 = insert(:user, %{tags: ["unchanged"]})
242 |> assign(:user, admin)
243 |> put_req_header("accept", "application/json")
245 "/api/pleroma/admin/users/tag?nicknames[]=#{user1.nickname}&nicknames[]=#{
250 %{conn: conn, user1: user1, user2: user2, user3: user3}
253 test "it removes specified tags from users with specified nicknames", %{
258 assert json_response(conn, :no_content)
259 assert User.get_cached_by_id(user1.id).tags == []
260 assert User.get_cached_by_id(user2.id).tags == ["y"]
263 test "it does not modify tags of not specified users", %{conn: conn, user3: user3} do
264 assert json_response(conn, :no_content)
265 assert User.get_cached_by_id(user3.id).tags == ["unchanged"]
269 describe "/api/pleroma/admin/users/:nickname/permission_group" do
270 test "GET is giving user_info" do
271 admin = insert(:user, info: %{is_admin: true})
275 |> assign(:user, admin)
276 |> put_req_header("accept", "application/json")
277 |> get("/api/pleroma/admin/users/#{admin.nickname}/permission_group/")
279 assert json_response(conn, 200) == %{
281 "is_moderator" => false
285 test "/:right POST, can add to a permission group" do
286 admin = insert(:user, info: %{is_admin: true})
291 |> assign(:user, admin)
292 |> put_req_header("accept", "application/json")
293 |> post("/api/pleroma/admin/users/#{user.nickname}/permission_group/admin")
295 assert json_response(conn, 200) == %{
300 test "/:right DELETE, can remove from a permission group" do
301 admin = insert(:user, info: %{is_admin: true})
302 user = insert(:user, info: %{is_admin: true})
306 |> assign(:user, admin)
307 |> put_req_header("accept", "application/json")
308 |> delete("/api/pleroma/admin/users/#{user.nickname}/permission_group/admin")
310 assert json_response(conn, 200) == %{
316 describe "PUT /api/pleroma/admin/users/:nickname/activation_status" do
317 setup %{conn: conn} do
318 admin = insert(:user, info: %{is_admin: true})
322 |> assign(:user, admin)
323 |> put_req_header("accept", "application/json")
328 test "deactivates the user", %{conn: conn} do
333 |> put("/api/pleroma/admin/users/#{user.nickname}/activation_status", %{status: false})
335 user = User.get_cached_by_id(user.id)
336 assert user.info.deactivated == true
337 assert json_response(conn, :no_content)
340 test "activates the user", %{conn: conn} do
341 user = insert(:user, info: %{deactivated: true})
345 |> put("/api/pleroma/admin/users/#{user.nickname}/activation_status", %{status: true})
347 user = User.get_cached_by_id(user.id)
348 assert user.info.deactivated == false
349 assert json_response(conn, :no_content)
352 test "returns 403 when requested by a non-admin", %{conn: conn} do
357 |> assign(:user, user)
358 |> put("/api/pleroma/admin/users/#{user.nickname}/activation_status", %{status: false})
360 assert json_response(conn, :forbidden)
364 describe "POST /api/pleroma/admin/email_invite, with valid config" do
366 registrations_open = Pleroma.Config.get([:instance, :registrations_open])
367 invites_enabled = Pleroma.Config.get([:instance, :invites_enabled])
368 Pleroma.Config.put([:instance, :registrations_open], false)
369 Pleroma.Config.put([:instance, :invites_enabled], true)
372 Pleroma.Config.put([:instance, :registrations_open], registrations_open)
373 Pleroma.Config.put([:instance, :invites_enabled], invites_enabled)
377 [user: insert(:user, info: %{is_admin: true})]
380 test "sends invitation and returns 204", %{conn: conn, user: user} do
381 recipient_email = "foo@bar.com"
382 recipient_name = "J. D."
386 |> assign(:user, user)
388 "/api/pleroma/admin/users/email_invite?email=#{recipient_email}&name=#{recipient_name}"
391 assert json_response(conn, :no_content)
393 token_record = List.last(Pleroma.Repo.all(Pleroma.UserInviteToken))
395 refute token_record.used
397 notify_email = Pleroma.Config.get([:instance, :notify_email])
398 instance_name = Pleroma.Config.get([:instance, :name])
401 Pleroma.Emails.UserEmail.user_invitation_email(
408 Swoosh.TestAssertions.assert_email_sent(
409 from: {instance_name, notify_email},
410 to: {recipient_name, recipient_email},
411 html_body: email.html_body
415 test "it returns 403 if requested by a non-admin", %{conn: conn} do
416 non_admin_user = insert(:user)
420 |> assign(:user, non_admin_user)
421 |> post("/api/pleroma/admin/users/email_invite?email=foo@bar.com&name=JD")
423 assert json_response(conn, :forbidden)
427 describe "POST /api/pleroma/admin/users/email_invite, with invalid config" do
429 [user: insert(:user, info: %{is_admin: true})]
432 test "it returns 500 if `invites_enabled` is not enabled", %{conn: conn, user: user} do
433 registrations_open = Pleroma.Config.get([:instance, :registrations_open])
434 invites_enabled = Pleroma.Config.get([:instance, :invites_enabled])
435 Pleroma.Config.put([:instance, :registrations_open], false)
436 Pleroma.Config.put([:instance, :invites_enabled], false)
439 Pleroma.Config.put([:instance, :registrations_open], registrations_open)
440 Pleroma.Config.put([:instance, :invites_enabled], invites_enabled)
446 |> assign(:user, user)
447 |> post("/api/pleroma/admin/users/email_invite?email=foo@bar.com&name=JD")
449 assert json_response(conn, :internal_server_error)
452 test "it returns 500 if `registrations_open` is enabled", %{conn: conn, user: user} do
453 registrations_open = Pleroma.Config.get([:instance, :registrations_open])
454 invites_enabled = Pleroma.Config.get([:instance, :invites_enabled])
455 Pleroma.Config.put([:instance, :registrations_open], true)
456 Pleroma.Config.put([:instance, :invites_enabled], true)
459 Pleroma.Config.put([:instance, :registrations_open], registrations_open)
460 Pleroma.Config.put([:instance, :invites_enabled], invites_enabled)
466 |> assign(:user, user)
467 |> post("/api/pleroma/admin/users/email_invite?email=foo@bar.com&name=JD")
469 assert json_response(conn, :internal_server_error)
473 test "/api/pleroma/admin/invite_token" do
474 admin = insert(:user, info: %{is_admin: true})
478 |> assign(:user, admin)
479 |> put_req_header("accept", "application/json")
480 |> get("/api/pleroma/admin/invite_token")
482 assert conn.status == 200
485 test "/api/pleroma/admin/users/:nickname/password_reset" do
486 admin = insert(:user, info: %{is_admin: true})
491 |> assign(:user, admin)
492 |> put_req_header("accept", "application/json")
493 |> get("/api/pleroma/admin/users/#{user.nickname}/password_reset")
495 assert conn.status == 200
498 describe "GET /api/pleroma/admin/users" do
500 admin = insert(:user, info: %{is_admin: true})
504 |> assign(:user, admin)
506 {:ok, conn: conn, admin: admin}
509 test "renders users array for the first page", %{conn: conn, admin: admin} do
510 user = insert(:user, local: false, tags: ["foo", "bar"])
511 conn = get(conn, "/api/pleroma/admin/users?page=1")
513 assert json_response(conn, 200) == %{
518 "deactivated" => admin.info.deactivated,
520 "nickname" => admin.nickname,
521 "roles" => %{"admin" => true, "moderator" => false},
526 "deactivated" => user.info.deactivated,
528 "nickname" => user.nickname,
529 "roles" => %{"admin" => false, "moderator" => false},
531 "tags" => ["foo", "bar"]
537 test "renders empty array for the second page", %{conn: conn} do
540 conn = get(conn, "/api/pleroma/admin/users?page=2")
542 assert json_response(conn, 200) == %{
549 test "regular search", %{conn: conn} do
550 user = insert(:user, nickname: "bob")
552 conn = get(conn, "/api/pleroma/admin/users?query=bo")
554 assert json_response(conn, 200) == %{
559 "deactivated" => user.info.deactivated,
561 "nickname" => user.nickname,
562 "roles" => %{"admin" => false, "moderator" => false},
570 test "search by domain", %{conn: conn} do
571 user = insert(:user, nickname: "nickname@domain.com")
574 conn = get(conn, "/api/pleroma/admin/users?query=domain.com")
576 assert json_response(conn, 200) == %{
581 "deactivated" => user.info.deactivated,
583 "nickname" => user.nickname,
584 "roles" => %{"admin" => false, "moderator" => false},
592 test "search by full nickname", %{conn: conn} do
593 user = insert(:user, nickname: "nickname@domain.com")
596 conn = get(conn, "/api/pleroma/admin/users?query=nickname@domain.com")
598 assert json_response(conn, 200) == %{
603 "deactivated" => user.info.deactivated,
605 "nickname" => user.nickname,
606 "roles" => %{"admin" => false, "moderator" => false},
614 test "search by display name", %{conn: conn} do
615 user = insert(:user, name: "Display name")
618 conn = get(conn, "/api/pleroma/admin/users?name=display")
620 assert json_response(conn, 200) == %{
625 "deactivated" => user.info.deactivated,
627 "nickname" => user.nickname,
628 "roles" => %{"admin" => false, "moderator" => false},
636 test "search by email", %{conn: conn} do
637 user = insert(:user, email: "email@example.com")
640 conn = get(conn, "/api/pleroma/admin/users?email=email@example.com")
642 assert json_response(conn, 200) == %{
647 "deactivated" => user.info.deactivated,
649 "nickname" => user.nickname,
650 "roles" => %{"admin" => false, "moderator" => false},
658 test "regular search with page size", %{conn: conn} do
659 user = insert(:user, nickname: "aalice")
660 user2 = insert(:user, nickname: "alice")
662 conn1 = get(conn, "/api/pleroma/admin/users?query=a&page_size=1&page=1")
664 assert json_response(conn1, 200) == %{
669 "deactivated" => user.info.deactivated,
671 "nickname" => user.nickname,
672 "roles" => %{"admin" => false, "moderator" => false},
679 conn2 = get(conn, "/api/pleroma/admin/users?query=a&page_size=1&page=2")
681 assert json_response(conn2, 200) == %{
686 "deactivated" => user2.info.deactivated,
688 "nickname" => user2.nickname,
689 "roles" => %{"admin" => false, "moderator" => false},
697 test "only local users" do
698 admin = insert(:user, info: %{is_admin: true}, nickname: "john")
699 user = insert(:user, nickname: "bob")
701 insert(:user, nickname: "bobb", local: false)
705 |> assign(:user, admin)
706 |> get("/api/pleroma/admin/users?query=bo&filters=local")
708 assert json_response(conn, 200) == %{
713 "deactivated" => user.info.deactivated,
715 "nickname" => user.nickname,
716 "roles" => %{"admin" => false, "moderator" => false},
724 test "only local users with no query", %{admin: old_admin} do
725 admin = insert(:user, info: %{is_admin: true}, nickname: "john")
726 user = insert(:user, nickname: "bob")
728 insert(:user, nickname: "bobb", local: false)
732 |> assign(:user, admin)
733 |> get("/api/pleroma/admin/users?filters=local")
735 assert json_response(conn, 200) == %{
740 "deactivated" => user.info.deactivated,
742 "nickname" => user.nickname,
743 "roles" => %{"admin" => false, "moderator" => false},
748 "deactivated" => admin.info.deactivated,
750 "nickname" => admin.nickname,
751 "roles" => %{"admin" => true, "moderator" => false},
756 "deactivated" => false,
757 "id" => old_admin.id,
759 "nickname" => old_admin.nickname,
760 "roles" => %{"admin" => true, "moderator" => false},
767 test "load only admins", %{conn: conn, admin: admin} do
768 second_admin = insert(:user, info: %{is_admin: true})
772 conn = get(conn, "/api/pleroma/admin/users?filters=is_admin")
774 assert json_response(conn, 200) == %{
779 "deactivated" => false,
781 "nickname" => admin.nickname,
782 "roles" => %{"admin" => true, "moderator" => false},
783 "local" => admin.local,
787 "deactivated" => false,
788 "id" => second_admin.id,
789 "nickname" => second_admin.nickname,
790 "roles" => %{"admin" => true, "moderator" => false},
791 "local" => second_admin.local,
798 test "load only moderators", %{conn: conn} do
799 moderator = insert(:user, info: %{is_moderator: true})
803 conn = get(conn, "/api/pleroma/admin/users?filters=is_moderator")
805 assert json_response(conn, 200) == %{
810 "deactivated" => false,
811 "id" => moderator.id,
812 "nickname" => moderator.nickname,
813 "roles" => %{"admin" => false, "moderator" => true},
814 "local" => moderator.local,
821 test "load users with tags list", %{conn: conn} do
822 user1 = insert(:user, tags: ["first"])
823 user2 = insert(:user, tags: ["second"])
827 conn = get(conn, "/api/pleroma/admin/users?tags[]=first&tags[]=second")
829 assert json_response(conn, 200) == %{
834 "deactivated" => false,
836 "nickname" => user1.nickname,
837 "roles" => %{"admin" => false, "moderator" => false},
838 "local" => user1.local,
842 "deactivated" => false,
844 "nickname" => user2.nickname,
845 "roles" => %{"admin" => false, "moderator" => false},
846 "local" => user2.local,
853 test "it works with multiple filters" do
854 admin = insert(:user, nickname: "john", info: %{is_admin: true})
855 user = insert(:user, nickname: "bob", local: false, info: %{deactivated: true})
857 insert(:user, nickname: "ken", local: true, info: %{deactivated: true})
858 insert(:user, nickname: "bobb", local: false, info: %{deactivated: false})
862 |> assign(:user, admin)
863 |> get("/api/pleroma/admin/users?filters=deactivated,external")
865 assert json_response(conn, 200) == %{
870 "deactivated" => user.info.deactivated,
872 "nickname" => user.nickname,
873 "roles" => %{"admin" => false, "moderator" => false},
874 "local" => user.local,
882 test "PATCH /api/pleroma/admin/users/:nickname/toggle_activation" do
883 admin = insert(:user, info: %{is_admin: true})
888 |> assign(:user, admin)
889 |> patch("/api/pleroma/admin/users/#{user.nickname}/toggle_activation")
891 assert json_response(conn, 200) ==
893 "deactivated" => !user.info.deactivated,
895 "nickname" => user.nickname,
896 "roles" => %{"admin" => false, "moderator" => false},
902 describe "GET /api/pleroma/admin/users/invite_token" do
904 admin = insert(:user, info: %{is_admin: true})
908 |> assign(:user, admin)
913 test "without options", %{conn: conn} do
914 conn = get(conn, "/api/pleroma/admin/users/invite_token")
916 token = json_response(conn, 200)
917 invite = UserInviteToken.find_by_token!(token)
919 refute invite.expires_at
920 refute invite.max_use
921 assert invite.invite_type == "one_time"
924 test "with expires_at", %{conn: conn} do
926 get(conn, "/api/pleroma/admin/users/invite_token", %{
927 "invite" => %{"expires_at" => Date.to_string(Date.utc_today())}
930 token = json_response(conn, 200)
931 invite = UserInviteToken.find_by_token!(token)
934 assert invite.expires_at == Date.utc_today()
935 refute invite.max_use
936 assert invite.invite_type == "date_limited"
939 test "with max_use", %{conn: conn} do
941 get(conn, "/api/pleroma/admin/users/invite_token", %{
942 "invite" => %{"max_use" => 150}
945 token = json_response(conn, 200)
946 invite = UserInviteToken.find_by_token!(token)
948 refute invite.expires_at
949 assert invite.max_use == 150
950 assert invite.invite_type == "reusable"
953 test "with max use and expires_at", %{conn: conn} do
955 get(conn, "/api/pleroma/admin/users/invite_token", %{
956 "invite" => %{"max_use" => 150, "expires_at" => Date.to_string(Date.utc_today())}
959 token = json_response(conn, 200)
960 invite = UserInviteToken.find_by_token!(token)
962 assert invite.expires_at == Date.utc_today()
963 assert invite.max_use == 150
964 assert invite.invite_type == "reusable_date_limited"
968 describe "GET /api/pleroma/admin/users/invites" do
970 admin = insert(:user, info: %{is_admin: true})
974 |> assign(:user, admin)
979 test "no invites", %{conn: conn} do
980 conn = get(conn, "/api/pleroma/admin/users/invites")
982 assert json_response(conn, 200) == %{"invites" => []}
985 test "with invite", %{conn: conn} do
986 {:ok, invite} = UserInviteToken.create_invite()
988 conn = get(conn, "/api/pleroma/admin/users/invites")
990 assert json_response(conn, 200) == %{
995 "invite_type" => "one_time",
997 "token" => invite.token,
1006 describe "POST /api/pleroma/admin/users/revoke_invite" do
1007 test "with token" do
1008 admin = insert(:user, info: %{is_admin: true})
1009 {:ok, invite} = UserInviteToken.create_invite()
1013 |> assign(:user, admin)
1014 |> post("/api/pleroma/admin/users/revoke_invite", %{"token" => invite.token})
1016 assert json_response(conn, 200) == %{
1017 "expires_at" => nil,
1019 "invite_type" => "one_time",
1021 "token" => invite.token,