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
14 alias Pleroma.ModerationLog
15 alias Pleroma.Plugs.OAuthScopesPlug
16 alias Pleroma.ReportNote
19 alias Pleroma.UserInviteToken
20 alias Pleroma.Web.ActivityPub.ActivityPub
21 alias Pleroma.Web.ActivityPub.Builder
22 alias Pleroma.Web.ActivityPub.Pipeline
23 alias Pleroma.Web.ActivityPub.Relay
24 alias Pleroma.Web.ActivityPub.Utils
25 alias Pleroma.Web.AdminAPI.AccountView
26 alias Pleroma.Web.AdminAPI.ConfigView
27 alias Pleroma.Web.AdminAPI.ModerationLogView
28 alias Pleroma.Web.AdminAPI.Report
29 alias Pleroma.Web.AdminAPI.ReportView
30 alias Pleroma.Web.AdminAPI.Search
31 alias Pleroma.Web.CommonAPI
32 alias Pleroma.Web.Endpoint
33 alias Pleroma.Web.MastodonAPI.AppView
34 alias Pleroma.Web.MastodonAPI.StatusView
35 alias Pleroma.Web.OAuth.App
36 alias Pleroma.Web.Router
40 @descriptions_json Pleroma.Docs.JSON.compile()
45 %{scopes: ["read:accounts"], admin: true}
46 when action in [:list_users, :user_show, :right_get, :show_user_credentials]
51 %{scopes: ["write:accounts"], admin: true}
54 :force_password_reset,
57 :user_toggle_activation,
66 :right_delete_multiple,
67 :update_user_credentials
71 plug(OAuthScopesPlug, %{scopes: ["read:invites"], admin: true} when action == :invites)
75 %{scopes: ["write:invites"], admin: true}
76 when action in [:create_invite_token, :revoke_invite, :email_invite]
81 %{scopes: ["write:follows"], admin: true}
82 when action in [:user_follow, :user_unfollow, :relay_follow, :relay_unfollow]
87 %{scopes: ["read:reports"], admin: true}
88 when action in [:list_reports, :report_show]
93 %{scopes: ["write:reports"], admin: true}
94 when action in [:reports_update, :report_notes_create, :report_notes_delete]
99 %{scopes: ["read:statuses"], admin: true}
100 when action in [:list_statuses, :list_user_statuses, :list_instance_statuses, :status_show]
105 %{scopes: ["write:statuses"], admin: true}
106 when action in [:status_update, :status_delete]
111 %{scopes: ["read"], admin: true}
117 :config_descriptions,
124 %{scopes: ["write"], admin: true}
128 :resend_confirmation_email,
138 action_fallback(:errors)
140 def user_delete(conn, %{"nickname" => nickname}) do
141 user_delete(conn, %{"nicknames" => [nickname]})
144 def user_delete(%{assigns: %{user: admin}} = conn, %{"nicknames" => nicknames}) do
147 |> Enum.map(&User.get_cached_by_nickname/1)
150 |> Enum.each(fn user ->
151 {:ok, delete_data, _} = Builder.delete(admin, user.ap_id)
152 Pipeline.common_pipeline(delete_data, local: true)
155 ModerationLog.insert_log(%{
165 def user_follow(%{assigns: %{user: admin}} = conn, %{
166 "follower" => follower_nick,
167 "followed" => followed_nick
169 with %User{} = follower <- User.get_cached_by_nickname(follower_nick),
170 %User{} = followed <- User.get_cached_by_nickname(followed_nick) do
171 User.follow(follower, followed)
173 ModerationLog.insert_log(%{
185 def user_unfollow(%{assigns: %{user: admin}} = conn, %{
186 "follower" => follower_nick,
187 "followed" => followed_nick
189 with %User{} = follower <- User.get_cached_by_nickname(follower_nick),
190 %User{} = followed <- User.get_cached_by_nickname(followed_nick) do
191 User.unfollow(follower, followed)
193 ModerationLog.insert_log(%{
205 def users_create(%{assigns: %{user: admin}} = conn, %{"users" => users}) do
207 Enum.map(users, fn %{"nickname" => nickname, "email" => email, "password" => password} ->
213 password_confirmation: password,
217 User.register_changeset(%User{}, user_data, need_confirmation: false)
219 |> Enum.reduce(Ecto.Multi.new(), fn changeset, multi ->
220 Ecto.Multi.insert(multi, Ecto.UUID.generate(), changeset)
223 case Pleroma.Repo.transaction(changesets) do
228 |> Enum.map(fn user ->
229 {:ok, user} = User.post_register_action(user)
233 |> Enum.map(&AccountView.render("created.json", %{user: &1}))
235 ModerationLog.insert_log(%{
237 subjects: Map.values(users),
244 {:error, id, changeset, _} ->
246 Enum.map(changesets.operations, fn
247 {current_id, {:changeset, _current_changeset, _}} when current_id == id ->
248 AccountView.render("create-error.json", %{changeset: changeset})
250 {_, {:changeset, current_changeset, _}} ->
251 AccountView.render("create-error.json", %{changeset: current_changeset})
255 |> put_status(:conflict)
260 def user_show(conn, %{"nickname" => nickname}) do
261 with %User{} = user <- User.get_cached_by_nickname_or_id(nickname) do
263 |> put_view(AccountView)
264 |> render("show.json", %{user: user})
266 _ -> {:error, :not_found}
270 def list_instance_statuses(conn, %{"instance" => instance} = params) do
271 with_reblogs = params["with_reblogs"] == "true" || params["with_reblogs"] == true
272 {page, page_size} = page_params(params)
275 ActivityPub.fetch_statuses(nil, %{
276 "instance" => instance,
277 "limit" => page_size,
278 "offset" => (page - 1) * page_size,
279 "exclude_reblogs" => !with_reblogs && "true"
283 |> put_view(Pleroma.Web.AdminAPI.StatusView)
284 |> render("index.json", %{activities: activities, as: :activity, skip_relationships: false})
287 def list_user_statuses(conn, %{"nickname" => nickname} = params) do
288 with_reblogs = params["with_reblogs"] == "true" || params["with_reblogs"] == true
289 godmode = params["godmode"] == "true" || params["godmode"] == true
291 with %User{} = user <- User.get_cached_by_nickname_or_id(nickname) do
292 {_, page_size} = page_params(params)
295 ActivityPub.fetch_user_activities(user, nil, %{
296 "limit" => page_size,
297 "godmode" => godmode,
298 "exclude_reblogs" => !with_reblogs && "true"
302 |> put_view(StatusView)
303 |> render("index.json", %{activities: activities, as: :activity, skip_relationships: false})
305 _ -> {:error, :not_found}
309 def user_toggle_activation(%{assigns: %{user: admin}} = conn, %{"nickname" => nickname}) do
310 user = User.get_cached_by_nickname(nickname)
312 {:ok, updated_user} = User.deactivate(user, !user.deactivated)
314 action = if user.deactivated, do: "activate", else: "deactivate"
316 ModerationLog.insert_log(%{
323 |> put_view(AccountView)
324 |> render("show.json", %{user: updated_user})
327 def user_activate(%{assigns: %{user: admin}} = conn, %{"nicknames" => nicknames}) do
328 users = Enum.map(nicknames, &User.get_cached_by_nickname/1)
329 {:ok, updated_users} = User.deactivate(users, false)
331 ModerationLog.insert_log(%{
338 |> put_view(AccountView)
339 |> render("index.json", %{users: Keyword.values(updated_users)})
342 def user_deactivate(%{assigns: %{user: admin}} = conn, %{"nicknames" => nicknames}) do
343 users = Enum.map(nicknames, &User.get_cached_by_nickname/1)
344 {:ok, updated_users} = User.deactivate(users, true)
346 ModerationLog.insert_log(%{
353 |> put_view(AccountView)
354 |> render("index.json", %{users: Keyword.values(updated_users)})
357 def tag_users(%{assigns: %{user: admin}} = conn, %{"nicknames" => nicknames, "tags" => tags}) do
358 with {:ok, _} <- User.tag(nicknames, tags) do
359 ModerationLog.insert_log(%{
361 nicknames: nicknames,
366 json_response(conn, :no_content, "")
370 def untag_users(%{assigns: %{user: admin}} = conn, %{"nicknames" => nicknames, "tags" => tags}) do
371 with {:ok, _} <- User.untag(nicknames, tags) do
372 ModerationLog.insert_log(%{
374 nicknames: nicknames,
379 json_response(conn, :no_content, "")
383 def list_users(conn, params) do
384 {page, page_size} = page_params(params)
385 filters = maybe_parse_filters(params["filters"])
388 query: params["query"],
390 page_size: page_size,
391 tags: params["tags"],
392 name: params["name"],
393 email: params["email"]
396 with {:ok, users, count} <- Search.user(Map.merge(search_params, filters)) do
399 AccountView.render("index.json", users: users, count: count, page_size: page_size)
404 @filters ~w(local external active deactivated is_admin is_moderator)
406 @spec maybe_parse_filters(String.t()) :: %{required(String.t()) => true} | %{}
407 defp maybe_parse_filters(filters) when is_nil(filters) or filters == "", do: %{}
409 defp maybe_parse_filters(filters) do
412 |> Enum.filter(&Enum.member?(@filters, &1))
413 |> Enum.map(&String.to_atom(&1))
414 |> Enum.into(%{}, &{&1, true})
417 def right_add_multiple(%{assigns: %{user: admin}} = conn, %{
418 "permission_group" => permission_group,
419 "nicknames" => nicknames
421 when permission_group in ["moderator", "admin"] do
422 update = %{:"is_#{permission_group}" => true}
424 users = nicknames |> Enum.map(&User.get_cached_by_nickname/1)
426 for u <- users, do: User.admin_api_update(u, update)
428 ModerationLog.insert_log(%{
432 permission: permission_group
438 def right_add_multiple(conn, _) do
439 render_error(conn, :not_found, "No such permission_group")
442 def right_add(%{assigns: %{user: admin}} = conn, %{
443 "permission_group" => permission_group,
444 "nickname" => nickname
446 when permission_group in ["moderator", "admin"] do
447 fields = %{:"is_#{permission_group}" => true}
451 |> User.get_cached_by_nickname()
452 |> User.admin_api_update(fields)
454 ModerationLog.insert_log(%{
458 permission: permission_group
464 def right_add(conn, _) do
465 render_error(conn, :not_found, "No such permission_group")
468 def right_get(conn, %{"nickname" => nickname}) do
469 user = User.get_cached_by_nickname(nickname)
473 is_moderator: user.is_moderator,
474 is_admin: user.is_admin
478 def right_delete_multiple(
479 %{assigns: %{user: %{nickname: admin_nickname} = admin}} = conn,
481 "permission_group" => permission_group,
482 "nicknames" => nicknames
485 when permission_group in ["moderator", "admin"] do
486 with false <- Enum.member?(nicknames, admin_nickname) do
487 update = %{:"is_#{permission_group}" => false}
489 users = nicknames |> Enum.map(&User.get_cached_by_nickname/1)
491 for u <- users, do: User.admin_api_update(u, update)
493 ModerationLog.insert_log(%{
497 permission: permission_group
502 _ -> render_error(conn, :forbidden, "You can't revoke your own admin/moderator status.")
506 def right_delete_multiple(conn, _) do
507 render_error(conn, :not_found, "No such permission_group")
511 %{assigns: %{user: admin}} = conn,
513 "permission_group" => permission_group,
514 "nickname" => nickname
517 when permission_group in ["moderator", "admin"] do
518 fields = %{:"is_#{permission_group}" => false}
522 |> User.get_cached_by_nickname()
523 |> User.admin_api_update(fields)
525 ModerationLog.insert_log(%{
529 permission: permission_group
535 def right_delete(%{assigns: %{user: %{nickname: nickname}}} = conn, %{"nickname" => nickname}) do
536 render_error(conn, :forbidden, "You can't revoke your own admin status.")
539 def relay_list(conn, _params) do
540 with {:ok, list} <- Relay.list() do
541 json(conn, %{relays: list})
549 def relay_follow(%{assigns: %{user: admin}} = conn, %{"relay_url" => target}) do
550 with {:ok, _message} <- Relay.follow(target) do
551 ModerationLog.insert_log(%{
552 action: "relay_follow",
566 def relay_unfollow(%{assigns: %{user: admin}} = conn, %{"relay_url" => target}) do
567 with {:ok, _message} <- Relay.unfollow(target) do
568 ModerationLog.insert_log(%{
569 action: "relay_unfollow",
583 @doc "Sends registration invite via email"
584 def email_invite(%{assigns: %{user: user}} = conn, %{"email" => email} = params) do
585 with {_, false} <- {:registrations_open, Config.get([:instance, :registrations_open])},
586 {_, true} <- {:invites_enabled, Config.get([:instance, :invites_enabled])},
587 {:ok, invite_token} <- UserInviteToken.create_invite(),
589 Pleroma.Emails.UserEmail.user_invitation_email(
595 {:ok, _} <- Pleroma.Emails.Mailer.deliver(email) do
596 json_response(conn, :no_content, "")
598 {:registrations_open, _} ->
601 {:error, "To send invites you need to set the `registrations_open` option to false."}
604 {:invites_enabled, _} ->
607 {:error, "To send invites you need to set the `invites_enabled` option to true."}
612 @doc "Create an account registration invite token"
613 def create_invite_token(conn, params) do
617 if params["max_use"],
618 do: Map.put(opts, :max_use, params["max_use"]),
622 if params["expires_at"],
623 do: Map.put(opts, :expires_at, params["expires_at"]),
626 {:ok, invite} = UserInviteToken.create_invite(opts)
628 json(conn, AccountView.render("invite.json", %{invite: invite}))
631 @doc "Get list of created invites"
632 def invites(conn, _params) do
633 invites = UserInviteToken.list_invites()
636 |> put_view(AccountView)
637 |> render("invites.json", %{invites: invites})
640 @doc "Revokes invite by token"
641 def revoke_invite(conn, %{"token" => token}) do
642 with {:ok, invite} <- UserInviteToken.find_by_token(token),
643 {:ok, updated_invite} = UserInviteToken.update_invite(invite, %{used: true}) do
645 |> put_view(AccountView)
646 |> render("invite.json", %{invite: updated_invite})
648 nil -> {:error, :not_found}
652 @doc "Get a password reset token (base64 string) for given nickname"
653 def get_password_reset(conn, %{"nickname" => nickname}) do
654 (%User{local: true} = user) = User.get_cached_by_nickname(nickname)
655 {:ok, token} = Pleroma.PasswordResetToken.create_token(user)
660 link: Router.Helpers.reset_password_url(Endpoint, :reset, token.token)
664 @doc "Force password reset for a given user"
665 def force_password_reset(%{assigns: %{user: admin}} = conn, %{"nicknames" => nicknames}) do
666 users = nicknames |> Enum.map(&User.get_cached_by_nickname/1)
668 Enum.each(users, &User.force_password_reset_async/1)
670 ModerationLog.insert_log(%{
673 action: "force_password_reset"
676 json_response(conn, :no_content, "")
679 @doc "Disable mfa for user's account."
680 def disable_mfa(conn, %{"nickname" => nickname}) do
681 case User.get_by_nickname(nickname) do
691 @doc "Show a given user's credentials"
692 def show_user_credentials(%{assigns: %{user: admin}} = conn, %{"nickname" => nickname}) do
693 with %User{} = user <- User.get_cached_by_nickname_or_id(nickname) do
695 |> put_view(AccountView)
696 |> render("credentials.json", %{user: user, for: admin})
698 _ -> {:error, :not_found}
702 @doc "Updates a given user"
703 def update_user_credentials(
704 %{assigns: %{user: admin}} = conn,
705 %{"nickname" => nickname} = params
707 with {_, user} <- {:user, User.get_cached_by_nickname(nickname)},
709 User.update_as_admin(user, params) do
710 ModerationLog.insert_log(%{
713 action: "updated_users"
716 if params["password"] do
717 User.force_password_reset_async(user)
720 ModerationLog.insert_log(%{
723 action: "force_password_reset"
726 json(conn, %{status: "success"})
728 {:error, changeset} ->
729 {_, {error, _}} = Enum.at(changeset.errors, 0)
730 json(conn, %{error: "New password #{error}."})
733 json(conn, %{error: "Unable to change password."})
737 def list_reports(conn, params) do
738 {page, page_size} = page_params(params)
740 reports = Utils.get_reports(params, page, page_size)
743 |> put_view(ReportView)
744 |> render("index.json", %{reports: reports})
747 def report_show(conn, %{"id" => id}) do
748 with %Activity{} = report <- Activity.get_by_id(id) do
750 |> put_view(ReportView)
751 |> render("show.json", Report.extract_report_info(report))
753 _ -> {:error, :not_found}
757 def reports_update(%{assigns: %{user: admin}} = conn, %{"reports" => reports}) do
760 |> Enum.map(fn report ->
761 with {:ok, activity} <- CommonAPI.update_report_state(report["id"], report["state"]) do
762 ModerationLog.insert_log(%{
763 action: "report_update",
770 {:error, message} -> %{id: report["id"], error: message}
774 case Enum.any?(result, &Map.has_key?(&1, :error)) do
775 true -> json_response(conn, :bad_request, result)
776 false -> json_response(conn, :no_content, "")
780 def report_notes_create(%{assigns: %{user: user}} = conn, %{
784 with {:ok, _} <- ReportNote.create(user.id, report_id, content) do
785 ModerationLog.insert_log(%{
786 action: "report_note",
788 subject: Activity.get_by_id(report_id),
792 json_response(conn, :no_content, "")
794 _ -> json_response(conn, :bad_request, "")
798 def report_notes_delete(%{assigns: %{user: user}} = conn, %{
800 "report_id" => report_id
802 with {:ok, note} <- ReportNote.destroy(note_id) do
803 ModerationLog.insert_log(%{
804 action: "report_note_delete",
806 subject: Activity.get_by_id(report_id),
810 json_response(conn, :no_content, "")
812 _ -> json_response(conn, :bad_request, "")
816 def list_statuses(%{assigns: %{user: _admin}} = conn, params) do
817 godmode = params["godmode"] == "true" || params["godmode"] == true
818 local_only = params["local_only"] == "true" || params["local_only"] == true
819 with_reblogs = params["with_reblogs"] == "true" || params["with_reblogs"] == true
820 {page, page_size} = page_params(params)
823 ActivityPub.fetch_statuses(nil, %{
824 "godmode" => godmode,
825 "local_only" => local_only,
826 "limit" => page_size,
827 "offset" => (page - 1) * page_size,
828 "exclude_reblogs" => !with_reblogs && "true"
832 |> put_view(Pleroma.Web.AdminAPI.StatusView)
833 |> render("index.json", %{activities: activities, as: :activity, skip_relationships: false})
836 def status_show(conn, %{"id" => id}) do
837 with %Activity{} = activity <- Activity.get_by_id(id) do
839 |> put_view(StatusView)
840 |> render("show.json", %{activity: activity})
842 _ -> errors(conn, {:error, :not_found})
846 def status_update(%{assigns: %{user: admin}} = conn, %{"id" => id} = params) do
849 |> Map.take(["sensitive", "visibility"])
850 |> Map.new(fn {key, value} -> {String.to_existing_atom(key), value} end)
852 with {:ok, activity} <- CommonAPI.update_activity_scope(id, params) do
853 {:ok, sensitive} = Ecto.Type.cast(:boolean, params[:sensitive])
855 ModerationLog.insert_log(%{
856 action: "status_update",
859 sensitive: sensitive,
860 visibility: params[:visibility]
864 |> put_view(StatusView)
865 |> render("show.json", %{activity: activity})
869 def status_delete(%{assigns: %{user: user}} = conn, %{"id" => id}) do
870 with {:ok, %Activity{}} <- CommonAPI.delete(id, user) do
871 ModerationLog.insert_log(%{
872 action: "status_delete",
881 def list_log(conn, params) do
882 {page, page_size} = page_params(params)
885 ModerationLog.get_all(%{
887 page_size: page_size,
888 start_date: params["start_date"],
889 end_date: params["end_date"],
890 user_id: params["user_id"],
891 search: params["search"]
895 |> put_view(ModerationLogView)
896 |> render("index.json", %{log: log})
899 def config_descriptions(conn, _params) do
901 |> Plug.Conn.put_resp_content_type("application/json")
902 |> Plug.Conn.send_resp(200, @descriptions_json)
905 def config_show(conn, %{"only_db" => true}) do
906 with :ok <- configurable_from_database(conn) do
907 configs = Pleroma.Repo.all(ConfigDB)
910 |> put_view(ConfigView)
911 |> render("index.json", %{configs: configs})
915 def config_show(conn, _params) do
916 with :ok <- configurable_from_database(conn) do
917 configs = ConfigDB.get_all_as_keyword()
920 Config.Holder.default_config()
921 |> ConfigDB.merge(configs)
922 |> Enum.map(fn {group, values} ->
923 Enum.map(values, fn {key, value} ->
925 if configs[group][key] do
926 ConfigDB.get_db_keys(configs[group][key], key)
929 db_value = configs[group][key]
932 if !is_nil(db_value) and Keyword.keyword?(db_value) and
933 ConfigDB.sub_key_full_update?(group, key, Keyword.keys(db_value)) do
934 ConfigDB.merge_group(group, key, value, db_value)
940 group: ConfigDB.convert(group),
941 key: ConfigDB.convert(key),
942 value: ConfigDB.convert(merged_value)
945 if db, do: Map.put(setting, :db, db), else: setting
950 json(conn, %{configs: merged, need_reboot: Restarter.Pleroma.need_reboot?()})
954 def config_update(conn, %{"configs" => configs}) do
955 with :ok <- configurable_from_database(conn) do
958 %{"group" => group, "key" => key, "delete" => true} = params ->
959 ConfigDB.delete(%{group: group, key: key, subkeys: params["subkeys"]})
961 %{"group" => group, "key" => key, "value" => value} ->
962 ConfigDB.update_or_create(%{group: group, key: key, value: value})
964 |> Enum.split_with(fn result -> elem(result, 0) == :error end)
968 |> Enum.map(fn {:ok, config} ->
969 Map.put(config, :db, ConfigDB.get_db_keys(config))
971 |> Enum.split_with(fn config ->
972 Ecto.get_meta(config, :state) == :deleted
975 Config.TransferTask.load_and_update_env(deleted, false)
977 if !Restarter.Pleroma.need_reboot?() do
978 changed_reboot_settings? =
980 |> Enum.any?(fn config ->
981 group = ConfigDB.from_string(config.group)
982 key = ConfigDB.from_string(config.key)
983 value = ConfigDB.from_binary(config.value)
984 Config.TransferTask.pleroma_need_restart?(group, key, value)
987 if changed_reboot_settings?, do: Restarter.Pleroma.need_reboot()
991 |> put_view(ConfigView)
992 |> render("index.json", %{configs: updated, need_reboot: Restarter.Pleroma.need_reboot?()})
996 def restart(conn, _params) do
997 with :ok <- configurable_from_database(conn) do
998 Restarter.Pleroma.restart(Config.get(:env), 50)
1004 def need_reboot(conn, _params) do
1005 json(conn, %{need_reboot: Restarter.Pleroma.need_reboot?()})
1008 defp configurable_from_database(conn) do
1009 if Config.get(:configurable_from_database) do
1014 {:error, "To use this endpoint you need to enable configuration from database."}
1019 def reload_emoji(conn, _params) do
1020 Pleroma.Emoji.reload()
1025 def confirm_email(%{assigns: %{user: admin}} = conn, %{"nicknames" => nicknames}) do
1026 users = nicknames |> Enum.map(&User.get_cached_by_nickname/1)
1028 User.toggle_confirmation(users)
1030 ModerationLog.insert_log(%{
1033 action: "confirm_email"
1039 def resend_confirmation_email(%{assigns: %{user: admin}} = conn, %{"nicknames" => nicknames}) do
1040 users = nicknames |> Enum.map(&User.get_cached_by_nickname/1)
1042 User.try_send_confirmation_email(users)
1044 ModerationLog.insert_log(%{
1047 action: "resend_confirmation_email"
1053 def oauth_app_create(conn, params) do
1055 if params["name"] do
1056 Map.put(params, "client_name", params["name"])
1062 case App.create(params) do
1064 AppView.render("show.json", %{app: app, admin: true})
1066 {:error, changeset} ->
1067 App.errors(changeset)
1073 def oauth_app_update(conn, params) do
1075 if params["name"] do
1076 Map.put(params, "client_name", params["name"])
1081 with {:ok, app} <- App.update(params) do
1082 json(conn, AppView.render("show.json", %{app: app, admin: true}))
1084 {:error, changeset} ->
1085 json(conn, App.errors(changeset))
1088 json_response(conn, :bad_request, "")
1092 def oauth_app_list(conn, params) do
1093 {page, page_size} = page_params(params)
1096 client_name: params["name"],
1097 client_id: params["client_id"],
1099 page_size: page_size
1103 if Map.has_key?(params, "trusted") do
1104 Map.put(search_params, :trusted, params["trusted"])
1109 with {:ok, apps, count} <- App.search(search_params) do
1112 AppView.render("index.json",
1115 page_size: page_size,
1122 def oauth_app_delete(conn, params) do
1123 with {:ok, _app} <- App.destroy(params["id"]) do
1124 json_response(conn, :no_content, "")
1126 _ -> json_response(conn, :bad_request, "")
1130 def stats(conn, params) do
1131 counters = Stats.get_status_visibility_count(params["instance"])
1133 json(conn, %{"status_visibility" => counters})
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