diff options
author | lain <lain@soykaf.club> | 2020-08-28 12:17:19 +0000 |
---|---|---|
committer | lain <lain@soykaf.club> | 2020-08-28 12:17:19 +0000 |
commit | 73dd5bdb7dcdf804bdbabcf632671d4de5042ebc (patch) | |
tree | efcb0b8e68f86d067de98a23f40a24c7dab79d2f /lib/pleroma/web/admin_api/controllers/config_controller.ex | |
parent | f891e2b2f1d1daa122b9856e4b660be394d31e34 (diff) | |
parent | b141e35d641e733dffe7bd6a45a5bbcafe586c56 (diff) | |
download | pleroma-73dd5bdb7dcdf804bdbabcf632671d4de5042ebc.tar.gz |
Merge branch 'release/2.1.0' into 'stable'v2.1.0
Release/2.1.0
See merge request pleroma/pleroma!2927
Diffstat (limited to 'lib/pleroma/web/admin_api/controllers/config_controller.ex')
-rw-r--r-- | lib/pleroma/web/admin_api/controllers/config_controller.ex | 150 |
1 files changed, 150 insertions, 0 deletions
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..0df13007f --- /dev/null +++ b/lib/pleroma/web/admin_api/controllers/config_controller.ex @@ -0,0 +1,150 @@ +# 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 + + 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(Pleroma.Docs.JSON.compiled_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, + need_reboot: Restarter.Pleroma.need_reboot?() + }) + 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 + + %ConfigDB{ + group: group, + key: key, + value: merged_value + } + |> Pleroma.Maps.put_if_present(:db, db) + end) + end) + |> List.flatten() + + render(conn, "index.json", %{ + 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, %{key: key, value: value} = config} -> + Map.put(config, :db, ConfigDB.get_db_keys(value, key)) + end) + |> Enum.split_with(&(Ecto.get_meta(&1, :state) == :deleted)) + + Config.TransferTask.load_and_update_env(deleted, false) + + if not Restarter.Pleroma.need_reboot?() do + changed_reboot_settings? = + (updated ++ deleted) + |> Enum.any?(&Config.TransferTask.pleroma_need_restart?(&1.group, &1.key, &1.value)) + + 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 |