1 # Pleroma: A lightweight social networking server
2 # Copyright © 2017-2020 Pleroma Authors <https://pleroma.social/>
3 # SPDX-License-Identifier: AGPL-3.0-only
5 defmodule Pleroma.Web.AdminAPI.AdminAPIController do
6 use Pleroma.Web, :controller
8 import Pleroma.Web.ControllerHelper, only: [json_response: 3]
10 alias Pleroma.Activity
12 alias Pleroma.ConfigDB
13 alias Pleroma.ModerationLog
14 alias Pleroma.Plugs.OAuthScopesPlug
15 alias Pleroma.ReportNote
18 alias Pleroma.UserInviteToken
19 alias Pleroma.Web.ActivityPub.ActivityPub
20 alias Pleroma.Web.ActivityPub.Relay
21 alias Pleroma.Web.ActivityPub.Utils
22 alias Pleroma.Web.AdminAPI.AccountView
23 alias Pleroma.Web.AdminAPI.ConfigView
24 alias Pleroma.Web.AdminAPI.ModerationLogView
25 alias Pleroma.Web.AdminAPI.Report
26 alias Pleroma.Web.AdminAPI.ReportView
27 alias Pleroma.Web.AdminAPI.Search
28 alias Pleroma.Web.CommonAPI
29 alias Pleroma.Web.Endpoint
30 alias Pleroma.Web.MastodonAPI.AppView
31 alias Pleroma.Web.MastodonAPI.StatusView
32 alias Pleroma.Web.OAuth.App
33 alias Pleroma.Web.Router
37 @descriptions_json Pleroma.Docs.JSON.compile()
42 %{scopes: ["read:accounts"], admin: true}
43 when action in [:list_users, :user_show, :right_get, :show_user_credentials]
48 %{scopes: ["write:accounts"], admin: true}
51 :force_password_reset,
54 :user_toggle_activation,
62 :right_delete_multiple,
63 :update_user_credentials
67 plug(OAuthScopesPlug, %{scopes: ["read:invites"], admin: true} when action == :invites)
71 %{scopes: ["write:invites"], admin: true}
72 when action in [:create_invite_token, :revoke_invite, :email_invite]
77 %{scopes: ["write:follows"], admin: true}
78 when action in [:user_follow, :user_unfollow, :relay_follow, :relay_unfollow]
83 %{scopes: ["read:reports"], admin: true}
84 when action in [:list_reports, :report_show]
89 %{scopes: ["write:reports"], admin: true}
90 when action in [:reports_update, :report_notes_create, :report_notes_delete]
95 %{scopes: ["read:statuses"], admin: true}
96 when action in [:list_statuses, :list_user_statuses, :list_instance_statuses]
101 %{scopes: ["write:statuses"], admin: true}
102 when action in [:status_update, :status_delete]
107 %{scopes: ["read"], admin: true}
113 :config_descriptions,
120 %{scopes: ["write"], admin: true}
124 :resend_confirmation_email,
134 action_fallback(:errors)
136 def user_delete(conn, %{"nickname" => nickname}) do
137 user_delete(conn, %{"nicknames" => [nickname]})
140 def user_delete(%{assigns: %{user: admin}} = conn, %{"nicknames" => nicknames}) do
141 users = nicknames |> Enum.map(&User.get_cached_by_nickname/1)
144 ModerationLog.insert_log(%{
154 def user_follow(%{assigns: %{user: admin}} = conn, %{
155 "follower" => follower_nick,
156 "followed" => followed_nick
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)
162 ModerationLog.insert_log(%{
174 def user_unfollow(%{assigns: %{user: admin}} = conn, %{
175 "follower" => follower_nick,
176 "followed" => followed_nick
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)
182 ModerationLog.insert_log(%{
194 def users_create(%{assigns: %{user: admin}} = conn, %{"users" => users}) do
196 Enum.map(users, fn %{"nickname" => nickname, "email" => email, "password" => password} ->
202 password_confirmation: password,
206 User.register_changeset(%User{}, user_data, need_confirmation: false)
208 |> Enum.reduce(Ecto.Multi.new(), fn changeset, multi ->
209 Ecto.Multi.insert(multi, Ecto.UUID.generate(), changeset)
212 case Pleroma.Repo.transaction(changesets) do
217 |> Enum.map(fn user ->
218 {:ok, user} = User.post_register_action(user)
222 |> Enum.map(&AccountView.render("created.json", %{user: &1}))
224 ModerationLog.insert_log(%{
226 subjects: Map.values(users),
233 {:error, id, changeset, _} ->
235 Enum.map(changesets.operations, fn
236 {current_id, {:changeset, _current_changeset, _}} when current_id == id ->
237 AccountView.render("create-error.json", %{changeset: changeset})
239 {_, {:changeset, current_changeset, _}} ->
240 AccountView.render("create-error.json", %{changeset: current_changeset})
244 |> put_status(:conflict)
249 def user_show(conn, %{"nickname" => nickname}) do
250 with %User{} = user <- User.get_cached_by_nickname_or_id(nickname) do
252 |> put_view(AccountView)
253 |> render("show.json", %{user: user})
255 _ -> {:error, :not_found}
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)
264 ActivityPub.fetch_statuses(nil, %{
265 "instance" => instance,
266 "limit" => page_size,
267 "offset" => (page - 1) * page_size,
268 "exclude_reblogs" => !with_reblogs && "true"
272 |> put_view(Pleroma.Web.AdminAPI.StatusView)
273 |> render("index.json", %{activities: activities, as: :activity, skip_relationships: false})
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
280 with %User{} = user <- User.get_cached_by_nickname_or_id(nickname) do
281 {_, page_size} = page_params(params)
284 ActivityPub.fetch_user_activities(user, nil, %{
285 "limit" => page_size,
286 "godmode" => godmode,
287 "exclude_reblogs" => !with_reblogs && "true"
291 |> put_view(StatusView)
292 |> render("index.json", %{activities: activities, as: :activity, skip_relationships: false})
294 _ -> {:error, :not_found}
298 def user_toggle_activation(%{assigns: %{user: admin}} = conn, %{"nickname" => nickname}) do
299 user = User.get_cached_by_nickname(nickname)
301 {:ok, updated_user} = User.deactivate(user, !user.deactivated)
303 action = if user.deactivated, do: "activate", else: "deactivate"
305 ModerationLog.insert_log(%{
312 |> put_view(AccountView)
313 |> render("show.json", %{user: updated_user})
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)
320 ModerationLog.insert_log(%{
327 |> put_view(AccountView)
328 |> render("index.json", %{users: Keyword.values(updated_users)})
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)
335 ModerationLog.insert_log(%{
342 |> put_view(AccountView)
343 |> render("index.json", %{users: Keyword.values(updated_users)})
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(%{
350 nicknames: nicknames,
355 json_response(conn, :no_content, "")
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(%{
363 nicknames: nicknames,
368 json_response(conn, :no_content, "")
372 def list_users(conn, params) do
373 {page, page_size} = page_params(params)
374 filters = maybe_parse_filters(params["filters"])
377 query: params["query"],
379 page_size: page_size,
380 tags: params["tags"],
381 name: params["name"],
382 email: params["email"]
385 with {:ok, users, count} <- Search.user(Map.merge(search_params, filters)),
386 {:ok, users, count} <- filter_service_users(users, count),
390 AccountView.render("index.json",
398 defp filter_service_users(users, count) do
399 filtered_users = Enum.reject(users, &service_user?/1)
400 count = if Enum.any?(users, &service_user?/1), do: length(filtered_users), else: count
402 {:ok, filtered_users, count}
405 defp service_user?(user) do
406 String.match?(user.ap_id, ~r/.*\/relay$/) or
407 String.match?(user.ap_id, ~r/.*\/internal\/fetch$/)
410 @filters ~w(local external active deactivated is_admin is_moderator)
412 @spec maybe_parse_filters(String.t()) :: %{required(String.t()) => true} | %{}
413 defp maybe_parse_filters(filters) when is_nil(filters) or filters == "", do: %{}
415 defp maybe_parse_filters(filters) do
418 |> Enum.filter(&Enum.member?(@filters, &1))
419 |> Enum.map(&String.to_atom(&1))
420 |> Enum.into(%{}, &{&1, true})
423 def right_add_multiple(%{assigns: %{user: admin}} = conn, %{
424 "permission_group" => permission_group,
425 "nicknames" => nicknames
427 when permission_group in ["moderator", "admin"] do
428 update = %{:"is_#{permission_group}" => true}
430 users = nicknames |> Enum.map(&User.get_cached_by_nickname/1)
432 for u <- users, do: User.admin_api_update(u, update)
434 ModerationLog.insert_log(%{
438 permission: permission_group
444 def right_add_multiple(conn, _) do
445 render_error(conn, :not_found, "No such permission_group")
448 def right_add(%{assigns: %{user: admin}} = conn, %{
449 "permission_group" => permission_group,
450 "nickname" => nickname
452 when permission_group in ["moderator", "admin"] do
453 fields = %{:"is_#{permission_group}" => true}
457 |> User.get_cached_by_nickname()
458 |> User.admin_api_update(fields)
460 ModerationLog.insert_log(%{
464 permission: permission_group
470 def right_add(conn, _) do
471 render_error(conn, :not_found, "No such permission_group")
474 def right_get(conn, %{"nickname" => nickname}) do
475 user = User.get_cached_by_nickname(nickname)
479 is_moderator: user.is_moderator,
480 is_admin: user.is_admin
484 def right_delete_multiple(
485 %{assigns: %{user: %{nickname: admin_nickname} = admin}} = conn,
487 "permission_group" => permission_group,
488 "nicknames" => nicknames
491 when permission_group in ["moderator", "admin"] do
492 with false <- Enum.member?(nicknames, admin_nickname) do
493 update = %{:"is_#{permission_group}" => false}
495 users = nicknames |> Enum.map(&User.get_cached_by_nickname/1)
497 for u <- users, do: User.admin_api_update(u, update)
499 ModerationLog.insert_log(%{
503 permission: permission_group
508 _ -> render_error(conn, :forbidden, "You can't revoke your own admin/moderator status.")
512 def right_delete_multiple(conn, _) do
513 render_error(conn, :not_found, "No such permission_group")
517 %{assigns: %{user: admin}} = conn,
519 "permission_group" => permission_group,
520 "nickname" => nickname
523 when permission_group in ["moderator", "admin"] do
524 fields = %{:"is_#{permission_group}" => false}
528 |> User.get_cached_by_nickname()
529 |> User.admin_api_update(fields)
531 ModerationLog.insert_log(%{
535 permission: permission_group
541 def right_delete(%{assigns: %{user: %{nickname: nickname}}} = conn, %{"nickname" => nickname}) do
542 render_error(conn, :forbidden, "You can't revoke your own admin status.")
545 def relay_list(conn, _params) do
546 with {:ok, list} <- Relay.list() do
547 json(conn, %{relays: list})
555 def relay_follow(%{assigns: %{user: admin}} = conn, %{"relay_url" => target}) do
556 with {:ok, _message} <- Relay.follow(target) do
557 ModerationLog.insert_log(%{
558 action: "relay_follow",
572 def relay_unfollow(%{assigns: %{user: admin}} = conn, %{"relay_url" => target}) do
573 with {:ok, _message} <- Relay.unfollow(target) do
574 ModerationLog.insert_log(%{
575 action: "relay_unfollow",
589 @doc "Sends registration invite via email"
590 def email_invite(%{assigns: %{user: user}} = conn, %{"email" => email} = params) do
591 with {_, false} <- {:registrations_open, Config.get([:instance, :registrations_open])},
592 {_, true} <- {:invites_enabled, Config.get([:instance, :invites_enabled])},
593 {:ok, invite_token} <- UserInviteToken.create_invite(),
595 Pleroma.Emails.UserEmail.user_invitation_email(
601 {:ok, _} <- Pleroma.Emails.Mailer.deliver(email) do
602 json_response(conn, :no_content, "")
604 {:registrations_open, _} ->
607 {:error, "To send invites you need to set the `registrations_open` option to false."}
610 {:invites_enabled, _} ->
613 {:error, "To send invites you need to set the `invites_enabled` option to true."}
618 @doc "Create an account registration invite token"
619 def create_invite_token(conn, params) do
623 if params["max_use"],
624 do: Map.put(opts, :max_use, params["max_use"]),
628 if params["expires_at"],
629 do: Map.put(opts, :expires_at, params["expires_at"]),
632 {:ok, invite} = UserInviteToken.create_invite(opts)
634 json(conn, AccountView.render("invite.json", %{invite: invite}))
637 @doc "Get list of created invites"
638 def invites(conn, _params) do
639 invites = UserInviteToken.list_invites()
642 |> put_view(AccountView)
643 |> render("invites.json", %{invites: invites})
646 @doc "Revokes invite by token"
647 def revoke_invite(conn, %{"token" => token}) do
648 with {:ok, invite} <- UserInviteToken.find_by_token(token),
649 {:ok, updated_invite} = UserInviteToken.update_invite(invite, %{used: true}) do
651 |> put_view(AccountView)
652 |> render("invite.json", %{invite: updated_invite})
654 nil -> {:error, :not_found}
658 @doc "Get a password reset token (base64 string) for given nickname"
659 def get_password_reset(conn, %{"nickname" => nickname}) do
660 (%User{local: true} = user) = User.get_cached_by_nickname(nickname)
661 {:ok, token} = Pleroma.PasswordResetToken.create_token(user)
666 link: Router.Helpers.reset_password_url(Endpoint, :reset, token.token)
670 @doc "Force password reset for a given user"
671 def force_password_reset(%{assigns: %{user: admin}} = conn, %{"nicknames" => nicknames}) do
672 users = nicknames |> Enum.map(&User.get_cached_by_nickname/1)
674 Enum.each(users, &User.force_password_reset_async/1)
676 ModerationLog.insert_log(%{
679 action: "force_password_reset"
682 json_response(conn, :no_content, "")
685 @doc "Show a given user's credentials"
686 def show_user_credentials(%{assigns: %{user: admin}} = conn, %{"nickname" => nickname}) do
687 with %User{} = user <- User.get_cached_by_nickname_or_id(nickname) do
689 |> put_view(AccountView)
690 |> render("credentials.json", %{user: user, for: admin})
692 _ -> {:error, :not_found}
696 @doc "Updates a given user"
697 def update_user_credentials(
698 %{assigns: %{user: admin}} = conn,
699 %{"nickname" => nickname} = params
701 with {_, user} <- {:user, User.get_cached_by_nickname(nickname)},
703 User.update_as_admin(user, params) do
704 ModerationLog.insert_log(%{
707 action: "updated_users"
710 if params["password"] do
711 User.force_password_reset_async(user)
714 ModerationLog.insert_log(%{
717 action: "force_password_reset"
720 json(conn, %{status: "success"})
722 {:error, changeset} ->
723 {_, {error, _}} = Enum.at(changeset.errors, 0)
724 json(conn, %{error: "New password #{error}."})
727 json(conn, %{error: "Unable to change password."})
731 def list_reports(conn, params) do
732 {page, page_size} = page_params(params)
734 reports = Utils.get_reports(params, page, page_size)
737 |> put_view(ReportView)
738 |> render("index.json", %{reports: reports})
741 def report_show(conn, %{"id" => id}) do
742 with %Activity{} = report <- Activity.get_by_id(id) do
744 |> put_view(ReportView)
745 |> render("show.json", Report.extract_report_info(report))
747 _ -> {:error, :not_found}
751 def reports_update(%{assigns: %{user: admin}} = conn, %{"reports" => reports}) do
754 |> Enum.map(fn report ->
755 with {:ok, activity} <- CommonAPI.update_report_state(report["id"], report["state"]) do
756 ModerationLog.insert_log(%{
757 action: "report_update",
764 {:error, message} -> %{id: report["id"], error: message}
768 case Enum.any?(result, &Map.has_key?(&1, :error)) do
769 true -> json_response(conn, :bad_request, result)
770 false -> json_response(conn, :no_content, "")
774 def report_notes_create(%{assigns: %{user: user}} = conn, %{
778 with {:ok, _} <- ReportNote.create(user.id, report_id, content) do
779 ModerationLog.insert_log(%{
780 action: "report_note",
782 subject: Activity.get_by_id(report_id),
786 json_response(conn, :no_content, "")
788 _ -> json_response(conn, :bad_request, "")
792 def report_notes_delete(%{assigns: %{user: user}} = conn, %{
794 "report_id" => report_id
796 with {:ok, note} <- ReportNote.destroy(note_id) do
797 ModerationLog.insert_log(%{
798 action: "report_note_delete",
800 subject: Activity.get_by_id(report_id),
804 json_response(conn, :no_content, "")
806 _ -> json_response(conn, :bad_request, "")
810 def list_statuses(%{assigns: %{user: _admin}} = conn, params) do
811 godmode = params["godmode"] == "true" || params["godmode"] == true
812 local_only = params["local_only"] == "true" || params["local_only"] == true
813 with_reblogs = params["with_reblogs"] == "true" || params["with_reblogs"] == true
814 {page, page_size} = page_params(params)
817 ActivityPub.fetch_statuses(nil, %{
818 "godmode" => godmode,
819 "local_only" => local_only,
820 "limit" => page_size,
821 "offset" => (page - 1) * page_size,
822 "exclude_reblogs" => !with_reblogs && "true"
826 |> put_view(Pleroma.Web.AdminAPI.StatusView)
827 |> render("index.json", %{activities: activities, as: :activity, skip_relationships: false})
830 def status_update(%{assigns: %{user: admin}} = conn, %{"id" => id} = params) do
831 with {:ok, activity} <- CommonAPI.update_activity_scope(id, params) do
832 {:ok, sensitive} = Ecto.Type.cast(:boolean, params["sensitive"])
834 ModerationLog.insert_log(%{
835 action: "status_update",
838 sensitive: sensitive,
839 visibility: params["visibility"]
843 |> put_view(StatusView)
844 |> render("show.json", %{activity: activity})
848 def status_delete(%{assigns: %{user: user}} = conn, %{"id" => id}) do
849 with {:ok, %Activity{}} <- CommonAPI.delete(id, user) do
850 ModerationLog.insert_log(%{
851 action: "status_delete",
860 def list_log(conn, params) do
861 {page, page_size} = page_params(params)
864 ModerationLog.get_all(%{
866 page_size: page_size,
867 start_date: params["start_date"],
868 end_date: params["end_date"],
869 user_id: params["user_id"],
870 search: params["search"]
874 |> put_view(ModerationLogView)
875 |> render("index.json", %{log: log})
878 def config_descriptions(conn, _params) do
880 |> Plug.Conn.put_resp_content_type("application/json")
881 |> Plug.Conn.send_resp(200, @descriptions_json)
884 def config_show(conn, %{"only_db" => true}) do
885 with :ok <- configurable_from_database(conn) do
886 configs = Pleroma.Repo.all(ConfigDB)
889 |> put_view(ConfigView)
890 |> render("index.json", %{configs: configs})
894 def config_show(conn, _params) do
895 with :ok <- configurable_from_database(conn) do
896 configs = ConfigDB.get_all_as_keyword()
899 Config.Holder.default_config()
900 |> ConfigDB.merge(configs)
901 |> Enum.map(fn {group, values} ->
902 Enum.map(values, fn {key, value} ->
904 if configs[group][key] do
905 ConfigDB.get_db_keys(configs[group][key], key)
908 db_value = configs[group][key]
911 if !is_nil(db_value) and Keyword.keyword?(db_value) and
912 ConfigDB.sub_key_full_update?(group, key, Keyword.keys(db_value)) do
913 ConfigDB.merge_group(group, key, value, db_value)
919 group: ConfigDB.convert(group),
920 key: ConfigDB.convert(key),
921 value: ConfigDB.convert(merged_value)
924 if db, do: Map.put(setting, :db, db), else: setting
929 json(conn, %{configs: merged, need_reboot: Restarter.Pleroma.need_reboot?()})
933 def config_update(conn, %{"configs" => configs}) do
934 with :ok <- configurable_from_database(conn) do
937 %{"group" => group, "key" => key, "delete" => true} = params ->
938 ConfigDB.delete(%{group: group, key: key, subkeys: params["subkeys"]})
940 %{"group" => group, "key" => key, "value" => value} ->
941 ConfigDB.update_or_create(%{group: group, key: key, value: value})
943 |> Enum.split_with(fn result -> elem(result, 0) == :error end)
947 |> Enum.map(fn {:ok, config} ->
948 Map.put(config, :db, ConfigDB.get_db_keys(config))
950 |> Enum.split_with(fn config ->
951 Ecto.get_meta(config, :state) == :deleted
954 Config.TransferTask.load_and_update_env(deleted, false)
956 if !Restarter.Pleroma.need_reboot?() do
957 changed_reboot_settings? =
959 |> Enum.any?(fn config ->
960 group = ConfigDB.from_string(config.group)
961 key = ConfigDB.from_string(config.key)
962 value = ConfigDB.from_binary(config.value)
963 Config.TransferTask.pleroma_need_restart?(group, key, value)
966 if changed_reboot_settings?, do: Restarter.Pleroma.need_reboot()
970 |> put_view(ConfigView)
971 |> render("index.json", %{configs: updated, need_reboot: Restarter.Pleroma.need_reboot?()})
975 def restart(conn, _params) do
976 with :ok <- configurable_from_database(conn) do
977 Restarter.Pleroma.restart(Config.get(:env), 50)
983 def need_reboot(conn, _params) do
984 json(conn, %{need_reboot: Restarter.Pleroma.need_reboot?()})
987 defp configurable_from_database(conn) do
988 if Config.get(:configurable_from_database) do
993 {:error, "To use this endpoint you need to enable configuration from database."}
998 def reload_emoji(conn, _params) do
999 Pleroma.Emoji.reload()
1004 def confirm_email(%{assigns: %{user: admin}} = conn, %{"nicknames" => nicknames}) do
1005 users = nicknames |> Enum.map(&User.get_cached_by_nickname/1)
1007 User.toggle_confirmation(users)
1009 ModerationLog.insert_log(%{
1012 action: "confirm_email"
1018 def resend_confirmation_email(%{assigns: %{user: admin}} = conn, %{"nicknames" => nicknames}) do
1019 users = nicknames |> Enum.map(&User.get_cached_by_nickname/1)
1021 User.try_send_confirmation_email(users)
1023 ModerationLog.insert_log(%{
1026 action: "resend_confirmation_email"
1032 def oauth_app_create(conn, params) do
1034 if params["name"] do
1035 Map.put(params, "client_name", params["name"])
1041 case App.create(params) do
1043 AppView.render("show.json", %{app: app, admin: true})
1045 {:error, changeset} ->
1046 App.errors(changeset)
1052 def oauth_app_update(conn, params) do
1054 if params["name"] do
1055 Map.put(params, "client_name", params["name"])
1060 with {:ok, app} <- App.update(params) do
1061 json(conn, AppView.render("show.json", %{app: app, admin: true}))
1063 {:error, changeset} ->
1064 json(conn, App.errors(changeset))
1067 json_response(conn, :bad_request, "")
1071 def oauth_app_list(conn, params) do
1072 {page, page_size} = page_params(params)
1075 client_name: params["name"],
1076 client_id: params["client_id"],
1078 page_size: page_size
1082 if Map.has_key?(params, "trusted") do
1083 Map.put(search_params, :trusted, params["trusted"])
1088 with {:ok, apps, count} <- App.search(search_params) do
1091 AppView.render("index.json",
1094 page_size: page_size,
1101 def oauth_app_delete(conn, params) do
1102 with {:ok, _app} <- App.destroy(params["id"]) do
1103 json_response(conn, :no_content, "")
1105 _ -> json_response(conn, :bad_request, "")
1109 def stats(conn, _) do
1110 count = Stats.get_status_visibility_count()
1113 |> json(%{"status_visibility" => count})
1116 defp errors(conn, {:error, :not_found}) do
1118 |> put_status(:not_found)
1119 |> json(dgettext("errors", "Not found"))
1122 defp errors(conn, {:error, reason}) do
1124 |> put_status(:bad_request)
1128 defp errors(conn, {:param_cast, _}) do
1130 |> put_status(:bad_request)
1131 |> json(dgettext("errors", "Invalid parameters"))
1134 defp errors(conn, _) do
1136 |> put_status(:internal_server_error)
1137 |> json(dgettext("errors", "Something went wrong"))
1140 defp page_params(params) do
1141 {get_page(params["page"]), get_page_size(params["page_size"])}
1144 defp get_page(page_string) when is_nil(page_string), do: 1
1146 defp get_page(page_string) do
1147 case Integer.parse(page_string) do
1153 defp get_page_size(page_size_string) when is_nil(page_size_string), do: @users_page_size
1155 defp get_page_size(page_size_string) do
1156 case Integer.parse(page_size_string) do
1157 {page_size, _} -> page_size
1158 :error -> @users_page_size