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