giant massive dep upgrade and dialyxir-found error emporium (#371)
[akkoma] / test / pleroma / web / admin_api / controllers / admin_api_controller_test.exs
1 # Pleroma: A lightweight social networking server
2 # Copyright © 2017-2021 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 import ExUnit.CaptureLog
10 import Pleroma.Factory
11 import Swoosh.TestAssertions
12
13 alias Pleroma.Activity
14 alias Pleroma.MFA
15 alias Pleroma.ModerationLog
16 alias Pleroma.Repo
17 alias Pleroma.Tests.ObanHelpers
18 alias Pleroma.User
19 alias Pleroma.Web.CommonAPI
20
21 setup_all do
22 Tesla.Mock.mock_global(fn env -> apply(HttpRequestMock, :request, [env]) end)
23
24 :ok
25 end
26
27 setup do
28 admin = insert(:user, is_admin: true)
29 token = insert(:oauth_admin_token, user: admin)
30
31 conn =
32 build_conn()
33 |> assign(:user, admin)
34 |> assign(:token, token)
35
36 {:ok, %{admin: admin, token: token, conn: conn}}
37 end
38
39 test "with valid `admin_token` query parameter, skips OAuth scopes check" do
40 clear_config([:admin_token], "password123")
41
42 user = insert(:user)
43
44 conn =
45 get(build_conn(), "/api/v1/pleroma/admin/users/#{user.nickname}?admin_token=password123")
46
47 assert json_response(conn, 200)
48 end
49
50 test "GET /api/v1/pleroma/admin/users/:nickname requires admin:read:accounts or broader scope",
51 %{admin: admin} do
52 user = insert(:user)
53 url = "/api/v1/pleroma/admin/users/#{user.nickname}"
54
55 good_token1 = insert(:oauth_token, user: admin, scopes: ["admin"])
56 good_token2 = insert(:oauth_token, user: admin, scopes: ["admin:read"])
57 good_token3 = insert(:oauth_token, user: admin, scopes: ["admin:read:accounts"])
58
59 bad_token1 = insert(:oauth_token, user: admin, scopes: ["read:accounts"])
60 bad_token2 = insert(:oauth_token, user: admin, scopes: ["admin:read:accounts:partial"])
61 bad_token3 = nil
62
63 for good_token <- [good_token1, good_token2, good_token3] do
64 conn =
65 build_conn()
66 |> assign(:user, admin)
67 |> assign(:token, good_token)
68 |> get(url)
69
70 assert json_response(conn, 200)
71 end
72
73 for good_token <- [good_token1, good_token2, good_token3] do
74 conn =
75 build_conn()
76 |> assign(:user, nil)
77 |> assign(:token, good_token)
78 |> get(url)
79
80 assert json_response(conn, :forbidden)
81 end
82
83 for bad_token <- [bad_token1, bad_token2, bad_token3] do
84 conn =
85 build_conn()
86 |> assign(:user, admin)
87 |> assign(:token, bad_token)
88 |> get(url)
89
90 assert json_response(conn, :forbidden)
91 end
92 end
93
94 describe "PUT /api/v1/pleroma/admin/users/tag" do
95 setup %{conn: conn} do
96 user1 = insert(:user, %{tags: ["x"]})
97 user2 = insert(:user, %{tags: ["y"]})
98 user3 = insert(:user, %{tags: ["unchanged"]})
99
100 conn =
101 conn
102 |> put_req_header("accept", "application/json")
103 |> put(
104 "/api/v1/pleroma/admin/users/tag?nicknames[]=#{user1.nickname}&nicknames[]=" <>
105 "#{user2.nickname}&tags[]=foo&tags[]=bar"
106 )
107
108 %{conn: conn, user1: user1, user2: user2, user3: user3}
109 end
110
111 test "it appends specified tags to users with specified nicknames", %{
112 conn: conn,
113 admin: admin,
114 user1: user1,
115 user2: user2
116 } do
117 assert empty_json_response(conn)
118 assert User.get_cached_by_id(user1.id).tags == ["x", "foo", "bar"]
119 assert User.get_cached_by_id(user2.id).tags == ["y", "foo", "bar"]
120
121 log_entry = Repo.one(ModerationLog)
122
123 users =
124 [user1.nickname, user2.nickname]
125 |> Enum.map(&"@#{&1}")
126 |> Enum.join(", ")
127
128 tags = ["foo", "bar"] |> Enum.join(", ")
129
130 assert ModerationLog.get_log_entry_message(log_entry) ==
131 "@#{admin.nickname} added tags: #{tags} to users: #{users}"
132 end
133
134 test "it does not modify tags of not specified users", %{conn: conn, user3: user3} do
135 assert empty_json_response(conn)
136 assert User.get_cached_by_id(user3.id).tags == ["unchanged"]
137 end
138 end
139
140 describe "DELETE /api/v1/pleroma/admin/users/tag" do
141 setup %{conn: conn} do
142 user1 = insert(:user, %{tags: ["x"]})
143 user2 = insert(:user, %{tags: ["y", "z"]})
144 user3 = insert(:user, %{tags: ["unchanged"]})
145
146 conn =
147 conn
148 |> put_req_header("accept", "application/json")
149 |> delete(
150 "/api/v1/pleroma/admin/users/tag?nicknames[]=#{user1.nickname}&nicknames[]=" <>
151 "#{user2.nickname}&tags[]=x&tags[]=z"
152 )
153
154 %{conn: conn, user1: user1, user2: user2, user3: user3}
155 end
156
157 test "it removes specified tags from users with specified nicknames", %{
158 conn: conn,
159 admin: admin,
160 user1: user1,
161 user2: user2
162 } do
163 assert empty_json_response(conn)
164 assert User.get_cached_by_id(user1.id).tags == []
165 assert User.get_cached_by_id(user2.id).tags == ["y"]
166
167 log_entry = Repo.one(ModerationLog)
168
169 users =
170 [user1.nickname, user2.nickname]
171 |> Enum.map(&"@#{&1}")
172 |> Enum.join(", ")
173
174 tags = ["x", "z"] |> Enum.join(", ")
175
176 assert ModerationLog.get_log_entry_message(log_entry) ==
177 "@#{admin.nickname} removed tags: #{tags} from users: #{users}"
178 end
179
180 test "it does not modify tags of not specified users", %{conn: conn, user3: user3} do
181 assert empty_json_response(conn)
182 assert User.get_cached_by_id(user3.id).tags == ["unchanged"]
183 end
184 end
185
186 describe "/api/v1/pleroma/admin/users/:nickname/permission_group" do
187 test "GET is giving user_info", %{admin: admin, conn: conn} do
188 conn =
189 conn
190 |> put_req_header("accept", "application/json")
191 |> get("/api/v1/pleroma/admin/users/#{admin.nickname}/permission_group/")
192
193 assert json_response(conn, 200) == %{
194 "is_admin" => true,
195 "is_moderator" => false
196 }
197 end
198
199 test "/:right POST, can add to a permission group", %{admin: admin, conn: conn} do
200 user = insert(:user)
201
202 conn =
203 conn
204 |> put_req_header("accept", "application/json")
205 |> post("/api/v1/pleroma/admin/users/#{user.nickname}/permission_group/admin")
206
207 assert json_response(conn, 200) == %{
208 "is_admin" => true
209 }
210
211 log_entry = Repo.one(ModerationLog)
212
213 assert ModerationLog.get_log_entry_message(log_entry) ==
214 "@#{admin.nickname} made @#{user.nickname} admin"
215 end
216
217 test "/:right POST, can add to a permission group (multiple)", %{admin: admin, conn: conn} do
218 user_one = insert(:user)
219 user_two = insert(:user)
220
221 conn =
222 conn
223 |> put_req_header("accept", "application/json")
224 |> post("/api/v1/pleroma/admin/users/permission_group/admin", %{
225 nicknames: [user_one.nickname, user_two.nickname]
226 })
227
228 assert json_response(conn, 200) == %{"is_admin" => true}
229
230 log_entry = Repo.one(ModerationLog)
231
232 assert ModerationLog.get_log_entry_message(log_entry) ==
233 "@#{admin.nickname} made @#{user_one.nickname}, @#{user_two.nickname} admin"
234 end
235
236 test "/:right DELETE, can remove from a permission group", %{admin: admin, conn: conn} do
237 user = insert(:user, is_admin: true)
238
239 conn =
240 conn
241 |> put_req_header("accept", "application/json")
242 |> delete("/api/v1/pleroma/admin/users/#{user.nickname}/permission_group/admin")
243
244 assert json_response(conn, 200) == %{"is_admin" => false}
245
246 log_entry = Repo.one(ModerationLog)
247
248 assert ModerationLog.get_log_entry_message(log_entry) ==
249 "@#{admin.nickname} revoked admin role from @#{user.nickname}"
250 end
251
252 test "/:right DELETE, can remove from a permission group (multiple)", %{
253 admin: admin,
254 conn: conn
255 } do
256 user_one = insert(:user, is_admin: true)
257 user_two = insert(:user, is_admin: true)
258
259 conn =
260 conn
261 |> put_req_header("accept", "application/json")
262 |> delete("/api/v1/pleroma/admin/users/permission_group/admin", %{
263 nicknames: [user_one.nickname, user_two.nickname]
264 })
265
266 assert json_response(conn, 200) == %{"is_admin" => false}
267
268 log_entry = Repo.one(ModerationLog)
269
270 assert ModerationLog.get_log_entry_message(log_entry) ==
271 "@#{admin.nickname} revoked admin role from @#{user_one.nickname}, @#{user_two.nickname}"
272 end
273 end
274
275 test "/api/v1/pleroma/admin/users/:nickname/password_reset", %{conn: conn} do
276 user = insert(:user)
277
278 conn =
279 conn
280 |> put_req_header("accept", "application/json")
281 |> get("/api/v1/pleroma/admin/users/#{user.nickname}/password_reset")
282
283 resp = json_response(conn, 200)
284
285 assert Regex.match?(~r/(http:\/\/|https:\/\/)/, resp["link"])
286 end
287
288 describe "PUT disable_mfa" do
289 test "returns 200 and disable 2fa", %{conn: conn} do
290 user =
291 insert(:user,
292 multi_factor_authentication_settings: %MFA.Settings{
293 enabled: true,
294 totp: %MFA.Settings.TOTP{secret: "otp_secret", confirmed: true}
295 }
296 )
297
298 response =
299 conn
300 |> put("/api/v1/pleroma/admin/users/disable_mfa", %{nickname: user.nickname})
301 |> json_response(200)
302
303 assert response == user.nickname
304 mfa_settings = refresh_record(user).multi_factor_authentication_settings
305
306 refute mfa_settings.enabled
307 refute mfa_settings.totp.confirmed
308 end
309
310 test "returns 404 if user not found", %{conn: conn} do
311 response =
312 conn
313 |> put("/api/v1/pleroma/admin/users/disable_mfa", %{nickname: "nickname"})
314 |> json_response(404)
315
316 assert response == %{"error" => "Not found"}
317 end
318 end
319
320 describe "GET /api/v1/pleroma/admin/restart" do
321 setup do: clear_config(:configurable_from_database, true)
322
323 test "pleroma restarts", %{conn: conn} do
324 capture_log(fn ->
325 assert conn |> get("/api/v1/pleroma/admin/restart") |> json_response(200) == %{}
326 end) =~ "pleroma restarted"
327
328 refute Restarter.Pleroma.need_reboot?()
329 end
330 end
331
332 test "need_reboot flag", %{conn: conn} do
333 assert conn
334 |> get("/api/v1/pleroma/admin/need_reboot")
335 |> json_response(200) == %{"need_reboot" => false}
336
337 Restarter.Pleroma.need_reboot()
338
339 assert conn
340 |> get("/api/v1/pleroma/admin/need_reboot")
341 |> json_response(200) == %{"need_reboot" => true}
342
343 on_exit(fn -> Restarter.Pleroma.refresh() end)
344 end
345
346 describe "GET /api/v1/pleroma/admin/users/:nickname/statuses" do
347 setup do
348 user = insert(:user)
349
350 insert(:note_activity, user: user)
351 insert(:note_activity, user: user)
352 insert(:note_activity, user: user)
353
354 %{user: user}
355 end
356
357 test "renders user's statuses", %{conn: conn, user: user} do
358 conn = get(conn, "/api/v1/pleroma/admin/users/#{user.nickname}/statuses")
359
360 assert %{"total" => 3, "activities" => activities} = json_response(conn, 200)
361 assert length(activities) == 3
362 end
363
364 test "renders user's statuses with pagination", %{conn: conn, user: user} do
365 %{"total" => 3, "activities" => [activity1]} =
366 conn
367 |> get("/api/v1/pleroma/admin/users/#{user.nickname}/statuses?page_size=1&page=1")
368 |> json_response(200)
369
370 %{"total" => 3, "activities" => [activity2]} =
371 conn
372 |> get("/api/v1/pleroma/admin/users/#{user.nickname}/statuses?page_size=1&page=2")
373 |> json_response(200)
374
375 refute activity1 == activity2
376 end
377
378 test "doesn't return private statuses by default", %{conn: conn, user: user} do
379 {:ok, _private_status} = CommonAPI.post(user, %{status: "private", visibility: "private"})
380
381 {:ok, _public_status} = CommonAPI.post(user, %{status: "public", visibility: "public"})
382
383 %{"total" => 4, "activities" => activities} =
384 conn
385 |> get("/api/v1/pleroma/admin/users/#{user.nickname}/statuses")
386 |> json_response(200)
387
388 assert length(activities) == 4
389 end
390
391 test "returns private statuses with godmode on", %{conn: conn, user: user} do
392 {:ok, _private_status} = CommonAPI.post(user, %{status: "private", visibility: "private"})
393
394 {:ok, _public_status} = CommonAPI.post(user, %{status: "public", visibility: "public"})
395
396 %{"total" => 5, "activities" => activities} =
397 conn
398 |> get("/api/v1/pleroma/admin/users/#{user.nickname}/statuses?godmode=true")
399 |> json_response(200)
400
401 assert length(activities) == 5
402 end
403
404 test "excludes reblogs by default", %{conn: conn, user: user} do
405 other_user = insert(:user)
406 {:ok, activity} = CommonAPI.post(user, %{status: "."})
407 {:ok, %Activity{}} = CommonAPI.repeat(activity.id, other_user)
408
409 assert %{"total" => 0, "activities" => []} ==
410 conn
411 |> get("/api/v1/pleroma/admin/users/#{other_user.nickname}/statuses")
412 |> json_response(200)
413
414 assert %{"total" => 1, "activities" => [_]} =
415 conn
416 |> get(
417 "/api/v1/pleroma/admin/users/#{other_user.nickname}/statuses?with_reblogs=true"
418 )
419 |> json_response(200)
420 end
421 end
422
423 describe "GET /api/v1/pleroma/admin/moderation_log" do
424 setup do
425 moderator = insert(:user, is_moderator: true)
426
427 %{moderator: moderator}
428 end
429
430 test "returns the log", %{conn: conn, admin: admin} do
431 Repo.insert(%ModerationLog{
432 data: %{
433 actor: %{
434 "id" => admin.id,
435 "nickname" => admin.nickname,
436 "type" => "user"
437 },
438 action: "relay_follow",
439 target: "https://example.org/relay"
440 },
441 inserted_at: NaiveDateTime.truncate(~N[2017-08-15 15:47:06.597036], :second)
442 })
443
444 Repo.insert(%ModerationLog{
445 data: %{
446 actor: %{
447 "id" => admin.id,
448 "nickname" => admin.nickname,
449 "type" => "user"
450 },
451 action: "relay_unfollow",
452 target: "https://example.org/relay"
453 },
454 inserted_at: NaiveDateTime.truncate(~N[2017-08-16 15:47:06.597036], :second)
455 })
456
457 conn = get(conn, "/api/v1/pleroma/admin/moderation_log")
458
459 response = json_response(conn, 200)
460 [first_entry, second_entry] = response["items"]
461
462 assert response["total"] == 2
463 assert first_entry["data"]["action"] == "relay_unfollow"
464
465 assert first_entry["message"] ==
466 "@#{admin.nickname} unfollowed relay: https://example.org/relay"
467
468 assert second_entry["data"]["action"] == "relay_follow"
469
470 assert second_entry["message"] ==
471 "@#{admin.nickname} followed relay: https://example.org/relay"
472 end
473
474 test "returns the log with pagination", %{conn: conn, admin: admin} do
475 Repo.insert(%ModerationLog{
476 data: %{
477 actor: %{
478 "id" => admin.id,
479 "nickname" => admin.nickname,
480 "type" => "user"
481 },
482 action: "relay_follow",
483 target: "https://example.org/relay"
484 },
485 inserted_at: NaiveDateTime.truncate(~N[2017-08-15 15:47:06.597036], :second)
486 })
487
488 Repo.insert(%ModerationLog{
489 data: %{
490 actor: %{
491 "id" => admin.id,
492 "nickname" => admin.nickname,
493 "type" => "user"
494 },
495 action: "relay_unfollow",
496 target: "https://example.org/relay"
497 },
498 inserted_at: NaiveDateTime.truncate(~N[2017-08-16 15:47:06.597036], :second)
499 })
500
501 conn1 = get(conn, "/api/v1/pleroma/admin/moderation_log?page_size=1&page=1")
502
503 response1 = json_response(conn1, 200)
504 [first_entry] = response1["items"]
505
506 assert response1["total"] == 2
507 assert response1["items"] |> length() == 1
508 assert first_entry["data"]["action"] == "relay_unfollow"
509
510 assert first_entry["message"] ==
511 "@#{admin.nickname} unfollowed relay: https://example.org/relay"
512
513 conn2 = get(conn, "/api/v1/pleroma/admin/moderation_log?page_size=1&page=2")
514
515 response2 = json_response(conn2, 200)
516 [second_entry] = response2["items"]
517
518 assert response2["total"] == 2
519 assert response2["items"] |> length() == 1
520 assert second_entry["data"]["action"] == "relay_follow"
521
522 assert second_entry["message"] ==
523 "@#{admin.nickname} followed relay: https://example.org/relay"
524 end
525
526 test "filters log by date", %{conn: conn, admin: admin} do
527 first_date = "2017-08-15T15:47:06Z"
528 second_date = "2017-08-20T15:47:06Z"
529
530 Repo.insert(%ModerationLog{
531 data: %{
532 actor: %{
533 "id" => admin.id,
534 "nickname" => admin.nickname,
535 "type" => "user"
536 },
537 action: "relay_follow",
538 target: "https://example.org/relay"
539 },
540 inserted_at: NaiveDateTime.from_iso8601!(first_date)
541 })
542
543 Repo.insert(%ModerationLog{
544 data: %{
545 actor: %{
546 "id" => admin.id,
547 "nickname" => admin.nickname,
548 "type" => "user"
549 },
550 action: "relay_unfollow",
551 target: "https://example.org/relay"
552 },
553 inserted_at: NaiveDateTime.from_iso8601!(second_date)
554 })
555
556 conn1 =
557 get(
558 conn,
559 "/api/v1/pleroma/admin/moderation_log?start_date=#{second_date}"
560 )
561
562 response1 = json_response(conn1, 200)
563 [first_entry] = response1["items"]
564
565 assert response1["total"] == 1
566 assert first_entry["data"]["action"] == "relay_unfollow"
567
568 assert first_entry["message"] ==
569 "@#{admin.nickname} unfollowed relay: https://example.org/relay"
570 end
571
572 test "returns log filtered by user", %{conn: conn, admin: admin, moderator: moderator} do
573 Repo.insert(%ModerationLog{
574 data: %{
575 actor: %{
576 "id" => admin.id,
577 "nickname" => admin.nickname,
578 "type" => "user"
579 },
580 action: "relay_follow",
581 target: "https://example.org/relay"
582 }
583 })
584
585 Repo.insert(%ModerationLog{
586 data: %{
587 actor: %{
588 "id" => moderator.id,
589 "nickname" => moderator.nickname,
590 "type" => "user"
591 },
592 action: "relay_unfollow",
593 target: "https://example.org/relay"
594 }
595 })
596
597 conn1 = get(conn, "/api/v1/pleroma/admin/moderation_log?user_id=#{moderator.id}")
598
599 response1 = json_response(conn1, 200)
600 [first_entry] = response1["items"]
601
602 assert response1["total"] == 1
603 assert get_in(first_entry, ["data", "actor", "id"]) == moderator.id
604 end
605
606 test "returns log filtered by search", %{conn: conn, moderator: moderator} do
607 ModerationLog.insert_log(%{
608 actor: moderator,
609 action: "relay_follow",
610 target: "https://example.org/relay"
611 })
612
613 ModerationLog.insert_log(%{
614 actor: moderator,
615 action: "relay_unfollow",
616 target: "https://example.org/relay"
617 })
618
619 conn1 = get(conn, "/api/v1/pleroma/admin/moderation_log?search=unfo")
620
621 response1 = json_response(conn1, 200)
622 [first_entry] = response1["items"]
623
624 assert response1["total"] == 1
625
626 assert get_in(first_entry, ["data", "message"]) ==
627 "@#{moderator.nickname} unfollowed relay: https://example.org/relay"
628 end
629 end
630
631 test "gets a remote users when [:instance, :limit_to_local_content] is set to :unauthenticated",
632 %{conn: conn} do
633 clear_config(Pleroma.Config.get([:instance, :limit_to_local_content]), :unauthenticated)
634 user = insert(:user, %{local: false, nickname: "u@peer1.com"})
635 conn = get(conn, "/api/v1/pleroma/admin/users/#{user.nickname}/credentials")
636
637 assert json_response(conn, 200)
638 end
639
640 describe "GET /users/:nickname/credentials" do
641 test "gets the user credentials", %{conn: conn} do
642 user = insert(:user)
643 conn = get(conn, "/api/v1/pleroma/admin/users/#{user.nickname}/credentials")
644
645 response = assert json_response(conn, 200)
646 assert response["email"] == user.email
647 end
648
649 test "returns 403 if requested by a non-admin" do
650 user = insert(:user)
651
652 conn =
653 build_conn()
654 |> assign(:user, user)
655 |> get("/api/v1/pleroma/admin/users/#{user.nickname}/credentials")
656
657 assert json_response(conn, :forbidden)
658 end
659 end
660
661 describe "PATCH /users/:nickname/credentials" do
662 setup do
663 user = insert(:user)
664 [user: user]
665 end
666
667 test "changes password and email", %{conn: conn, admin: admin, user: user} do
668 assert user.password_reset_pending == false
669
670 conn =
671 patch(conn, "/api/v1/pleroma/admin/users/#{user.nickname}/credentials", %{
672 "password" => "new_password",
673 "email" => "new_email@example.com",
674 "name" => "new_name"
675 })
676
677 assert json_response(conn, 200) == %{"status" => "success"}
678
679 ObanHelpers.perform_all()
680
681 updated_user = User.get_by_id(user.id)
682
683 assert updated_user.email == "new_email@example.com"
684 assert updated_user.name == "new_name"
685 assert updated_user.password_hash != user.password_hash
686 assert updated_user.password_reset_pending == true
687
688 [log_entry2, log_entry1] = ModerationLog |> Repo.all() |> Enum.sort()
689
690 assert ModerationLog.get_log_entry_message(log_entry1) ==
691 "@#{admin.nickname} updated users: @#{user.nickname}"
692
693 assert ModerationLog.get_log_entry_message(log_entry2) ==
694 "@#{admin.nickname} forced password reset for users: @#{user.nickname}"
695 end
696
697 test "returns 403 if requested by a non-admin", %{user: user} do
698 conn =
699 build_conn()
700 |> assign(:user, user)
701 |> patch("/api/v1/pleroma/admin/users/#{user.nickname}/credentials", %{
702 "password" => "new_password",
703 "email" => "new_email@example.com",
704 "name" => "new_name"
705 })
706
707 assert json_response(conn, :forbidden)
708 end
709
710 test "changes actor type from permitted list", %{conn: conn, user: user} do
711 assert user.actor_type == "Person"
712
713 assert patch(conn, "/api/v1/pleroma/admin/users/#{user.nickname}/credentials", %{
714 "actor_type" => "Service"
715 })
716 |> json_response(200) == %{"status" => "success"}
717
718 updated_user = User.get_by_id(user.id)
719
720 assert updated_user.actor_type == "Service"
721
722 assert patch(conn, "/api/v1/pleroma/admin/users/#{user.nickname}/credentials", %{
723 "actor_type" => "Application"
724 })
725 |> json_response(400) == %{"errors" => %{"actor_type" => "is invalid"}}
726 end
727
728 test "update non existing user", %{conn: conn} do
729 assert patch(conn, "/api/v1/pleroma/admin/users/non-existing/credentials", %{
730 "password" => "new_password"
731 })
732 |> json_response(404) == %{"error" => "Not found"}
733 end
734 end
735
736 describe "PATCH /users/:nickname/force_password_reset" do
737 test "sets password_reset_pending to true", %{conn: conn} do
738 user = insert(:user)
739 assert user.password_reset_pending == false
740
741 conn =
742 patch(conn, "/api/v1/pleroma/admin/users/force_password_reset", %{
743 nicknames: [user.nickname]
744 })
745
746 assert empty_json_response(conn) == ""
747
748 ObanHelpers.perform_all()
749
750 assert User.get_by_id(user.id).password_reset_pending == true
751 end
752 end
753
754 describe "PATCH /confirm_email" do
755 test "it confirms emails of two users", %{conn: conn, admin: admin} do
756 [first_user, second_user] = insert_pair(:user, is_confirmed: false)
757
758 refute first_user.is_confirmed
759 refute second_user.is_confirmed
760
761 ret_conn =
762 patch(conn, "/api/v1/pleroma/admin/users/confirm_email", %{
763 nicknames: [
764 first_user.nickname,
765 second_user.nickname
766 ]
767 })
768
769 assert ret_conn.status == 200
770
771 first_user = User.get_by_id(first_user.id)
772 second_user = User.get_by_id(second_user.id)
773
774 assert first_user.is_confirmed
775 assert second_user.is_confirmed
776
777 log_entry = Repo.one(ModerationLog)
778
779 assert ModerationLog.get_log_entry_message(log_entry) ==
780 "@#{admin.nickname} confirmed email for users: @#{first_user.nickname}, @#{second_user.nickname}"
781 end
782 end
783
784 describe "PATCH /resend_confirmation_email" do
785 test "it resend emails for two users", %{conn: conn, admin: admin} do
786 [first_user, second_user] = insert_pair(:user, is_confirmed: false)
787
788 ret_conn =
789 patch(conn, "/api/v1/pleroma/admin/users/resend_confirmation_email", %{
790 nicknames: [
791 first_user.nickname,
792 second_user.nickname
793 ]
794 })
795
796 assert ret_conn.status == 200
797
798 log_entry = Repo.one(ModerationLog)
799
800 assert ModerationLog.get_log_entry_message(log_entry) ==
801 "@#{admin.nickname} re-sent confirmation email for users: @#{first_user.nickname}, @#{second_user.nickname}"
802
803 ObanHelpers.perform_all()
804
805 Pleroma.Emails.UserEmail.account_confirmation_email(first_user)
806 |> assert_email_sent()
807 end
808 end
809
810 describe "/api/v1/pleroma/admin/stats" do
811 test "status visibility count", %{conn: conn} do
812 user = insert(:user)
813 CommonAPI.post(user, %{visibility: "public", status: "hey"})
814 CommonAPI.post(user, %{visibility: "unlisted", status: "hey"})
815 CommonAPI.post(user, %{visibility: "unlisted", status: "hey"})
816
817 response =
818 conn
819 |> get("/api/v1/pleroma/admin/stats")
820 |> json_response(200)
821
822 assert %{"direct" => 0, "private" => 0, "public" => 1, "unlisted" => 2} =
823 response["status_visibility"]
824 end
825
826 test "by instance", %{conn: conn} do
827 user1 = insert(:user)
828 instance2 = "instance2.tld"
829 user2 = insert(:user, %{ap_id: "https://#{instance2}/@actor"})
830
831 CommonAPI.post(user1, %{visibility: "public", status: "hey"})
832 CommonAPI.post(user2, %{visibility: "unlisted", status: "hey"})
833 CommonAPI.post(user2, %{visibility: "private", status: "hey"})
834
835 response =
836 conn
837 |> get("/api/v1/pleroma/admin/stats", instance: instance2)
838 |> json_response(200)
839
840 assert %{"direct" => 0, "private" => 1, "public" => 0, "unlisted" => 1} =
841 response["status_visibility"]
842 end
843 end
844
845 describe "/api/v1/pleroma/backups" do
846 test "it creates a backup", %{conn: conn} do
847 admin = %{id: admin_id, nickname: admin_nickname} = insert(:user, is_admin: true)
848 token = insert(:oauth_admin_token, user: admin)
849 user = %{id: user_id, nickname: user_nickname} = insert(:user)
850
851 assert "" ==
852 conn
853 |> assign(:user, admin)
854 |> assign(:token, token)
855 |> post("/api/v1/pleroma/admin/backups", %{nickname: user.nickname})
856 |> json_response(200)
857
858 assert [backup] = Repo.all(Pleroma.User.Backup)
859
860 ObanHelpers.perform_all()
861
862 email = Pleroma.Emails.UserEmail.backup_is_ready_email(backup, admin.id)
863
864 assert String.contains?(email.html_body, "Admin @#{admin.nickname} requested a full backup")
865 assert_email_sent(to: {user.name, user.email}, html_body: email.html_body)
866
867 log_message = "@#{admin_nickname} requested account backup for @#{user_nickname}"
868
869 assert [
870 %{
871 data: %{
872 "action" => "create_backup",
873 "actor" => %{
874 "id" => ^admin_id,
875 "nickname" => ^admin_nickname
876 },
877 "message" => ^log_message,
878 "subject" => %{
879 "id" => ^user_id,
880 "nickname" => ^user_nickname
881 }
882 }
883 }
884 ] = Pleroma.ModerationLog |> Repo.all()
885 end
886
887 test "it doesn't limit admins", %{conn: conn} do
888 admin = insert(:user, is_admin: true)
889 token = insert(:oauth_admin_token, user: admin)
890 user = insert(:user)
891
892 assert "" ==
893 conn
894 |> assign(:user, admin)
895 |> assign(:token, token)
896 |> post("/api/v1/pleroma/admin/backups", %{nickname: user.nickname})
897 |> json_response(200)
898
899 assert [_backup] = Repo.all(Pleroma.User.Backup)
900
901 assert "" ==
902 conn
903 |> assign(:user, admin)
904 |> assign(:token, token)
905 |> post("/api/v1/pleroma/admin/backups", %{nickname: user.nickname})
906 |> json_response(200)
907
908 assert Repo.aggregate(Pleroma.User.Backup, :count) == 2
909 end
910 end
911 end
912
913 # Needed for testing
914 defmodule Pleroma.Web.Endpoint.NotReal do
915 end
916
917 defmodule Pleroma.Captcha.NotReal do
918 end