forked from AkkomaGang/akkoma
Merge branch 'feature/database-configuration-whitelist' into 'develop'
Database configuration whitelist See merge request pleroma/pleroma!2522
This commit is contained in:
commit
e455ca3f3e
5 changed files with 117 additions and 16 deletions
|
@ -19,6 +19,7 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/).
|
||||||
- NodeInfo: `pleroma:api/v1/notifications:include_types_filter` to the `features` list.
|
- NodeInfo: `pleroma:api/v1/notifications:include_types_filter` to the `features` list.
|
||||||
- NodeInfo: `pleroma_emoji_reactions` to the `features` list.
|
- NodeInfo: `pleroma_emoji_reactions` to the `features` list.
|
||||||
- Configuration: `:restrict_unauthenticated` setting, restrict access for unauthenticated users to timelines (public and federate), user profiles and statuses.
|
- Configuration: `:restrict_unauthenticated` setting, restrict access for unauthenticated users to timelines (public and federate), user profiles and statuses.
|
||||||
|
- Configuration: Add `:database_config_whitelist` setting to whitelist settings which can be configured from AdminFE.
|
||||||
- New HTTP adapter [gun](https://github.com/ninenines/gun). Gun adapter requires minimum OTP version of 22.2 otherwise Pleroma won’t start. For hackney OTP update is not required.
|
- New HTTP adapter [gun](https://github.com/ninenines/gun). Gun adapter requires minimum OTP version of 22.2 otherwise Pleroma won’t start. For hackney OTP update is not required.
|
||||||
- Mix task to create trusted OAuth App.
|
- Mix task to create trusted OAuth App.
|
||||||
- Notifications: Added `follow_request` notification type.
|
- Notifications: Added `follow_request` notification type.
|
||||||
|
|
|
@ -911,6 +911,21 @@ config :auto_linker,
|
||||||
|
|
||||||
Boolean, enables/disables in-database configuration. Read [Transfering the config to/from the database](../administration/CLI_tasks/config.md) for more information.
|
Boolean, enables/disables in-database configuration. Read [Transfering the config to/from the database](../administration/CLI_tasks/config.md) for more information.
|
||||||
|
|
||||||
|
## :database_config_whitelist
|
||||||
|
|
||||||
|
List of valid configuration sections which are allowed to be configured from the
|
||||||
|
database. Settings stored in the database before the whitelist is configured are
|
||||||
|
still applied, so it is suggested to only use the whitelist on instances that
|
||||||
|
have not migrated the config to the database.
|
||||||
|
|
||||||
|
Example:
|
||||||
|
```elixir
|
||||||
|
config :pleroma, :database_config_whitelist, [
|
||||||
|
{:pleroma, :instance},
|
||||||
|
{:pleroma, Pleroma.Web.Metadata},
|
||||||
|
{:auto_linker}
|
||||||
|
]
|
||||||
|
```
|
||||||
|
|
||||||
### Multi-factor authentication - :two_factor_authentication
|
### Multi-factor authentication - :two_factor_authentication
|
||||||
* `totp` - a list containing TOTP configuration
|
* `totp` - a list containing TOTP configuration
|
||||||
|
|
|
@ -18,7 +18,6 @@ def compile do
|
||||||
with config <- Pleroma.Config.Loader.read("config/description.exs") do
|
with config <- Pleroma.Config.Loader.read("config/description.exs") do
|
||||||
config[:pleroma][:config_description]
|
config[:pleroma][:config_description]
|
||||||
|> Pleroma.Docs.Generator.convert_to_strings()
|
|> Pleroma.Docs.Generator.convert_to_strings()
|
||||||
|> Jason.encode!()
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -37,7 +37,7 @@ defmodule Pleroma.Web.AdminAPI.AdminAPIController do
|
||||||
|
|
||||||
require Logger
|
require Logger
|
||||||
|
|
||||||
@descriptions_json Pleroma.Docs.JSON.compile()
|
@descriptions Pleroma.Docs.JSON.compile()
|
||||||
@users_page_size 50
|
@users_page_size 50
|
||||||
|
|
||||||
plug(
|
plug(
|
||||||
|
@ -897,9 +897,9 @@ def list_log(conn, params) do
|
||||||
end
|
end
|
||||||
|
|
||||||
def config_descriptions(conn, _params) do
|
def config_descriptions(conn, _params) do
|
||||||
conn
|
descriptions = Enum.filter(@descriptions, &whitelisted_config?/1)
|
||||||
|> Plug.Conn.put_resp_content_type("application/json")
|
|
||||||
|> Plug.Conn.send_resp(200, @descriptions_json)
|
json(conn, descriptions)
|
||||||
end
|
end
|
||||||
|
|
||||||
def config_show(conn, %{"only_db" => true}) do
|
def config_show(conn, %{"only_db" => true}) do
|
||||||
|
@ -954,7 +954,9 @@ def config_show(conn, _params) do
|
||||||
def config_update(conn, %{"configs" => configs}) do
|
def config_update(conn, %{"configs" => configs}) do
|
||||||
with :ok <- configurable_from_database(conn) do
|
with :ok <- configurable_from_database(conn) do
|
||||||
{_errors, results} =
|
{_errors, results} =
|
||||||
Enum.map(configs, fn
|
configs
|
||||||
|
|> Enum.filter(&whitelisted_config?/1)
|
||||||
|
|> Enum.map(fn
|
||||||
%{"group" => group, "key" => key, "delete" => true} = params ->
|
%{"group" => group, "key" => key, "delete" => true} = params ->
|
||||||
ConfigDB.delete(%{group: group, key: key, subkeys: params["subkeys"]})
|
ConfigDB.delete(%{group: group, key: key, subkeys: params["subkeys"]})
|
||||||
|
|
||||||
|
@ -1016,6 +1018,28 @@ defp configurable_from_database(conn) do
|
||||||
end
|
end
|
||||||
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
|
def reload_emoji(conn, _params) do
|
||||||
Pleroma.Emoji.reload()
|
Pleroma.Emoji.reload()
|
||||||
|
|
||||||
|
|
|
@ -2940,6 +2940,33 @@ test "proxy tuple ip", %{conn: conn} do
|
||||||
assert %{"tuple" => [":proxy_url", %{"tuple" => [":socks5", "127.0.0.1", 1234]}]} in value
|
assert %{"tuple" => [":proxy_url", %{"tuple" => [":socks5", "127.0.0.1", 1234]}]} in value
|
||||||
assert ":proxy_url" in db
|
assert ":proxy_url" in db
|
||||||
end
|
end
|
||||||
|
|
||||||
|
test "doesn't set keys not in the whitelist", %{conn: conn} do
|
||||||
|
clear_config(:database_config_whitelist, [
|
||||||
|
{:pleroma, :key1},
|
||||||
|
{:pleroma, :key2},
|
||||||
|
{:pleroma, Pleroma.Captcha.NotReal},
|
||||||
|
{:not_real}
|
||||||
|
])
|
||||||
|
|
||||||
|
post(conn, "/api/pleroma/admin/config", %{
|
||||||
|
configs: [
|
||||||
|
%{group: ":pleroma", key: ":key1", value: "value1"},
|
||||||
|
%{group: ":pleroma", key: ":key2", value: "value2"},
|
||||||
|
%{group: ":pleroma", key: ":key3", value: "value3"},
|
||||||
|
%{group: ":pleroma", key: "Pleroma.Web.Endpoint.NotReal", value: "value4"},
|
||||||
|
%{group: ":pleroma", key: "Pleroma.Captcha.NotReal", value: "value5"},
|
||||||
|
%{group: ":not_real", key: ":anything", value: "value6"}
|
||||||
|
]
|
||||||
|
})
|
||||||
|
|
||||||
|
assert Application.get_env(:pleroma, :key1) == "value1"
|
||||||
|
assert Application.get_env(:pleroma, :key2) == "value2"
|
||||||
|
assert Application.get_env(:pleroma, :key3) == nil
|
||||||
|
assert Application.get_env(:pleroma, Pleroma.Web.Endpoint.NotReal) == nil
|
||||||
|
assert Application.get_env(:pleroma, Pleroma.Captcha.NotReal) == "value5"
|
||||||
|
assert Application.get_env(:not_real, :anything) == "value6"
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
describe "GET /api/pleroma/admin/restart" do
|
describe "GET /api/pleroma/admin/restart" do
|
||||||
|
@ -3571,7 +3598,8 @@ test "it deletes the note", %{conn: conn, report_id: report_id} do
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
test "GET /api/pleroma/admin/config/descriptions", %{conn: conn} do
|
describe "GET /api/pleroma/admin/config/descriptions" do
|
||||||
|
test "structure", %{conn: conn} do
|
||||||
admin = insert(:user, is_admin: true)
|
admin = insert(:user, is_admin: true)
|
||||||
|
|
||||||
conn =
|
conn =
|
||||||
|
@ -3586,6 +3614,40 @@ test "GET /api/pleroma/admin/config/descriptions", %{conn: conn} do
|
||||||
assert child["description"]
|
assert child["description"]
|
||||||
end
|
end
|
||||||
|
|
||||||
|
test "filters by database configuration whitelist", %{conn: conn} do
|
||||||
|
clear_config(:database_config_whitelist, [
|
||||||
|
{:pleroma, :instance},
|
||||||
|
{:pleroma, :activitypub},
|
||||||
|
{:pleroma, Pleroma.Upload},
|
||||||
|
{:esshd}
|
||||||
|
])
|
||||||
|
|
||||||
|
admin = insert(:user, is_admin: true)
|
||||||
|
|
||||||
|
conn =
|
||||||
|
assign(conn, :user, admin)
|
||||||
|
|> get("/api/pleroma/admin/config/descriptions")
|
||||||
|
|
||||||
|
children = json_response(conn, 200)
|
||||||
|
|
||||||
|
assert length(children) == 4
|
||||||
|
|
||||||
|
assert Enum.count(children, fn c -> c["group"] == ":pleroma" end) == 3
|
||||||
|
|
||||||
|
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)
|
||||||
|
assert web_endpoint["children"]
|
||||||
|
|
||||||
|
esshd = Enum.find(children, fn c -> c["group"] == ":esshd" end)
|
||||||
|
assert esshd["children"]
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
describe "/api/pleroma/admin/stats" do
|
describe "/api/pleroma/admin/stats" do
|
||||||
test "status visibility count", %{conn: conn} do
|
test "status visibility count", %{conn: conn} do
|
||||||
admin = insert(:user, is_admin: true)
|
admin = insert(:user, is_admin: true)
|
||||||
|
|
Loading…
Reference in a new issue