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