aboutsummaryrefslogtreecommitdiff
path: root/lib
diff options
context:
space:
mode:
authorlain <lain@soykaf.club>2020-06-04 13:00:13 +0000
committerlain <lain@soykaf.club>2020-06-04 13:00:13 +0000
commitf5cb1f3616e9cb9430038697532eb49161937dec (patch)
tree963b921fe475defce3a7924318ffeb5a965c0979 /lib
parentd6693a91028ab3ee7865f530f3ad2532542fc2d2 (diff)
parenta8132690bd80b83fc0057566d78a49eceefe0349 (diff)
downloadpleroma-f5cb1f3616e9cb9430038697532eb49161937dec.tar.gz
Merge branch 'openapi/admin/config' into 'develop'
Add OpenAPI spec to AdminAPI.ConfigController See merge request pleroma/pleroma!2606
Diffstat (limited to 'lib')
-rw-r--r--lib/pleroma/web/admin_api/controllers/admin_api_controller.ex127
-rw-r--r--lib/pleroma/web/admin_api/controllers/config_controller.ex153
-rw-r--r--lib/pleroma/web/api_spec/operations/admin/config_operation.ex142
-rw-r--r--lib/pleroma/web/router.ex6
4 files changed, 298 insertions, 130 deletions
diff --git a/lib/pleroma/web/admin_api/controllers/admin_api_controller.ex b/lib/pleroma/web/admin_api/controllers/admin_api_controller.ex
index 467d05375..bf24581cc 100644
--- a/lib/pleroma/web/admin_api/controllers/admin_api_controller.ex
+++ b/lib/pleroma/web/admin_api/controllers/admin_api_controller.ex
@@ -8,7 +8,6 @@ defmodule Pleroma.Web.AdminAPI.AdminAPIController do
import Pleroma.Web.ControllerHelper, only: [json_response: 3]
alias Pleroma.Config
- alias Pleroma.ConfigDB
alias Pleroma.MFA
alias Pleroma.ModerationLog
alias Pleroma.Plugs.OAuthScopesPlug
@@ -20,7 +19,6 @@ defmodule Pleroma.Web.AdminAPI.AdminAPIController do
alias Pleroma.Web.ActivityPub.Relay
alias Pleroma.Web.AdminAPI
alias Pleroma.Web.AdminAPI.AccountView
- alias Pleroma.Web.AdminAPI.ConfigView
alias Pleroma.Web.AdminAPI.ModerationLogView
alias Pleroma.Web.AdminAPI.Search
alias Pleroma.Web.Endpoint
@@ -28,7 +26,6 @@ defmodule Pleroma.Web.AdminAPI.AdminAPIController do
require Logger
- @descriptions Pleroma.Docs.JSON.compile()
@users_page_size 50
plug(
@@ -75,11 +72,9 @@ defmodule Pleroma.Web.AdminAPI.AdminAPIController do
OAuthScopesPlug,
%{scopes: ["read"], admin: true}
when action in [
- :config_show,
:list_log,
:stats,
:relay_list,
- :config_descriptions,
:need_reboot
]
)
@@ -89,7 +84,6 @@ defmodule Pleroma.Web.AdminAPI.AdminAPIController do
%{scopes: ["write"], admin: true}
when action in [
:restart,
- :config_update,
:resend_confirmation_email,
:confirm_email,
:reload_emoji
@@ -645,105 +639,6 @@ defmodule Pleroma.Web.AdminAPI.AdminAPIController do
|> render("index.json", %{log: log})
end
- def config_descriptions(conn, _params) do
- descriptions = Enum.filter(@descriptions, &whitelisted_config?/1)
-
- json(conn, descriptions)
- end
-
- def config_show(conn, %{"only_db" => true}) do
- with :ok <- configurable_from_database() do
- configs = Pleroma.Repo.all(ConfigDB)
-
- conn
- |> put_view(ConfigView)
- |> render("index.json", %{configs: configs})
- end
- end
-
- def config_show(conn, _params) do
- with :ok <- configurable_from_database() do
- configs = ConfigDB.get_all_as_keyword()
-
- merged =
- Config.Holder.default_config()
- |> ConfigDB.merge(configs)
- |> Enum.map(fn {group, values} ->
- Enum.map(values, fn {key, value} ->
- db =
- if configs[group][key] do
- ConfigDB.get_db_keys(configs[group][key], key)
- end
-
- db_value = configs[group][key]
-
- merged_value =
- if !is_nil(db_value) and Keyword.keyword?(db_value) and
- ConfigDB.sub_key_full_update?(group, key, Keyword.keys(db_value)) do
- ConfigDB.merge_group(group, key, value, db_value)
- else
- value
- end
-
- setting = %{
- group: ConfigDB.convert(group),
- key: ConfigDB.convert(key),
- value: ConfigDB.convert(merged_value)
- }
-
- if db, do: Map.put(setting, :db, db), else: setting
- end)
- end)
- |> List.flatten()
-
- json(conn, %{configs: merged, need_reboot: Restarter.Pleroma.need_reboot?()})
- end
- end
-
- def config_update(conn, %{"configs" => configs}) do
- with :ok <- configurable_from_database() do
- {_errors, results} =
- configs
- |> Enum.filter(&whitelisted_config?/1)
- |> Enum.map(fn
- %{"group" => group, "key" => key, "delete" => true} = params ->
- ConfigDB.delete(%{group: group, key: key, subkeys: params["subkeys"]})
-
- %{"group" => group, "key" => key, "value" => value} ->
- ConfigDB.update_or_create(%{group: group, key: key, value: value})
- end)
- |> Enum.split_with(fn result -> elem(result, 0) == :error end)
-
- {deleted, updated} =
- results
- |> Enum.map(fn {:ok, config} ->
- Map.put(config, :db, ConfigDB.get_db_keys(config))
- end)
- |> Enum.split_with(fn config ->
- Ecto.get_meta(config, :state) == :deleted
- end)
-
- Config.TransferTask.load_and_update_env(deleted, false)
-
- if !Restarter.Pleroma.need_reboot?() do
- changed_reboot_settings? =
- (updated ++ deleted)
- |> Enum.any?(fn config ->
- group = ConfigDB.from_string(config.group)
- key = ConfigDB.from_string(config.key)
- value = ConfigDB.from_binary(config.value)
- Config.TransferTask.pleroma_need_restart?(group, key, value)
- end)
-
- if changed_reboot_settings?, do: Restarter.Pleroma.need_reboot()
- end
-
- conn
- |> put_view(ConfigView)
- |> render("index.json", %{configs: updated, need_reboot: Restarter.Pleroma.need_reboot?()})
- end
- end
-
def restart(conn, _params) do
with :ok <- configurable_from_database() do
Restarter.Pleroma.restart(Config.get(:env), 50)
@@ -764,28 +659,6 @@ defmodule Pleroma.Web.AdminAPI.AdminAPIController do
end
end
- defp whitelisted_config?(group, key) do
- if whitelisted_configs = Config.get(:database_config_whitelist) do
- Enum.any?(whitelisted_configs, fn
- {whitelisted_group} ->
- group == inspect(whitelisted_group)
-
- {whitelisted_group, whitelisted_key} ->
- group == inspect(whitelisted_group) && key == inspect(whitelisted_key)
- end)
- else
- true
- end
- end
-
- defp whitelisted_config?(%{"group" => group, "key" => key}) do
- whitelisted_config?(group, key)
- end
-
- defp whitelisted_config?(%{:group => group} = config) do
- whitelisted_config?(group, config[:key])
- end
-
def reload_emoji(conn, _params) do
Pleroma.Emoji.reload()
diff --git a/lib/pleroma/web/admin_api/controllers/config_controller.ex b/lib/pleroma/web/admin_api/controllers/config_controller.ex
new file mode 100644
index 000000000..e221d9418
--- /dev/null
+++ b/lib/pleroma/web/admin_api/controllers/config_controller.ex
@@ -0,0 +1,153 @@
+# Pleroma: A lightweight social networking server
+# Copyright © 2017-2020 Pleroma Authors <https://pleroma.social/>
+# SPDX-License-Identifier: AGPL-3.0-only
+
+defmodule Pleroma.Web.AdminAPI.ConfigController do
+ use Pleroma.Web, :controller
+
+ alias Pleroma.Config
+ alias Pleroma.ConfigDB
+ alias Pleroma.Plugs.OAuthScopesPlug
+
+ @descriptions Pleroma.Docs.JSON.compile()
+
+ plug(Pleroma.Web.ApiSpec.CastAndValidate)
+ plug(OAuthScopesPlug, %{scopes: ["write"], admin: true} when action == :update)
+
+ plug(
+ OAuthScopesPlug,
+ %{scopes: ["read"], admin: true}
+ when action in [:show, :descriptions]
+ )
+
+ action_fallback(Pleroma.Web.AdminAPI.FallbackController)
+
+ defdelegate open_api_operation(action), to: Pleroma.Web.ApiSpec.Admin.ConfigOperation
+
+ def descriptions(conn, _params) do
+ descriptions = Enum.filter(@descriptions, &whitelisted_config?/1)
+
+ json(conn, descriptions)
+ end
+
+ def show(conn, %{only_db: true}) do
+ with :ok <- configurable_from_database() do
+ configs = Pleroma.Repo.all(ConfigDB)
+ render(conn, "index.json", %{configs: configs})
+ end
+ end
+
+ def show(conn, _params) do
+ with :ok <- configurable_from_database() do
+ configs = ConfigDB.get_all_as_keyword()
+
+ merged =
+ Config.Holder.default_config()
+ |> ConfigDB.merge(configs)
+ |> Enum.map(fn {group, values} ->
+ Enum.map(values, fn {key, value} ->
+ db =
+ if configs[group][key] do
+ ConfigDB.get_db_keys(configs[group][key], key)
+ end
+
+ db_value = configs[group][key]
+
+ merged_value =
+ if not is_nil(db_value) and Keyword.keyword?(db_value) and
+ ConfigDB.sub_key_full_update?(group, key, Keyword.keys(db_value)) do
+ ConfigDB.merge_group(group, key, value, db_value)
+ else
+ value
+ end
+
+ setting = %{
+ group: ConfigDB.convert(group),
+ key: ConfigDB.convert(key),
+ value: ConfigDB.convert(merged_value)
+ }
+
+ if db, do: Map.put(setting, :db, db), else: setting
+ end)
+ end)
+ |> List.flatten()
+
+ json(conn, %{configs: merged, need_reboot: Restarter.Pleroma.need_reboot?()})
+ end
+ end
+
+ def update(%{body_params: %{configs: configs}} = conn, _) do
+ with :ok <- configurable_from_database() do
+ results =
+ configs
+ |> Enum.filter(&whitelisted_config?/1)
+ |> Enum.map(fn
+ %{group: group, key: key, delete: true} = params ->
+ ConfigDB.delete(%{group: group, key: key, subkeys: params[:subkeys]})
+
+ %{group: group, key: key, value: value} ->
+ ConfigDB.update_or_create(%{group: group, key: key, value: value})
+ end)
+ |> Enum.reject(fn {result, _} -> result == :error end)
+
+ {deleted, updated} =
+ results
+ |> Enum.map(fn {:ok, config} ->
+ Map.put(config, :db, ConfigDB.get_db_keys(config))
+ end)
+ |> Enum.split_with(fn config ->
+ Ecto.get_meta(config, :state) == :deleted
+ end)
+
+ Config.TransferTask.load_and_update_env(deleted, false)
+
+ if not Restarter.Pleroma.need_reboot?() do
+ changed_reboot_settings? =
+ (updated ++ deleted)
+ |> Enum.any?(fn config ->
+ group = ConfigDB.from_string(config.group)
+ key = ConfigDB.from_string(config.key)
+ value = ConfigDB.from_binary(config.value)
+ Config.TransferTask.pleroma_need_restart?(group, key, value)
+ end)
+
+ if changed_reboot_settings?, do: Restarter.Pleroma.need_reboot()
+ end
+
+ render(conn, "index.json", %{
+ configs: updated,
+ need_reboot: Restarter.Pleroma.need_reboot?()
+ })
+ end
+ end
+
+ defp configurable_from_database do
+ if Config.get(:configurable_from_database) do
+ :ok
+ else
+ {:error, "To use this endpoint you need to enable configuration from database."}
+ end
+ end
+
+ defp whitelisted_config?(group, key) do
+ if whitelisted_configs = Config.get(:database_config_whitelist) do
+ Enum.any?(whitelisted_configs, fn
+ {whitelisted_group} ->
+ group == inspect(whitelisted_group)
+
+ {whitelisted_group, whitelisted_key} ->
+ group == inspect(whitelisted_group) && key == inspect(whitelisted_key)
+ end)
+ else
+ true
+ end
+ end
+
+ defp whitelisted_config?(%{group: group, key: key}) do
+ whitelisted_config?(group, key)
+ end
+
+ defp whitelisted_config?(%{group: group} = config) do
+ whitelisted_config?(group, config[:key])
+ end
+end
diff --git a/lib/pleroma/web/api_spec/operations/admin/config_operation.ex b/lib/pleroma/web/api_spec/operations/admin/config_operation.ex
new file mode 100644
index 000000000..7b38a2ef4
--- /dev/null
+++ b/lib/pleroma/web/api_spec/operations/admin/config_operation.ex
@@ -0,0 +1,142 @@
+# Pleroma: A lightweight social networking server
+# Copyright © 2017-2020 Pleroma Authors <https://pleroma.social/>
+# SPDX-License-Identifier: AGPL-3.0-only
+
+defmodule Pleroma.Web.ApiSpec.Admin.ConfigOperation do
+ alias OpenApiSpex.Operation
+ alias OpenApiSpex.Schema
+ alias Pleroma.Web.ApiSpec.Schemas.ApiError
+
+ import Pleroma.Web.ApiSpec.Helpers
+
+ def open_api_operation(action) do
+ operation = String.to_existing_atom("#{action}_operation")
+ apply(__MODULE__, operation, [])
+ end
+
+ def show_operation do
+ %Operation{
+ tags: ["Admin", "Config"],
+ summary: "Get list of merged default settings with saved in database",
+ operationId: "AdminAPI.ConfigController.show",
+ parameters: [
+ Operation.parameter(
+ :only_db,
+ :query,
+ %Schema{type: :boolean, default: false},
+ "Get only saved in database settings"
+ )
+ ],
+ security: [%{"oAuth" => ["read"]}],
+ responses: %{
+ 200 => Operation.response("Config", "application/json", config_response()),
+ 400 => Operation.response("Bad Request", "application/json", ApiError)
+ }
+ }
+ end
+
+ def update_operation do
+ %Operation{
+ tags: ["Admin", "Config"],
+ summary: "Update config settings",
+ operationId: "AdminAPI.ConfigController.update",
+ security: [%{"oAuth" => ["write"]}],
+ requestBody:
+ request_body("Parameters", %Schema{
+ type: :object,
+ properties: %{
+ configs: %Schema{
+ type: :array,
+ items: %Schema{
+ type: :object,
+ properties: %{
+ group: %Schema{type: :string},
+ key: %Schema{type: :string},
+ value: any(),
+ delete: %Schema{type: :boolean},
+ subkeys: %Schema{type: :array, items: %Schema{type: :string}}
+ }
+ }
+ }
+ }
+ }),
+ responses: %{
+ 200 => Operation.response("Config", "application/json", config_response()),
+ 400 => Operation.response("Bad Request", "application/json", ApiError)
+ }
+ }
+ end
+
+ def descriptions_operation do
+ %Operation{
+ tags: ["Admin", "Config"],
+ summary: "Get JSON with config descriptions.",
+ operationId: "AdminAPI.ConfigController.descriptions",
+ security: [%{"oAuth" => ["read"]}],
+ responses: %{
+ 200 =>
+ Operation.response("Config Descriptions", "application/json", %Schema{
+ type: :array,
+ items: %Schema{
+ type: :object,
+ properties: %{
+ group: %Schema{type: :string},
+ key: %Schema{type: :string},
+ type: %Schema{oneOf: [%Schema{type: :string}, %Schema{type: :array}]},
+ description: %Schema{type: :string},
+ children: %Schema{
+ type: :array,
+ items: %Schema{
+ type: :object,
+ properties: %{
+ key: %Schema{type: :string},
+ type: %Schema{oneOf: [%Schema{type: :string}, %Schema{type: :array}]},
+ description: %Schema{type: :string},
+ suggestions: %Schema{type: :array}
+ }
+ }
+ }
+ }
+ }
+ }),
+ 400 => Operation.response("Bad Request", "application/json", ApiError)
+ }
+ }
+ end
+
+ defp any do
+ %Schema{
+ oneOf: [
+ %Schema{type: :array},
+ %Schema{type: :object},
+ %Schema{type: :string},
+ %Schema{type: :integer},
+ %Schema{type: :boolean}
+ ]
+ }
+ end
+
+ defp config_response do
+ %Schema{
+ type: :object,
+ properties: %{
+ configs: %Schema{
+ type: :array,
+ items: %Schema{
+ type: :object,
+ properties: %{
+ group: %Schema{type: :string},
+ key: %Schema{type: :string},
+ value: any()
+ }
+ }
+ },
+ need_reboot: %Schema{
+ type: :boolean,
+ description:
+ "If `need_reboot` is `true`, instance must be restarted, so reboot time settings can take effect"
+ }
+ }
+ }
+ end
+end
diff --git a/lib/pleroma/web/router.ex b/lib/pleroma/web/router.ex
index 80ea28364..9922a0944 100644
--- a/lib/pleroma/web/router.ex
+++ b/lib/pleroma/web/router.ex
@@ -194,9 +194,9 @@ defmodule Pleroma.Web.Router do
delete("/statuses/:id", StatusController, :delete)
get("/statuses", StatusController, :index)
- get("/config", AdminAPIController, :config_show)
- post("/config", AdminAPIController, :config_update)
- get("/config/descriptions", AdminAPIController, :config_descriptions)
+ get("/config", ConfigController, :show)
+ post("/config", ConfigController, :update)
+ get("/config/descriptions", ConfigController, :descriptions)
get("/need_reboot", AdminAPIController, :need_reboot)
get("/restart", AdminAPIController, :restart)