From c688d09478d7569fa047665ea21532816a78002f Mon Sep 17 00:00:00 2001 From: Phantasm Date: Sat, 18 Jul 2026 16:06:11 +0200 Subject: [PATCH] ConfigDB: Implement config update blacklist in AdminAPI --- .../controllers/config_controller.ex | 30 +++++++- .../controllers/config_controller_test.exs | 71 +++++++++++++++++++ 2 files changed, 100 insertions(+), 1 deletion(-) diff --git a/lib/pleroma/web/admin_api/controllers/config_controller.ex b/lib/pleroma/web/admin_api/controllers/config_controller.ex index 3eba03525..503fbc14d 100644 --- a/lib/pleroma/web/admin_api/controllers/config_controller.ex +++ b/lib/pleroma/web/admin_api/controllers/config_controller.ex @@ -71,7 +71,10 @@ defmodule Pleroma.Web.AdminAPI.ConfigController do end def descriptions(conn, _params) do - descriptions = Enum.filter(Pleroma.Docs.JSON.compiled_descriptions(), &whitelisted_config?/1) + descriptions = + Pleroma.Docs.JSON.compiled_descriptions() + |> Enum.filter(&whitelisted_config?/1) + |> Enum.reject(&blacklisted_config?/1) json(conn, translate_descriptions(descriptions)) end @@ -133,6 +136,7 @@ defmodule Pleroma.Web.AdminAPI.ConfigController do results = configs |> Enum.filter(&whitelisted_config?/1) + |> Enum.reject(&blacklisted_config?/1) |> Enum.map(fn %{group: group, key: key, delete: true} = params -> ConfigDB.delete(%{group: group, key: key, subkeys: params[:subkeys]}) @@ -197,4 +201,28 @@ defmodule Pleroma.Web.AdminAPI.ConfigController do defp whitelisted_config?(%{group: group} = config) do whitelisted_config?(group, config[:key]) end + + defp blacklisted_config?(":pleroma", ":database_config_blacklist"), do: true + + defp blacklisted_config?(group, key) do + if blacklisted_configs = Config.get(:database_config_blacklist) do + Enum.any?(blacklisted_configs, fn + {blacklisted_group} -> + group == inspect(blacklisted_group) + + {blacklisted_group, blacklisted_key} -> + group == inspect(blacklisted_group) and key == inspect(blacklisted_key) + end) + else + true + end + end + + defp blacklisted_config?(%{group: group, key: key}) do + blacklisted_config?(group, key) + end + + defp blacklisted_config?(%{group: group} = config) do + blacklisted_config?(group, config[:key]) + end end diff --git a/test/pleroma/web/admin_api/controllers/config_controller_test.exs b/test/pleroma/web/admin_api/controllers/config_controller_test.exs index e62d95fad..047662d39 100644 --- a/test/pleroma/web/admin_api/controllers/config_controller_test.exs +++ b/test/pleroma/web/admin_api/controllers/config_controller_test.exs @@ -1245,6 +1245,52 @@ defmodule Pleroma.Web.AdminAPI.ConfigControllerTest do refute ConfigDB.get_by_group_and_key(:pleroma, :database_config_whitelist) end + test "doesn't set keys in the blacklist", %{conn: conn} do + clear_config(:database_config_blacklist, [{:pleroma, :logger}, {:pleroma, :key2}, {:pleroma, Pleroma.Captcha.NotReal}, {:blacklisted_group}]) + + conn + |> put_req_header("content-type", "application/json") + |> post("/api/pleroma/admin/config", %{ + configs: [ + %{group: ":pleroma", key: ":logger", value: "logconf"}, + %{group: ":pleroma", key: ":key1", value: "value1"}, + %{group: ":pleroma", key: ":key2", value: "value2"}, + %{group: ":not_real", key: ":anything", value: "value3"}, + %{group: ":blacklisted_group", key: ":anything", value: "value4"} + ] + }) + + assert Application.get_env(:pleroma, :logger) == nil + assert Application.get_env(:pleroma, :key1) == "value1" + assert Application.get_env(:pleroma, :key2) == nil + assert Application.get_env(:pleroma, Pleroma.Captcha.NotReal) == nil + assert Application.get_env(:blacklisted_group, :anything) == nil + end + + test "doesn't allow updating the database_config_blacklist itself", %{conn: conn} do + original_blacklist = Pleroma.Config.get(:database_config_blacklist) + + refute ConfigDB.get_by_group_and_key(:pleroma, :database_config_blacklist) + + %{"configs" => configs} = + conn + |> put_req_header("content-type", "application/json") + |> post("/api/pleroma/admin/config", %{ + configs: [ + %{ + group: ":pleroma", + key: ":database_config_blacklist", + value: [%{"tuple" => [":pleroma", ":key1"]}] + } + ] + }) + |> json_response_and_validate_schema(200) + + assert configs == [] + assert Pleroma.Config.get(:database_config_blacklist) == original_blacklist + refute ConfigDB.get_by_group_and_key(:pleroma, :database_config_blacklist) + end + test "args for Pleroma.Upload.Filter.Mogrify with custom tuples", %{conn: conn} do assert conn |> put_req_header("content-type", "application/json") @@ -1515,5 +1561,30 @@ defmodule Pleroma.Web.AdminAPI.ConfigControllerTest do assert length(response) == length(Pleroma.Docs.JSON.compiled_descriptions()) end + + test "filters by database configuration blacklist and whitelist", %{conn: conn} do + clear_config(:database_config_whitelist, [{:pleroma, :instance}, {:pleroma, :activitypub}, {:pleroma, Pleroma.Upload}]) + clear_config(:database_config_blacklist, [ + {:pleroma, Pleroma.Upload}, + ]) + + children = + conn + |> get("/api/pleroma/admin/config/descriptions") + |> json_response_and_validate_schema(200) + + assert length(children) == 2 + + assert Enum.count(children, fn c -> c["group"] == ":pleroma" end) == 2 + + instance = Enum.find(children, fn c -> c["key"] == ":instance" end) + assert instance["children"] + + activitypub = Enum.find(children, fn c -> c["key"] == ":activitypub" end) + assert activitypub["children"] + + web_endpoint = Enum.find(children, fn c -> c["key"] == "Pleroma.Upload" end) + refute web_endpoint["children"] + end end end