Add exclusion reasons, mix task to check enabled keys

This commit is contained in:
FloatingGhost 2023-08-15 13:59:15 +01:00
parent d63bb3f6b1
commit 6f55ca14f2
4 changed files with 75 additions and 34 deletions

View file

@ -423,6 +423,7 @@ config :pleroma, :config_description, [
label: "URI Schemes",
type: :group,
description: "URI schemes related settings",
db_exclusion_reasons: "Does not make sense to configure dynamically",
children: [
%{
key: :valid_schemes,
@ -1638,6 +1639,7 @@ config :pleroma, :config_description, [
key: Pleroma.Web.MediaProxy.Invalidation.Script,
type: :group,
description: "Invalidation script settings",
db_exclusion_reason: "Provides an arbitrary execution path",
children: [
%{
key: :script_path,
@ -1751,6 +1753,7 @@ config :pleroma, :config_description, [
%{
group: :web_push_encryption,
key: :vapid_details,
db_exclusion_reason: "Webserver secret keys",
label: "Vapid Details",
type: :group,
description:
@ -1822,19 +1825,13 @@ config :pleroma, :config_description, [
%{
group: :pleroma,
label: "Pleroma Admin Token",
type: :group,
description:
"Allows setting a token that can be used to authenticate requests with admin privileges without a normal user account token. Append the `admin_token` parameter to requests to utilize it. (Please reconsider using HTTP Basic Auth or OAuth-based authentication if possible)",
children: [
%{
key: :admin_token,
type: :string,
description: "Admin token",
suggestions: [
"Please use a high entropy string or UUID"
]
}
]
],
db_exclusion_reason: "Can provide passwordless admin access"
},
%{
group: :pleroma,
@ -2178,6 +2175,7 @@ config :pleroma, :config_description, [
label: "Pleroma Authenticator",
type: :group,
description: "Authenticator",
db_exclusion_reason: "Should be provided at boot-time",
children: [
%{
key: Pleroma.Web.Auth.Authenticator,
@ -2191,6 +2189,7 @@ config :pleroma, :config_description, [
key: :ldap,
label: "LDAP",
type: :group,
db_exclusion_reason: "Provides access to another service",
description:
"Use LDAP for user authentication. When a user logs in to the Pleroma instance, the name and password" <>
" will be verified by trying to authenticate (bind) to a LDAP server." <>
@ -2590,6 +2589,7 @@ config :pleroma, :config_description, [
label: "Mime Types",
type: :group,
description: "Mime Types settings",
db_exclusion_reason: "Should be provided at compile-time",
children: [
%{
key: :types,
@ -2796,6 +2796,7 @@ config :pleroma, :config_description, [
group: :cors_plug,
label: "CORS plug config",
type: :group,
db_exclusion_reason: "Should be provided at compile-time",
children: [
%{
key: :max_age,
@ -2953,6 +2954,7 @@ config :pleroma, :config_description, [
key: :modules,
type: :group,
description: "Custom Runtime Modules",
db_exclusion_reason: "Allows for custom elixir execution",
children: [
%{
key: :runtime_dir,
@ -3089,6 +3091,7 @@ config :pleroma, :config_description, [
group: :ex_aws,
key: :s3,
type: :group,
db_exclusion_reason: "Provides access to another service",
descriptions: "S3 service related settings",
children: [
%{
@ -3468,6 +3471,7 @@ config :pleroma, :config_description, [
key: :argos_translate,
type: :group,
description: "ArgosTranslate Settings.",
db_exclusion_reason: "Excluded for being able to set arbitrary paths to executables",
children: [
%{
key: :command_argos_translate,

View file

@ -10,6 +10,7 @@ defmodule Mix.Tasks.Pleroma.Config do
alias Pleroma.ConfigDB
alias Pleroma.Repo
alias Pleroma.Config.ConfigurableFromDatabase
@shortdoc "Manages the location of the config"
@moduledoc File.read!("docs/docs/administration/CLI_tasks/config.md")
@ -244,6 +245,28 @@ defmodule Mix.Tasks.Pleroma.Config do
end
end
# Primarily a developer tool to check nothing was missed from
# db configwhitelist
def run(["check-allowed"]) do
start_pleroma()
Pleroma.Docs.JSON.compile()
raw = Pleroma.Docs.JSON.compiled_descriptions()
whitelisted = Enum.filter(raw, &ConfigurableFromDatabase.whitelisted_config?/1)
raw_map = MapSet.new(raw)
whitelisted_map = MapSet.new(whitelisted)
IO.puts("Config keys defined in description.exs but not listed as explicitly allowed in the db")
IO.puts(" Please check that standard admins should not need to touch the listed settings whilst the server is live.")
IO.puts(" !! Please remember that admins are not neccesarily sysadmins nor are they immune to oauth/password leakage.")
IO.puts("-------------")
MapSet.difference(raw_map, whitelisted_map)
|> Enum.each(fn map ->
IO.puts("#{map[:group]}, #{map[:key]} (#{map[:label]})")
IO.puts(map[:db_exclusion_reason] || "No exclusion reason set")
IO.puts("++")
end)
end
@spec migrate_to_db(Path.t() | nil) :: any()
def migrate_to_db(file_path \\ nil) do
with :ok <- Pleroma.Config.DeprecationWarnings.warn() do

View file

@ -1,4 +1,6 @@
defmodule Pleroma.Config.ConfigurableFromDatabase do
alias Pleroma.Config
# Basically it's silly to let this be configurable
# set a list of things that we can set in the database
# this is mostly our stuff, with some extra in there
@ -9,6 +11,7 @@ defmodule Pleroma.Config.ConfigurableFromDatabase do
{:pleroma, Pleroma.Upload},
{:pleroma, Pleroma.Uploaders.Local},
{:pleroma, Pleroma.Uploaders.S3},
{:pleroma, :auth},
{:pleroma, :emoji},
{:pleroma, :http},
{:pleroma, :instance},
@ -70,9 +73,34 @@ defmodule Pleroma.Config.ConfigurableFromDatabase do
{:pleroma, Pleroma.Search.Elasticsearch.Cluster},
{:pleroma, :translator},
{:pleroma, :deepl},
{:pleroma, :libre_translate}
{:pleroma, :libre_translate},
# But not argostranslate, because executables!
{:pleroma, Pleroma.Upload.Filter.AnonymizeFilename},
{:pleroma, Pleroma.Upload.Filter.Mogrify},
{:pleroma, Pleroma.Workers.PurgeExpiredActivity},
{:pleroma, :rate_limit}
]
def allowed_groups, do: @allowed_groups
def enabled, do: Config.get(:configurable_from_database)
def whitelisted_config?(group, key) do
allowed_groups()
|> Enum.any?(fn
{whitelisted_group} ->
group == inspect(whitelisted_group)
{whitelisted_group, whitelisted_key} ->
group == inspect(whitelisted_group) && key == inspect(whitelisted_key)
end)
end
def whitelisted_config?(%{group: group, key: key}) do
whitelisted_config?(group, key)
end
def whitelisted_config?(%{group: group} = config) do
whitelisted_config?(group, config[:key])
end
end

View file

@ -8,6 +8,7 @@ defmodule Pleroma.Web.AdminAPI.ConfigController do
alias Pleroma.Config
alias Pleroma.ConfigDB
alias Pleroma.Web.Plugs.OAuthScopesPlug
alias Pleroma.Config.ConfigurableFromDatabase
plug(Pleroma.Web.ApiSpec.CastAndValidate)
plug(OAuthScopesPlug, %{scopes: ["admin:write"]} when action == :update)
@ -71,7 +72,11 @@ defmodule Pleroma.Web.AdminAPI.ConfigController do
end
def descriptions(conn, _params) do
descriptions = Enum.filter(Pleroma.Docs.JSON.compiled_descriptions(), &whitelisted_config?/1)
descriptions =
Enum.filter(
Pleroma.Docs.JSON.compiled_descriptions(),
&ConfigurableFromDatabase.whitelisted_config?/1
)
json(conn, translate_descriptions(descriptions))
end
@ -132,7 +137,7 @@ defmodule Pleroma.Web.AdminAPI.ConfigController do
with :ok <- configurable_from_database() do
results =
configs
|> Enum.filter(&whitelisted_config?/1)
|> Enum.filter(&ConfigurableFromDatabase.whitelisted_config?/1)
|> Enum.map(fn
%{group: group, key: key, delete: true} = params ->
ConfigDB.delete(%{group: group, key: key, subkeys: params[:subkeys]})
@ -167,29 +172,10 @@ defmodule Pleroma.Web.AdminAPI.ConfigController do
end
defp configurable_from_database do
if Config.get(:configurable_from_database) do
if ConfigurableFromDatabase.enabled() do
:ok
else
{:error, "You must enable configurable_from_database in your config file."}
end
end
defp whitelisted_config?(group, key) do
Pleroma.Config.ConfigurableFromDatabase.allowed_groups()
|> Enum.any?(fn
{whitelisted_group} ->
group == inspect(whitelisted_group)
{whitelisted_group, whitelisted_key} ->
group == inspect(whitelisted_group) && key == inspect(whitelisted_key)
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