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