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