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, :status_show]
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_show(conn, %{"id" => id}) do
841 with %Activity{} = activity <- Activity.get_by_id(id) do
843 |> put_view(StatusView)
844 |> render("show.json", %{activity: activity})
846 _ -> errors(conn, {:error, :not_found})
850 def status_update(%{assigns: %{user: admin}} = conn, %{"id" => id} = params) do
851 with {:ok, activity} <- CommonAPI.update_activity_scope(id, params) do
852 {:ok, sensitive} = Ecto.Type.cast(:boolean, params["sensitive"])
854 ModerationLog.insert_log(%{
855 action: "status_update",
858 sensitive: sensitive,
859 visibility: params["visibility"]
863 |> put_view(StatusView)
864 |> render("show.json", %{activity: activity})
868 def status_delete(%{assigns: %{user: user}} = conn, %{"id" => id}) do
869 with {:ok, %Activity{}} <- CommonAPI.delete(id, user) do
870 ModerationLog.insert_log(%{
871 action: "status_delete",
880 def list_log(conn, params) do
881 {page, page_size} = page_params(params)
884 ModerationLog.get_all(%{
886 page_size: page_size,
887 start_date: params["start_date"],
888 end_date: params["end_date"],
889 user_id: params["user_id"],
890 search: params["search"]
894 |> put_view(ModerationLogView)
895 |> render("index.json", %{log: log})
898 def config_descriptions(conn, _params) do
900 |> Plug.Conn.put_resp_content_type("application/json")
901 |> Plug.Conn.send_resp(200, @descriptions_json)
904 def config_show(conn, %{"only_db" => true}) do
905 with :ok <- configurable_from_database(conn) do
906 configs = Pleroma.Repo.all(ConfigDB)
909 |> put_view(ConfigView)
910 |> render("index.json", %{configs: configs})
914 def config_show(conn, _params) do
915 with :ok <- configurable_from_database(conn) do
916 configs = ConfigDB.get_all_as_keyword()
919 Config.Holder.default_config()
920 |> ConfigDB.merge(configs)
921 |> Enum.map(fn {group, values} ->
922 Enum.map(values, fn {key, value} ->
924 if configs[group][key] do
925 ConfigDB.get_db_keys(configs[group][key], key)
928 db_value = configs[group][key]
931 if !is_nil(db_value) and Keyword.keyword?(db_value) and
932 ConfigDB.sub_key_full_update?(group, key, Keyword.keys(db_value)) do
933 ConfigDB.merge_group(group, key, value, db_value)
939 group: ConfigDB.convert(group),
940 key: ConfigDB.convert(key),
941 value: ConfigDB.convert(merged_value)
944 if db, do: Map.put(setting, :db, db), else: setting
949 json(conn, %{configs: merged, need_reboot: Restarter.Pleroma.need_reboot?()})
953 def config_update(conn, %{"configs" => configs}) do
954 with :ok <- configurable_from_database(conn) do
957 %{"group" => group, "key" => key, "delete" => true} = params ->
958 ConfigDB.delete(%{group: group, key: key, subkeys: params["subkeys"]})
960 %{"group" => group, "key" => key, "value" => value} ->
961 ConfigDB.update_or_create(%{group: group, key: key, value: value})
963 |> Enum.split_with(fn result -> elem(result, 0) == :error end)
967 |> Enum.map(fn {:ok, config} ->
968 Map.put(config, :db, ConfigDB.get_db_keys(config))
970 |> Enum.split_with(fn config ->
971 Ecto.get_meta(config, :state) == :deleted
974 Config.TransferTask.load_and_update_env(deleted, false)
976 if !Restarter.Pleroma.need_reboot?() do
977 changed_reboot_settings? =
979 |> Enum.any?(fn config ->
980 group = ConfigDB.from_string(config.group)
981 key = ConfigDB.from_string(config.key)
982 value = ConfigDB.from_binary(config.value)
983 Config.TransferTask.pleroma_need_restart?(group, key, value)
986 if changed_reboot_settings?, do: Restarter.Pleroma.need_reboot()
990 |> put_view(ConfigView)
991 |> render("index.json", %{configs: updated, need_reboot: Restarter.Pleroma.need_reboot?()})
995 def restart(conn, _params) do
996 with :ok <- configurable_from_database(conn) do
997 Restarter.Pleroma.restart(Config.get(:env), 50)
1003 def need_reboot(conn, _params) do
1004 json(conn, %{need_reboot: Restarter.Pleroma.need_reboot?()})
1007 defp configurable_from_database(conn) do
1008 if Config.get(:configurable_from_database) do
1013 {:error, "To use this endpoint you need to enable configuration from database."}
1018 def reload_emoji(conn, _params) do
1019 Pleroma.Emoji.reload()
1024 def confirm_email(%{assigns: %{user: admin}} = conn, %{"nicknames" => nicknames}) do
1025 users = nicknames |> Enum.map(&User.get_cached_by_nickname/1)
1027 User.toggle_confirmation(users)
1029 ModerationLog.insert_log(%{
1032 action: "confirm_email"
1038 def resend_confirmation_email(%{assigns: %{user: admin}} = conn, %{"nicknames" => nicknames}) do
1039 users = nicknames |> Enum.map(&User.get_cached_by_nickname/1)
1041 User.try_send_confirmation_email(users)
1043 ModerationLog.insert_log(%{
1046 action: "resend_confirmation_email"
1052 def oauth_app_create(conn, params) do
1054 if params["name"] do
1055 Map.put(params, "client_name", params["name"])
1061 case App.create(params) do
1063 AppView.render("show.json", %{app: app, admin: true})
1065 {:error, changeset} ->
1066 App.errors(changeset)
1072 def oauth_app_update(conn, params) do
1074 if params["name"] do
1075 Map.put(params, "client_name", params["name"])
1080 with {:ok, app} <- App.update(params) do
1081 json(conn, AppView.render("show.json", %{app: app, admin: true}))
1083 {:error, changeset} ->
1084 json(conn, App.errors(changeset))
1087 json_response(conn, :bad_request, "")
1091 def oauth_app_list(conn, params) do
1092 {page, page_size} = page_params(params)
1095 client_name: params["name"],
1096 client_id: params["client_id"],
1098 page_size: page_size
1102 if Map.has_key?(params, "trusted") do
1103 Map.put(search_params, :trusted, params["trusted"])
1108 with {:ok, apps, count} <- App.search(search_params) do
1111 AppView.render("index.json",
1114 page_size: page_size,
1121 def oauth_app_delete(conn, params) do
1122 with {:ok, _app} <- App.destroy(params["id"]) do
1123 json_response(conn, :no_content, "")
1125 _ -> json_response(conn, :bad_request, "")
1129 def stats(conn, _) do
1130 count = Stats.get_status_visibility_count()
1133 |> json(%{"status_visibility" => count})
1136 defp errors(conn, {:error, :not_found}) do
1138 |> put_status(:not_found)
1139 |> json(dgettext("errors", "Not found"))
1142 defp errors(conn, {:error, reason}) do
1144 |> put_status(:bad_request)
1148 defp errors(conn, {:param_cast, _}) do
1150 |> put_status(:bad_request)
1151 |> json(dgettext("errors", "Invalid parameters"))
1154 defp errors(conn, _) do
1156 |> put_status(:internal_server_error)
1157 |> json(dgettext("errors", "Something went wrong"))
1160 defp page_params(params) do
1161 {get_page(params["page"]), get_page_size(params["page_size"])}
1164 defp get_page(page_string) when is_nil(page_string), do: 1
1166 defp get_page(page_string) do
1167 case Integer.parse(page_string) do
1173 defp get_page_size(page_size_string) when is_nil(page_size_string), do: @users_page_size
1175 defp get_page_size(page_size_string) do
1176 case Integer.parse(page_size_string) do
1177 {page_size, _} -> page_size
1178 :error -> @users_page_size