52900026f85cb5375faa5530deecc9babc2a7e0a
[akkoma] / lib / pleroma / web / admin_api / controllers / admin_api_controller.ex
1 # Pleroma: A lightweight social networking server
2 # Copyright © 2017-2020 Pleroma Authors <https://pleroma.social/>
3 # SPDX-License-Identifier: AGPL-3.0-only
4
5 defmodule Pleroma.Web.AdminAPI.AdminAPIController do
6 use Pleroma.Web, :controller
7
8 import Pleroma.Web.ControllerHelper, only: [json_response: 3]
9
10 alias Pleroma.Activity
11 alias Pleroma.Config
12 alias Pleroma.MFA
13 alias Pleroma.ModerationLog
14 alias Pleroma.Plugs.OAuthScopesPlug
15 alias Pleroma.ReportNote
16 alias Pleroma.Stats
17 alias Pleroma.User
18 alias Pleroma.UserInviteToken
19 alias Pleroma.Web.ActivityPub.ActivityPub
20 alias Pleroma.Web.ActivityPub.Builder
21 alias Pleroma.Web.ActivityPub.Pipeline
22 alias Pleroma.Web.ActivityPub.Relay
23 alias Pleroma.Web.ActivityPub.Utils
24 alias Pleroma.Web.AdminAPI
25 alias Pleroma.Web.AdminAPI.AccountView
26 alias Pleroma.Web.AdminAPI.ModerationLogView
27 alias Pleroma.Web.AdminAPI.Report
28 alias Pleroma.Web.AdminAPI.ReportView
29 alias Pleroma.Web.AdminAPI.Search
30 alias Pleroma.Web.CommonAPI
31 alias Pleroma.Web.Endpoint
32 alias Pleroma.Web.MastodonAPI
33 alias Pleroma.Web.MastodonAPI.AppView
34 alias Pleroma.Web.OAuth.App
35 alias Pleroma.Web.Router
36
37 require Logger
38
39 @users_page_size 50
40
41 plug(
42 OAuthScopesPlug,
43 %{scopes: ["read:accounts"], admin: true}
44 when action in [:list_users, :user_show, :right_get, :show_user_credentials]
45 )
46
47 plug(
48 OAuthScopesPlug,
49 %{scopes: ["write:accounts"], admin: true}
50 when action in [
51 :get_password_reset,
52 :force_password_reset,
53 :user_delete,
54 :users_create,
55 :user_toggle_activation,
56 :user_activate,
57 :user_deactivate,
58 :tag_users,
59 :untag_users,
60 :right_add,
61 :right_add_multiple,
62 :right_delete,
63 :disable_mfa,
64 :right_delete_multiple,
65 :update_user_credentials
66 ]
67 )
68
69 plug(OAuthScopesPlug, %{scopes: ["read:invites"], admin: true} when action == :invites)
70
71 plug(
72 OAuthScopesPlug,
73 %{scopes: ["write:invites"], admin: true}
74 when action in [:create_invite_token, :revoke_invite, :email_invite]
75 )
76
77 plug(
78 OAuthScopesPlug,
79 %{scopes: ["write:follows"], admin: true}
80 when action in [:user_follow, :user_unfollow, :relay_follow, :relay_unfollow]
81 )
82
83 plug(
84 OAuthScopesPlug,
85 %{scopes: ["read:reports"], admin: true}
86 when action in [:list_reports, :report_show]
87 )
88
89 plug(
90 OAuthScopesPlug,
91 %{scopes: ["write:reports"], admin: true}
92 when action in [:reports_update, :report_notes_create, :report_notes_delete]
93 )
94
95 plug(
96 OAuthScopesPlug,
97 %{scopes: ["read:statuses"], admin: true}
98 when action in [:list_user_statuses, :list_instance_statuses]
99 )
100
101 plug(
102 OAuthScopesPlug,
103 %{scopes: ["read"], admin: true}
104 when action in [
105 :list_log,
106 :stats,
107 :relay_list,
108 :need_reboot
109 ]
110 )
111
112 plug(
113 OAuthScopesPlug,
114 %{scopes: ["write"], admin: true}
115 when action in [
116 :restart,
117 :resend_confirmation_email,
118 :confirm_email,
119 :oauth_app_create,
120 :oauth_app_list,
121 :oauth_app_update,
122 :oauth_app_delete,
123 :reload_emoji
124 ]
125 )
126
127 action_fallback(AdminAPI.FallbackController)
128
129 def user_delete(conn, %{"nickname" => nickname}) do
130 user_delete(conn, %{"nicknames" => [nickname]})
131 end
132
133 def user_delete(%{assigns: %{user: admin}} = conn, %{"nicknames" => nicknames}) do
134 users =
135 nicknames
136 |> Enum.map(&User.get_cached_by_nickname/1)
137
138 users
139 |> Enum.each(fn user ->
140 {:ok, delete_data, _} = Builder.delete(admin, user.ap_id)
141 Pipeline.common_pipeline(delete_data, local: true)
142 end)
143
144 ModerationLog.insert_log(%{
145 actor: admin,
146 subject: users,
147 action: "delete"
148 })
149
150 conn
151 |> json(nicknames)
152 end
153
154 def user_follow(%{assigns: %{user: admin}} = conn, %{
155 "follower" => follower_nick,
156 "followed" => followed_nick
157 }) do
158 with %User{} = follower <- User.get_cached_by_nickname(follower_nick),
159 %User{} = followed <- User.get_cached_by_nickname(followed_nick) do
160 User.follow(follower, followed)
161
162 ModerationLog.insert_log(%{
163 actor: admin,
164 followed: followed,
165 follower: follower,
166 action: "follow"
167 })
168 end
169
170 conn
171 |> json("ok")
172 end
173
174 def user_unfollow(%{assigns: %{user: admin}} = conn, %{
175 "follower" => follower_nick,
176 "followed" => followed_nick
177 }) do
178 with %User{} = follower <- User.get_cached_by_nickname(follower_nick),
179 %User{} = followed <- User.get_cached_by_nickname(followed_nick) do
180 User.unfollow(follower, followed)
181
182 ModerationLog.insert_log(%{
183 actor: admin,
184 followed: followed,
185 follower: follower,
186 action: "unfollow"
187 })
188 end
189
190 conn
191 |> json("ok")
192 end
193
194 def users_create(%{assigns: %{user: admin}} = conn, %{"users" => users}) do
195 changesets =
196 Enum.map(users, fn %{"nickname" => nickname, "email" => email, "password" => password} ->
197 user_data = %{
198 nickname: nickname,
199 name: nickname,
200 email: email,
201 password: password,
202 password_confirmation: password,
203 bio: "."
204 }
205
206 User.register_changeset(%User{}, user_data, need_confirmation: false)
207 end)
208 |> Enum.reduce(Ecto.Multi.new(), fn changeset, multi ->
209 Ecto.Multi.insert(multi, Ecto.UUID.generate(), changeset)
210 end)
211
212 case Pleroma.Repo.transaction(changesets) do
213 {:ok, users} ->
214 res =
215 users
216 |> Map.values()
217 |> Enum.map(fn user ->
218 {:ok, user} = User.post_register_action(user)
219
220 user
221 end)
222 |> Enum.map(&AccountView.render("created.json", %{user: &1}))
223
224 ModerationLog.insert_log(%{
225 actor: admin,
226 subjects: Map.values(users),
227 action: "create"
228 })
229
230 conn
231 |> json(res)
232
233 {:error, id, changeset, _} ->
234 res =
235 Enum.map(changesets.operations, fn
236 {current_id, {:changeset, _current_changeset, _}} when current_id == id ->
237 AccountView.render("create-error.json", %{changeset: changeset})
238
239 {_, {:changeset, current_changeset, _}} ->
240 AccountView.render("create-error.json", %{changeset: current_changeset})
241 end)
242
243 conn
244 |> put_status(:conflict)
245 |> json(res)
246 end
247 end
248
249 def user_show(conn, %{"nickname" => nickname}) do
250 with %User{} = user <- User.get_cached_by_nickname_or_id(nickname) do
251 conn
252 |> put_view(AccountView)
253 |> render("show.json", %{user: user})
254 else
255 _ -> {:error, :not_found}
256 end
257 end
258
259 def list_instance_statuses(conn, %{"instance" => instance} = params) do
260 with_reblogs = params["with_reblogs"] == "true" || params["with_reblogs"] == true
261 {page, page_size} = page_params(params)
262
263 activities =
264 ActivityPub.fetch_statuses(nil, %{
265 "instance" => instance,
266 "limit" => page_size,
267 "offset" => (page - 1) * page_size,
268 "exclude_reblogs" => !with_reblogs && "true"
269 })
270
271 conn
272 |> put_view(AdminAPI.StatusView)
273 |> render("index.json", %{activities: activities, as: :activity})
274 end
275
276 def list_user_statuses(conn, %{"nickname" => nickname} = params) do
277 with_reblogs = params["with_reblogs"] == "true" || params["with_reblogs"] == true
278 godmode = params["godmode"] == "true" || params["godmode"] == true
279
280 with %User{} = user <- User.get_cached_by_nickname_or_id(nickname) do
281 {_, page_size} = page_params(params)
282
283 activities =
284 ActivityPub.fetch_user_activities(user, nil, %{
285 "limit" => page_size,
286 "godmode" => godmode,
287 "exclude_reblogs" => !with_reblogs && "true"
288 })
289
290 conn
291 |> put_view(MastodonAPI.StatusView)
292 |> render("index.json", %{activities: activities, as: :activity})
293 else
294 _ -> {:error, :not_found}
295 end
296 end
297
298 def user_toggle_activation(%{assigns: %{user: admin}} = conn, %{"nickname" => nickname}) do
299 user = User.get_cached_by_nickname(nickname)
300
301 {:ok, updated_user} = User.deactivate(user, !user.deactivated)
302
303 action = if user.deactivated, do: "activate", else: "deactivate"
304
305 ModerationLog.insert_log(%{
306 actor: admin,
307 subject: [user],
308 action: action
309 })
310
311 conn
312 |> put_view(AccountView)
313 |> render("show.json", %{user: updated_user})
314 end
315
316 def user_activate(%{assigns: %{user: admin}} = conn, %{"nicknames" => nicknames}) do
317 users = Enum.map(nicknames, &User.get_cached_by_nickname/1)
318 {:ok, updated_users} = User.deactivate(users, false)
319
320 ModerationLog.insert_log(%{
321 actor: admin,
322 subject: users,
323 action: "activate"
324 })
325
326 conn
327 |> put_view(AccountView)
328 |> render("index.json", %{users: Keyword.values(updated_users)})
329 end
330
331 def user_deactivate(%{assigns: %{user: admin}} = conn, %{"nicknames" => nicknames}) do
332 users = Enum.map(nicknames, &User.get_cached_by_nickname/1)
333 {:ok, updated_users} = User.deactivate(users, true)
334
335 ModerationLog.insert_log(%{
336 actor: admin,
337 subject: users,
338 action: "deactivate"
339 })
340
341 conn
342 |> put_view(AccountView)
343 |> render("index.json", %{users: Keyword.values(updated_users)})
344 end
345
346 def tag_users(%{assigns: %{user: admin}} = conn, %{"nicknames" => nicknames, "tags" => tags}) do
347 with {:ok, _} <- User.tag(nicknames, tags) do
348 ModerationLog.insert_log(%{
349 actor: admin,
350 nicknames: nicknames,
351 tags: tags,
352 action: "tag"
353 })
354
355 json_response(conn, :no_content, "")
356 end
357 end
358
359 def untag_users(%{assigns: %{user: admin}} = conn, %{"nicknames" => nicknames, "tags" => tags}) do
360 with {:ok, _} <- User.untag(nicknames, tags) do
361 ModerationLog.insert_log(%{
362 actor: admin,
363 nicknames: nicknames,
364 tags: tags,
365 action: "untag"
366 })
367
368 json_response(conn, :no_content, "")
369 end
370 end
371
372 def list_users(conn, params) do
373 {page, page_size} = page_params(params)
374 filters = maybe_parse_filters(params["filters"])
375
376 search_params = %{
377 query: params["query"],
378 page: page,
379 page_size: page_size,
380 tags: params["tags"],
381 name: params["name"],
382 email: params["email"]
383 }
384
385 with {:ok, users, count} <- Search.user(Map.merge(search_params, filters)) do
386 json(
387 conn,
388 AccountView.render("index.json", users: users, count: count, page_size: page_size)
389 )
390 end
391 end
392
393 @filters ~w(local external active deactivated is_admin is_moderator)
394
395 @spec maybe_parse_filters(String.t()) :: %{required(String.t()) => true} | %{}
396 defp maybe_parse_filters(filters) when is_nil(filters) or filters == "", do: %{}
397
398 defp maybe_parse_filters(filters) do
399 filters
400 |> String.split(",")
401 |> Enum.filter(&Enum.member?(@filters, &1))
402 |> Enum.map(&String.to_atom(&1))
403 |> Enum.into(%{}, &{&1, true})
404 end
405
406 def right_add_multiple(%{assigns: %{user: admin}} = conn, %{
407 "permission_group" => permission_group,
408 "nicknames" => nicknames
409 })
410 when permission_group in ["moderator", "admin"] do
411 update = %{:"is_#{permission_group}" => true}
412
413 users = nicknames |> Enum.map(&User.get_cached_by_nickname/1)
414
415 for u <- users, do: User.admin_api_update(u, update)
416
417 ModerationLog.insert_log(%{
418 action: "grant",
419 actor: admin,
420 subject: users,
421 permission: permission_group
422 })
423
424 json(conn, update)
425 end
426
427 def right_add_multiple(conn, _) do
428 render_error(conn, :not_found, "No such permission_group")
429 end
430
431 def right_add(%{assigns: %{user: admin}} = conn, %{
432 "permission_group" => permission_group,
433 "nickname" => nickname
434 })
435 when permission_group in ["moderator", "admin"] do
436 fields = %{:"is_#{permission_group}" => true}
437
438 {:ok, user} =
439 nickname
440 |> User.get_cached_by_nickname()
441 |> User.admin_api_update(fields)
442
443 ModerationLog.insert_log(%{
444 action: "grant",
445 actor: admin,
446 subject: [user],
447 permission: permission_group
448 })
449
450 json(conn, fields)
451 end
452
453 def right_add(conn, _) do
454 render_error(conn, :not_found, "No such permission_group")
455 end
456
457 def right_get(conn, %{"nickname" => nickname}) do
458 user = User.get_cached_by_nickname(nickname)
459
460 conn
461 |> json(%{
462 is_moderator: user.is_moderator,
463 is_admin: user.is_admin
464 })
465 end
466
467 def right_delete_multiple(
468 %{assigns: %{user: %{nickname: admin_nickname} = admin}} = conn,
469 %{
470 "permission_group" => permission_group,
471 "nicknames" => nicknames
472 }
473 )
474 when permission_group in ["moderator", "admin"] do
475 with false <- Enum.member?(nicknames, admin_nickname) do
476 update = %{:"is_#{permission_group}" => false}
477
478 users = nicknames |> Enum.map(&User.get_cached_by_nickname/1)
479
480 for u <- users, do: User.admin_api_update(u, update)
481
482 ModerationLog.insert_log(%{
483 action: "revoke",
484 actor: admin,
485 subject: users,
486 permission: permission_group
487 })
488
489 json(conn, update)
490 else
491 _ -> render_error(conn, :forbidden, "You can't revoke your own admin/moderator status.")
492 end
493 end
494
495 def right_delete_multiple(conn, _) do
496 render_error(conn, :not_found, "No such permission_group")
497 end
498
499 def right_delete(
500 %{assigns: %{user: admin}} = conn,
501 %{
502 "permission_group" => permission_group,
503 "nickname" => nickname
504 }
505 )
506 when permission_group in ["moderator", "admin"] do
507 fields = %{:"is_#{permission_group}" => false}
508
509 {:ok, user} =
510 nickname
511 |> User.get_cached_by_nickname()
512 |> User.admin_api_update(fields)
513
514 ModerationLog.insert_log(%{
515 action: "revoke",
516 actor: admin,
517 subject: [user],
518 permission: permission_group
519 })
520
521 json(conn, fields)
522 end
523
524 def right_delete(%{assigns: %{user: %{nickname: nickname}}} = conn, %{"nickname" => nickname}) do
525 render_error(conn, :forbidden, "You can't revoke your own admin status.")
526 end
527
528 def relay_list(conn, _params) do
529 with {:ok, list} <- Relay.list() do
530 json(conn, %{relays: list})
531 else
532 _ ->
533 conn
534 |> put_status(500)
535 end
536 end
537
538 def relay_follow(%{assigns: %{user: admin}} = conn, %{"relay_url" => target}) do
539 with {:ok, _message} <- Relay.follow(target) do
540 ModerationLog.insert_log(%{
541 action: "relay_follow",
542 actor: admin,
543 target: target
544 })
545
546 json(conn, target)
547 else
548 _ ->
549 conn
550 |> put_status(500)
551 |> json(target)
552 end
553 end
554
555 def relay_unfollow(%{assigns: %{user: admin}} = conn, %{"relay_url" => target}) do
556 with {:ok, _message} <- Relay.unfollow(target) do
557 ModerationLog.insert_log(%{
558 action: "relay_unfollow",
559 actor: admin,
560 target: target
561 })
562
563 json(conn, target)
564 else
565 _ ->
566 conn
567 |> put_status(500)
568 |> json(target)
569 end
570 end
571
572 @doc "Sends registration invite via email"
573 def email_invite(%{assigns: %{user: user}} = conn, %{"email" => email} = params) do
574 with {_, false} <- {:registrations_open, Config.get([:instance, :registrations_open])},
575 {_, true} <- {:invites_enabled, Config.get([:instance, :invites_enabled])},
576 {:ok, invite_token} <- UserInviteToken.create_invite(),
577 email <-
578 Pleroma.Emails.UserEmail.user_invitation_email(
579 user,
580 invite_token,
581 email,
582 params["name"]
583 ),
584 {:ok, _} <- Pleroma.Emails.Mailer.deliver(email) do
585 json_response(conn, :no_content, "")
586 else
587 {:registrations_open, _} ->
588 {:error, "To send invites you need to set the `registrations_open` option to false."}
589
590 {:invites_enabled, _} ->
591 {:error, "To send invites you need to set the `invites_enabled` option to true."}
592 end
593 end
594
595 @doc "Create an account registration invite token"
596 def create_invite_token(conn, params) do
597 opts = %{}
598
599 opts =
600 if params["max_use"],
601 do: Map.put(opts, :max_use, params["max_use"]),
602 else: opts
603
604 opts =
605 if params["expires_at"],
606 do: Map.put(opts, :expires_at, params["expires_at"]),
607 else: opts
608
609 {:ok, invite} = UserInviteToken.create_invite(opts)
610
611 json(conn, AccountView.render("invite.json", %{invite: invite}))
612 end
613
614 @doc "Get list of created invites"
615 def invites(conn, _params) do
616 invites = UserInviteToken.list_invites()
617
618 conn
619 |> put_view(AccountView)
620 |> render("invites.json", %{invites: invites})
621 end
622
623 @doc "Revokes invite by token"
624 def revoke_invite(conn, %{"token" => token}) do
625 with {:ok, invite} <- UserInviteToken.find_by_token(token),
626 {:ok, updated_invite} = UserInviteToken.update_invite(invite, %{used: true}) do
627 conn
628 |> put_view(AccountView)
629 |> render("invite.json", %{invite: updated_invite})
630 else
631 nil -> {:error, :not_found}
632 end
633 end
634
635 @doc "Get a password reset token (base64 string) for given nickname"
636 def get_password_reset(conn, %{"nickname" => nickname}) do
637 (%User{local: true} = user) = User.get_cached_by_nickname(nickname)
638 {:ok, token} = Pleroma.PasswordResetToken.create_token(user)
639
640 conn
641 |> json(%{
642 token: token.token,
643 link: Router.Helpers.reset_password_url(Endpoint, :reset, token.token)
644 })
645 end
646
647 @doc "Force password reset for a given user"
648 def force_password_reset(%{assigns: %{user: admin}} = conn, %{"nicknames" => nicknames}) do
649 users = nicknames |> Enum.map(&User.get_cached_by_nickname/1)
650
651 Enum.each(users, &User.force_password_reset_async/1)
652
653 ModerationLog.insert_log(%{
654 actor: admin,
655 subject: users,
656 action: "force_password_reset"
657 })
658
659 json_response(conn, :no_content, "")
660 end
661
662 @doc "Disable mfa for user's account."
663 def disable_mfa(conn, %{"nickname" => nickname}) do
664 case User.get_by_nickname(nickname) do
665 %User{} = user ->
666 MFA.disable(user)
667 json(conn, nickname)
668
669 _ ->
670 {:error, :not_found}
671 end
672 end
673
674 @doc "Show a given user's credentials"
675 def show_user_credentials(%{assigns: %{user: admin}} = conn, %{"nickname" => nickname}) do
676 with %User{} = user <- User.get_cached_by_nickname_or_id(nickname) do
677 conn
678 |> put_view(AccountView)
679 |> render("credentials.json", %{user: user, for: admin})
680 else
681 _ -> {:error, :not_found}
682 end
683 end
684
685 @doc "Updates a given user"
686 def update_user_credentials(
687 %{assigns: %{user: admin}} = conn,
688 %{"nickname" => nickname} = params
689 ) do
690 with {_, %User{} = user} <- {:user, User.get_cached_by_nickname(nickname)},
691 {:ok, _user} <-
692 User.update_as_admin(user, params) do
693 ModerationLog.insert_log(%{
694 actor: admin,
695 subject: [user],
696 action: "updated_users"
697 })
698
699 if params["password"] do
700 User.force_password_reset_async(user)
701 end
702
703 ModerationLog.insert_log(%{
704 actor: admin,
705 subject: [user],
706 action: "force_password_reset"
707 })
708
709 json(conn, %{status: "success"})
710 else
711 {:error, changeset} ->
712 errors = Map.new(changeset.errors, fn {key, {error, _}} -> {key, error} end)
713
714 json(conn, %{errors: errors})
715
716 _ ->
717 json(conn, %{error: "Unable to update user."})
718 end
719 end
720
721 def list_reports(conn, params) do
722 {page, page_size} = page_params(params)
723
724 reports = Utils.get_reports(params, page, page_size)
725
726 conn
727 |> put_view(ReportView)
728 |> render("index.json", %{reports: reports})
729 end
730
731 def report_show(conn, %{"id" => id}) do
732 with %Activity{} = report <- Activity.get_by_id(id) do
733 conn
734 |> put_view(ReportView)
735 |> render("show.json", Report.extract_report_info(report))
736 else
737 _ -> {:error, :not_found}
738 end
739 end
740
741 def reports_update(%{assigns: %{user: admin}} = conn, %{"reports" => reports}) do
742 result =
743 reports
744 |> Enum.map(fn report ->
745 with {:ok, activity} <- CommonAPI.update_report_state(report["id"], report["state"]) do
746 ModerationLog.insert_log(%{
747 action: "report_update",
748 actor: admin,
749 subject: activity
750 })
751
752 activity
753 else
754 {:error, message} -> %{id: report["id"], error: message}
755 end
756 end)
757
758 case Enum.any?(result, &Map.has_key?(&1, :error)) do
759 true -> json_response(conn, :bad_request, result)
760 false -> json_response(conn, :no_content, "")
761 end
762 end
763
764 def report_notes_create(%{assigns: %{user: user}} = conn, %{
765 "id" => report_id,
766 "content" => content
767 }) do
768 with {:ok, _} <- ReportNote.create(user.id, report_id, content) do
769 ModerationLog.insert_log(%{
770 action: "report_note",
771 actor: user,
772 subject: Activity.get_by_id(report_id),
773 text: content
774 })
775
776 json_response(conn, :no_content, "")
777 else
778 _ -> json_response(conn, :bad_request, "")
779 end
780 end
781
782 def report_notes_delete(%{assigns: %{user: user}} = conn, %{
783 "id" => note_id,
784 "report_id" => report_id
785 }) do
786 with {:ok, note} <- ReportNote.destroy(note_id) do
787 ModerationLog.insert_log(%{
788 action: "report_note_delete",
789 actor: user,
790 subject: Activity.get_by_id(report_id),
791 text: note.content
792 })
793
794 json_response(conn, :no_content, "")
795 else
796 _ -> json_response(conn, :bad_request, "")
797 end
798 end
799
800 def list_log(conn, params) do
801 {page, page_size} = page_params(params)
802
803 log =
804 ModerationLog.get_all(%{
805 page: page,
806 page_size: page_size,
807 start_date: params["start_date"],
808 end_date: params["end_date"],
809 user_id: params["user_id"],
810 search: params["search"]
811 })
812
813 conn
814 |> put_view(ModerationLogView)
815 |> render("index.json", %{log: log})
816 end
817
818 def restart(conn, _params) do
819 with :ok <- configurable_from_database() do
820 Restarter.Pleroma.restart(Config.get(:env), 50)
821
822 json(conn, %{})
823 end
824 end
825
826 def need_reboot(conn, _params) do
827 json(conn, %{need_reboot: Restarter.Pleroma.need_reboot?()})
828 end
829
830 defp configurable_from_database do
831 if Config.get(:configurable_from_database) do
832 :ok
833 else
834 {:error, "To use this endpoint you need to enable configuration from database."}
835 end
836 end
837
838 def reload_emoji(conn, _params) do
839 Pleroma.Emoji.reload()
840
841 conn |> json("ok")
842 end
843
844 def confirm_email(%{assigns: %{user: admin}} = conn, %{"nicknames" => nicknames}) do
845 users = nicknames |> Enum.map(&User.get_cached_by_nickname/1)
846
847 User.toggle_confirmation(users)
848
849 ModerationLog.insert_log(%{
850 actor: admin,
851 subject: users,
852 action: "confirm_email"
853 })
854
855 conn |> json("")
856 end
857
858 def resend_confirmation_email(%{assigns: %{user: admin}} = conn, %{"nicknames" => nicknames}) do
859 users = nicknames |> Enum.map(&User.get_cached_by_nickname/1)
860
861 User.try_send_confirmation_email(users)
862
863 ModerationLog.insert_log(%{
864 actor: admin,
865 subject: users,
866 action: "resend_confirmation_email"
867 })
868
869 conn |> json("")
870 end
871
872 def oauth_app_create(conn, params) do
873 params =
874 if params["name"] do
875 Map.put(params, "client_name", params["name"])
876 else
877 params
878 end
879
880 result =
881 case App.create(params) do
882 {:ok, app} ->
883 AppView.render("show.json", %{app: app, admin: true})
884
885 {:error, changeset} ->
886 App.errors(changeset)
887 end
888
889 json(conn, result)
890 end
891
892 def oauth_app_update(conn, params) do
893 params =
894 if params["name"] do
895 Map.put(params, "client_name", params["name"])
896 else
897 params
898 end
899
900 with {:ok, app} <- App.update(params) do
901 json(conn, AppView.render("show.json", %{app: app, admin: true}))
902 else
903 {:error, changeset} ->
904 json(conn, App.errors(changeset))
905
906 nil ->
907 json_response(conn, :bad_request, "")
908 end
909 end
910
911 def oauth_app_list(conn, params) do
912 {page, page_size} = page_params(params)
913
914 search_params = %{
915 client_name: params["name"],
916 client_id: params["client_id"],
917 page: page,
918 page_size: page_size
919 }
920
921 search_params =
922 if Map.has_key?(params, "trusted") do
923 Map.put(search_params, :trusted, params["trusted"])
924 else
925 search_params
926 end
927
928 with {:ok, apps, count} <- App.search(search_params) do
929 json(
930 conn,
931 AppView.render("index.json",
932 apps: apps,
933 count: count,
934 page_size: page_size,
935 admin: true
936 )
937 )
938 end
939 end
940
941 def oauth_app_delete(conn, params) do
942 with {:ok, _app} <- App.destroy(params["id"]) do
943 json_response(conn, :no_content, "")
944 else
945 _ -> json_response(conn, :bad_request, "")
946 end
947 end
948
949 def stats(conn, _) do
950 count = Stats.get_status_visibility_count()
951
952 conn
953 |> json(%{"status_visibility" => count})
954 end
955
956 defp page_params(params) do
957 {get_page(params["page"]), get_page_size(params["page_size"])}
958 end
959
960 defp get_page(page_string) when is_nil(page_string), do: 1
961
962 defp get_page(page_string) do
963 case Integer.parse(page_string) do
964 {page, _} -> page
965 :error -> 1
966 end
967 end
968
969 defp get_page_size(page_size_string) when is_nil(page_size_string), do: @users_page_size
970
971 defp get_page_size(page_size_string) do
972 case Integer.parse(page_size_string) do
973 {page_size, _} -> page_size
974 :error -> @users_page_size
975 end
976 end
977 end