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(%{assigns: %{user: admin}} = conn, %{"nickname" => nickname}) do
137 user = User.get_cached_by_nickname(nickname)
140 ModerationLog.insert_log(%{
150 def user_delete(%{assigns: %{user: admin}} = conn, %{"nicknames" => nicknames}) do
151 users = nicknames |> Enum.map(&User.get_cached_by_nickname/1)
154 ModerationLog.insert_log(%{
164 def user_follow(%{assigns: %{user: admin}} = conn, %{
165 "follower" => follower_nick,
166 "followed" => followed_nick
168 with %User{} = follower <- User.get_cached_by_nickname(follower_nick),
169 %User{} = followed <- User.get_cached_by_nickname(followed_nick) do
170 User.follow(follower, followed)
172 ModerationLog.insert_log(%{
184 def user_unfollow(%{assigns: %{user: admin}} = conn, %{
185 "follower" => follower_nick,
186 "followed" => followed_nick
188 with %User{} = follower <- User.get_cached_by_nickname(follower_nick),
189 %User{} = followed <- User.get_cached_by_nickname(followed_nick) do
190 User.unfollow(follower, followed)
192 ModerationLog.insert_log(%{
204 def users_create(%{assigns: %{user: admin}} = conn, %{"users" => users}) do
206 Enum.map(users, fn %{"nickname" => nickname, "email" => email, "password" => password} ->
212 password_confirmation: password,
216 User.register_changeset(%User{}, user_data, need_confirmation: false)
218 |> Enum.reduce(Ecto.Multi.new(), fn changeset, multi ->
219 Ecto.Multi.insert(multi, Ecto.UUID.generate(), changeset)
222 case Pleroma.Repo.transaction(changesets) do
227 |> Enum.map(fn user ->
228 {:ok, user} = User.post_register_action(user)
232 |> Enum.map(&AccountView.render("created.json", %{user: &1}))
234 ModerationLog.insert_log(%{
236 subjects: Map.values(users),
243 {:error, id, changeset, _} ->
245 Enum.map(changesets.operations, fn
246 {current_id, {:changeset, _current_changeset, _}} when current_id == id ->
247 AccountView.render("create-error.json", %{changeset: changeset})
249 {_, {:changeset, current_changeset, _}} ->
250 AccountView.render("create-error.json", %{changeset: current_changeset})
254 |> put_status(:conflict)
259 def user_show(conn, %{"nickname" => nickname}) do
260 with %User{} = user <- User.get_cached_by_nickname_or_id(nickname) do
262 |> put_view(AccountView)
263 |> render("show.json", %{user: user})
265 _ -> {:error, :not_found}
269 def list_instance_statuses(conn, %{"instance" => instance} = params) do
270 with_reblogs = params["with_reblogs"] == "true" || params["with_reblogs"] == true
271 {page, page_size} = page_params(params)
274 ActivityPub.fetch_statuses(nil, %{
275 "instance" => instance,
276 "limit" => page_size,
277 "offset" => (page - 1) * page_size,
278 "exclude_reblogs" => !with_reblogs && "true"
282 |> put_view(Pleroma.Web.AdminAPI.StatusView)
283 |> render("index.json", %{activities: activities, as: :activity, skip_relationships: false})
286 def list_user_statuses(conn, %{"nickname" => nickname} = params) do
287 with_reblogs = params["with_reblogs"] == "true" || params["with_reblogs"] == true
288 godmode = params["godmode"] == "true" || params["godmode"] == true
290 with %User{} = user <- User.get_cached_by_nickname_or_id(nickname) do
291 {_, page_size} = page_params(params)
294 ActivityPub.fetch_user_activities(user, nil, %{
295 "limit" => page_size,
296 "godmode" => godmode,
297 "exclude_reblogs" => !with_reblogs && "true"
301 |> put_view(StatusView)
302 |> render("index.json", %{activities: activities, as: :activity, skip_relationships: false})
304 _ -> {:error, :not_found}
308 def user_toggle_activation(%{assigns: %{user: admin}} = conn, %{"nickname" => nickname}) do
309 user = User.get_cached_by_nickname(nickname)
311 {:ok, updated_user} = User.deactivate(user, !user.deactivated)
313 action = if user.deactivated, do: "activate", else: "deactivate"
315 ModerationLog.insert_log(%{
322 |> put_view(AccountView)
323 |> render("show.json", %{user: updated_user})
326 def user_activate(%{assigns: %{user: admin}} = conn, %{"nicknames" => nicknames}) do
327 users = Enum.map(nicknames, &User.get_cached_by_nickname/1)
328 {:ok, updated_users} = User.deactivate(users, false)
330 ModerationLog.insert_log(%{
337 |> put_view(AccountView)
338 |> render("index.json", %{users: Keyword.values(updated_users)})
341 def user_deactivate(%{assigns: %{user: admin}} = conn, %{"nicknames" => nicknames}) do
342 users = Enum.map(nicknames, &User.get_cached_by_nickname/1)
343 {:ok, updated_users} = User.deactivate(users, true)
345 ModerationLog.insert_log(%{
352 |> put_view(AccountView)
353 |> render("index.json", %{users: Keyword.values(updated_users)})
356 def tag_users(%{assigns: %{user: admin}} = conn, %{"nicknames" => nicknames, "tags" => tags}) do
357 with {:ok, _} <- User.tag(nicknames, tags) do
358 ModerationLog.insert_log(%{
360 nicknames: nicknames,
365 json_response(conn, :no_content, "")
369 def untag_users(%{assigns: %{user: admin}} = conn, %{"nicknames" => nicknames, "tags" => tags}) do
370 with {:ok, _} <- User.untag(nicknames, tags) do
371 ModerationLog.insert_log(%{
373 nicknames: nicknames,
378 json_response(conn, :no_content, "")
382 def list_users(conn, params) do
383 {page, page_size} = page_params(params)
384 filters = maybe_parse_filters(params["filters"])
387 query: params["query"],
389 page_size: page_size,
390 tags: params["tags"],
391 name: params["name"],
392 email: params["email"]
395 with {:ok, users, count} <- Search.user(Map.merge(search_params, filters)),
396 {:ok, users, count} <- filter_service_users(users, count),
400 AccountView.render("index.json",
408 defp filter_service_users(users, count) do
409 filtered_users = Enum.reject(users, &service_user?/1)
410 count = if Enum.any?(users, &service_user?/1), do: length(filtered_users), else: count
412 {:ok, filtered_users, count}
415 defp service_user?(user) do
416 String.match?(user.ap_id, ~r/.*\/relay$/) or
417 String.match?(user.ap_id, ~r/.*\/internal\/fetch$/)
420 @filters ~w(local external active deactivated is_admin is_moderator)
422 @spec maybe_parse_filters(String.t()) :: %{required(String.t()) => true} | %{}
423 defp maybe_parse_filters(filters) when is_nil(filters) or filters == "", do: %{}
425 defp maybe_parse_filters(filters) do
428 |> Enum.filter(&Enum.member?(@filters, &1))
429 |> Enum.map(&String.to_atom(&1))
430 |> Enum.into(%{}, &{&1, true})
433 def right_add_multiple(%{assigns: %{user: admin}} = conn, %{
434 "permission_group" => permission_group,
435 "nicknames" => nicknames
437 when permission_group in ["moderator", "admin"] do
438 update = %{:"is_#{permission_group}" => true}
440 users = nicknames |> Enum.map(&User.get_cached_by_nickname/1)
442 for u <- users, do: User.admin_api_update(u, update)
444 ModerationLog.insert_log(%{
448 permission: permission_group
454 def right_add_multiple(conn, _) do
455 render_error(conn, :not_found, "No such permission_group")
458 def right_add(%{assigns: %{user: admin}} = conn, %{
459 "permission_group" => permission_group,
460 "nickname" => nickname
462 when permission_group in ["moderator", "admin"] do
463 fields = %{:"is_#{permission_group}" => true}
467 |> User.get_cached_by_nickname()
468 |> User.admin_api_update(fields)
470 ModerationLog.insert_log(%{
474 permission: permission_group
480 def right_add(conn, _) do
481 render_error(conn, :not_found, "No such permission_group")
484 def right_get(conn, %{"nickname" => nickname}) do
485 user = User.get_cached_by_nickname(nickname)
489 is_moderator: user.is_moderator,
490 is_admin: user.is_admin
494 def right_delete_multiple(
495 %{assigns: %{user: %{nickname: admin_nickname} = admin}} = conn,
497 "permission_group" => permission_group,
498 "nicknames" => nicknames
501 when permission_group in ["moderator", "admin"] do
502 with false <- Enum.member?(nicknames, admin_nickname) do
503 update = %{:"is_#{permission_group}" => false}
505 users = nicknames |> Enum.map(&User.get_cached_by_nickname/1)
507 for u <- users, do: User.admin_api_update(u, update)
509 ModerationLog.insert_log(%{
513 permission: permission_group
518 _ -> render_error(conn, :forbidden, "You can't revoke your own admin/moderator status.")
522 def right_delete_multiple(conn, _) do
523 render_error(conn, :not_found, "No such permission_group")
527 %{assigns: %{user: admin}} = conn,
529 "permission_group" => permission_group,
530 "nickname" => nickname
533 when permission_group in ["moderator", "admin"] do
534 fields = %{:"is_#{permission_group}" => false}
538 |> User.get_cached_by_nickname()
539 |> User.admin_api_update(fields)
541 ModerationLog.insert_log(%{
545 permission: permission_group
551 def right_delete(%{assigns: %{user: %{nickname: nickname}}} = conn, %{"nickname" => nickname}) do
552 render_error(conn, :forbidden, "You can't revoke your own admin status.")
555 def relay_list(conn, _params) do
556 with {:ok, list} <- Relay.list() do
557 json(conn, %{relays: list})
565 def relay_follow(%{assigns: %{user: admin}} = conn, %{"relay_url" => target}) do
566 with {:ok, _message} <- Relay.follow(target) do
567 ModerationLog.insert_log(%{
568 action: "relay_follow",
582 def relay_unfollow(%{assigns: %{user: admin}} = conn, %{"relay_url" => target}) do
583 with {:ok, _message} <- Relay.unfollow(target) do
584 ModerationLog.insert_log(%{
585 action: "relay_unfollow",
599 @doc "Sends registration invite via email"
600 def email_invite(%{assigns: %{user: user}} = conn, %{"email" => email} = params) do
601 with {_, false} <- {:registrations_open, Config.get([:instance, :registrations_open])},
602 {_, true} <- {:invites_enabled, Config.get([:instance, :invites_enabled])},
603 {:ok, invite_token} <- UserInviteToken.create_invite(),
605 Pleroma.Emails.UserEmail.user_invitation_email(
611 {:ok, _} <- Pleroma.Emails.Mailer.deliver(email) do
612 json_response(conn, :no_content, "")
614 {:registrations_open, _} ->
617 {:error, "To send invites you need to set the `registrations_open` option to false."}
620 {:invites_enabled, _} ->
623 {:error, "To send invites you need to set the `invites_enabled` option to true."}
628 @doc "Create an account registration invite token"
629 def create_invite_token(conn, params) do
633 if params["max_use"],
634 do: Map.put(opts, :max_use, params["max_use"]),
638 if params["expires_at"],
639 do: Map.put(opts, :expires_at, params["expires_at"]),
642 {:ok, invite} = UserInviteToken.create_invite(opts)
644 json(conn, AccountView.render("invite.json", %{invite: invite}))
647 @doc "Get list of created invites"
648 def invites(conn, _params) do
649 invites = UserInviteToken.list_invites()
652 |> put_view(AccountView)
653 |> render("invites.json", %{invites: invites})
656 @doc "Revokes invite by token"
657 def revoke_invite(conn, %{"token" => token}) do
658 with {:ok, invite} <- UserInviteToken.find_by_token(token),
659 {:ok, updated_invite} = UserInviteToken.update_invite(invite, %{used: true}) do
661 |> put_view(AccountView)
662 |> render("invite.json", %{invite: updated_invite})
664 nil -> {:error, :not_found}
668 @doc "Get a password reset token (base64 string) for given nickname"
669 def get_password_reset(conn, %{"nickname" => nickname}) do
670 (%User{local: true} = user) = User.get_cached_by_nickname(nickname)
671 {:ok, token} = Pleroma.PasswordResetToken.create_token(user)
676 link: Router.Helpers.reset_password_url(Endpoint, :reset, token.token)
680 @doc "Force password reset for a given user"
681 def force_password_reset(%{assigns: %{user: admin}} = conn, %{"nicknames" => nicknames}) do
682 users = nicknames |> Enum.map(&User.get_cached_by_nickname/1)
684 Enum.each(users, &User.force_password_reset_async/1)
686 ModerationLog.insert_log(%{
689 action: "force_password_reset"
692 json_response(conn, :no_content, "")
695 @doc "Show a given user's credentials"
696 def show_user_credentials(%{assigns: %{user: admin}} = conn, %{"nickname" => nickname}) do
697 with %User{} = user <- User.get_cached_by_nickname_or_id(nickname) do
699 |> put_view(AccountView)
700 |> render("credentials.json", %{user: user, for: admin})
702 _ -> {:error, :not_found}
706 @doc "Updates a given user"
707 def update_user_credentials(
708 %{assigns: %{user: admin}} = conn,
709 %{"nickname" => nickname} = params
711 with {_, user} <- {:user, User.get_cached_by_nickname(nickname)},
713 User.update_as_admin(user, params) do
714 ModerationLog.insert_log(%{
717 action: "updated_users"
720 if params["password"] do
721 User.force_password_reset_async(user)
724 ModerationLog.insert_log(%{
727 action: "force_password_reset"
730 json(conn, %{status: "success"})
732 {:error, changeset} ->
733 {_, {error, _}} = Enum.at(changeset.errors, 0)
734 json(conn, %{error: "New password #{error}."})
737 json(conn, %{error: "Unable to change password."})
741 def list_reports(conn, params) do
742 {page, page_size} = page_params(params)
744 reports = Utils.get_reports(params, page, page_size)
747 |> put_view(ReportView)
748 |> render("index.json", %{reports: reports})
751 def report_show(conn, %{"id" => id}) do
752 with %Activity{} = report <- Activity.get_by_id(id) do
754 |> put_view(ReportView)
755 |> render("show.json", Report.extract_report_info(report))
757 _ -> {:error, :not_found}
761 def reports_update(%{assigns: %{user: admin}} = conn, %{"reports" => reports}) do
764 |> Enum.map(fn report ->
765 with {:ok, activity} <- CommonAPI.update_report_state(report["id"], report["state"]) do
766 ModerationLog.insert_log(%{
767 action: "report_update",
774 {:error, message} -> %{id: report["id"], error: message}
778 case Enum.any?(result, &Map.has_key?(&1, :error)) do
779 true -> json_response(conn, :bad_request, result)
780 false -> json_response(conn, :no_content, "")
784 def report_notes_create(%{assigns: %{user: user}} = conn, %{
788 with {:ok, _} <- ReportNote.create(user.id, report_id, content) do
789 ModerationLog.insert_log(%{
790 action: "report_note",
792 subject: Activity.get_by_id(report_id),
796 json_response(conn, :no_content, "")
798 _ -> json_response(conn, :bad_request, "")
802 def report_notes_delete(%{assigns: %{user: user}} = conn, %{
804 "report_id" => report_id
806 with {:ok, note} <- ReportNote.destroy(note_id) do
807 ModerationLog.insert_log(%{
808 action: "report_note_delete",
810 subject: Activity.get_by_id(report_id),
814 json_response(conn, :no_content, "")
816 _ -> json_response(conn, :bad_request, "")
820 def list_statuses(%{assigns: %{user: _admin}} = conn, params) do
821 godmode = params["godmode"] == "true" || params["godmode"] == true
822 local_only = params["local_only"] == "true" || params["local_only"] == true
823 with_reblogs = params["with_reblogs"] == "true" || params["with_reblogs"] == true
824 {page, page_size} = page_params(params)
827 ActivityPub.fetch_statuses(nil, %{
828 "godmode" => godmode,
829 "local_only" => local_only,
830 "limit" => page_size,
831 "offset" => (page - 1) * page_size,
832 "exclude_reblogs" => !with_reblogs && "true"
836 |> put_view(Pleroma.Web.AdminAPI.StatusView)
837 |> render("index.json", %{activities: activities, as: :activity, skip_relationships: false})
840 def status_update(%{assigns: %{user: admin}} = conn, %{"id" => id} = params) do
841 with {:ok, activity} <- CommonAPI.update_activity_scope(id, params) do
842 {:ok, sensitive} = Ecto.Type.cast(:boolean, params["sensitive"])
844 ModerationLog.insert_log(%{
845 action: "status_update",
848 sensitive: sensitive,
849 visibility: params["visibility"]
853 |> put_view(StatusView)
854 |> render("show.json", %{activity: activity})
858 def status_delete(%{assigns: %{user: user}} = conn, %{"id" => id}) do
859 with {:ok, %Activity{}} <- CommonAPI.delete(id, user) do
860 ModerationLog.insert_log(%{
861 action: "status_delete",
870 def list_log(conn, params) do
871 {page, page_size} = page_params(params)
874 ModerationLog.get_all(%{
876 page_size: page_size,
877 start_date: params["start_date"],
878 end_date: params["end_date"],
879 user_id: params["user_id"],
880 search: params["search"]
884 |> put_view(ModerationLogView)
885 |> render("index.json", %{log: log})
888 def config_descriptions(conn, _params) do
890 |> Plug.Conn.put_resp_content_type("application/json")
891 |> Plug.Conn.send_resp(200, @descriptions_json)
894 def config_show(conn, %{"only_db" => true}) do
895 with :ok <- configurable_from_database(conn) do
896 configs = Pleroma.Repo.all(ConfigDB)
899 |> put_view(ConfigView)
900 |> render("index.json", %{configs: configs})
904 def config_show(conn, _params) do
905 with :ok <- configurable_from_database(conn) do
906 configs = ConfigDB.get_all_as_keyword()
909 Config.Holder.default_config()
910 |> ConfigDB.merge(configs)
911 |> Enum.map(fn {group, values} ->
912 Enum.map(values, fn {key, value} ->
914 if configs[group][key] do
915 ConfigDB.get_db_keys(configs[group][key], key)
918 db_value = configs[group][key]
921 if !is_nil(db_value) and Keyword.keyword?(db_value) and
922 ConfigDB.sub_key_full_update?(group, key, Keyword.keys(db_value)) do
923 ConfigDB.merge_group(group, key, value, db_value)
929 group: ConfigDB.convert(group),
930 key: ConfigDB.convert(key),
931 value: ConfigDB.convert(merged_value)
934 if db, do: Map.put(setting, :db, db), else: setting
939 json(conn, %{configs: merged, need_reboot: Restarter.Pleroma.need_reboot?()})
943 def config_update(conn, %{"configs" => configs}) do
944 with :ok <- configurable_from_database(conn) do
947 %{"group" => group, "key" => key, "delete" => true} = params ->
948 ConfigDB.delete(%{group: group, key: key, subkeys: params["subkeys"]})
950 %{"group" => group, "key" => key, "value" => value} ->
951 ConfigDB.update_or_create(%{group: group, key: key, value: value})
953 |> Enum.split_with(fn result -> elem(result, 0) == :error end)
957 |> Enum.map(fn {:ok, config} ->
958 Map.put(config, :db, ConfigDB.get_db_keys(config))
960 |> Enum.split_with(fn config ->
961 Ecto.get_meta(config, :state) == :deleted
964 Config.TransferTask.load_and_update_env(deleted, false)
966 if !Restarter.Pleroma.need_reboot?() do
967 changed_reboot_settings? =
969 |> Enum.any?(fn config ->
970 group = ConfigDB.from_string(config.group)
971 key = ConfigDB.from_string(config.key)
972 value = ConfigDB.from_binary(config.value)
973 Config.TransferTask.pleroma_need_restart?(group, key, value)
976 if changed_reboot_settings?, do: Restarter.Pleroma.need_reboot()
980 |> put_view(ConfigView)
981 |> render("index.json", %{configs: updated, need_reboot: Restarter.Pleroma.need_reboot?()})
985 def restart(conn, _params) do
986 with :ok <- configurable_from_database(conn) do
987 Restarter.Pleroma.restart(Config.get(:env), 50)
993 def need_reboot(conn, _params) do
994 json(conn, %{need_reboot: Restarter.Pleroma.need_reboot?()})
997 defp configurable_from_database(conn) do
998 if Config.get(:configurable_from_database) do
1003 {:error, "To use this endpoint you need to enable configuration from database."}
1008 def reload_emoji(conn, _params) do
1009 Pleroma.Emoji.reload()
1014 def confirm_email(%{assigns: %{user: admin}} = conn, %{"nicknames" => nicknames}) do
1015 users = nicknames |> Enum.map(&User.get_cached_by_nickname/1)
1017 User.toggle_confirmation(users)
1019 ModerationLog.insert_log(%{
1022 action: "confirm_email"
1028 def resend_confirmation_email(%{assigns: %{user: admin}} = conn, %{"nicknames" => nicknames}) do
1029 users = nicknames |> Enum.map(&User.get_cached_by_nickname/1)
1031 User.try_send_confirmation_email(users)
1033 ModerationLog.insert_log(%{
1036 action: "resend_confirmation_email"
1042 def oauth_app_create(conn, params) do
1044 if params["name"] do
1045 Map.put(params, "client_name", params["name"])
1051 case App.create(params) do
1053 AppView.render("show.json", %{app: app, admin: true})
1055 {:error, changeset} ->
1056 App.errors(changeset)
1062 def oauth_app_update(conn, params) do
1064 if params["name"] do
1065 Map.put(params, "client_name", params["name"])
1070 with {:ok, app} <- App.update(params) do
1071 json(conn, AppView.render("show.json", %{app: app, admin: true}))
1073 {:error, changeset} ->
1074 json(conn, App.errors(changeset))
1077 json_response(conn, :bad_request, "")
1081 def oauth_app_list(conn, params) do
1082 {page, page_size} = page_params(params)
1085 client_name: params["name"],
1086 client_id: params["client_id"],
1088 page_size: page_size
1092 if Map.has_key?(params, "trusted") do
1093 Map.put(search_params, :trusted, params["trusted"])
1098 with {:ok, apps, count} <- App.search(search_params) do
1101 AppView.render("index.json",
1104 page_size: page_size,
1111 def oauth_app_delete(conn, params) do
1112 with {:ok, _app} <- App.destroy(params["id"]) do
1113 json_response(conn, :no_content, "")
1115 _ -> json_response(conn, :bad_request, "")
1119 def stats(conn, _) do
1120 count = Stats.get_status_visibility_count()
1123 |> json(%{"status_visibility" => count})
1126 defp errors(conn, {:error, :not_found}) do
1128 |> put_status(:not_found)
1129 |> json(dgettext("errors", "Not found"))
1132 defp errors(conn, {:error, reason}) do
1134 |> put_status(:bad_request)
1138 defp errors(conn, {:param_cast, _}) do
1140 |> put_status(:bad_request)
1141 |> json(dgettext("errors", "Invalid parameters"))
1144 defp errors(conn, _) do
1146 |> put_status(:internal_server_error)
1147 |> json(dgettext("errors", "Something went wrong"))
1150 defp page_params(params) do
1151 {get_page(params["page"]), get_page_size(params["page_size"])}
1154 defp get_page(page_string) when is_nil(page_string), do: 1
1156 defp get_page(page_string) do
1157 case Integer.parse(page_string) do
1163 defp get_page_size(page_size_string) when is_nil(page_size_string), do: @users_page_size
1165 defp get_page_size(page_size_string) do
1166 case Integer.parse(page_size_string) do
1167 {page_size, _} -> page_size
1168 :error -> @users_page_size