@@ -580,6 +580,8 @@ Note: Available `:permission_group` is currently moderator and admin. 404 is ret | |||||
Module name can be passed as string, which starts with `Pleroma`, e.g. `"Pleroma.Upload"`. | Module name can be passed as string, which starts with `Pleroma`, e.g. `"Pleroma.Upload"`. | ||||
Atom or boolean value can be passed with `:` in the beginning, e.g. `":true"`, `":upload"`. | Atom or boolean value can be passed with `:` in the beginning, e.g. `":true"`, `":upload"`. | ||||
Integer with `i:`, e.g. `"i:150"`. | Integer with `i:`, e.g. `"i:150"`. | ||||
Tuple with more than 2 values with `{"tuple": ["first_val", Pleroma.Module, []]}`. | |||||
`{"tuple": ["some_string", "Pleroma.Some.Module", []]}` will be converted to `{"some_string", Pleroma.Some.Module, []}`. | |||||
Compile time settings (need instance reboot): | Compile time settings (need instance reboot): | ||||
- all settings by this keys: | - all settings by this keys: | ||||
@@ -619,6 +621,9 @@ Compile time settings (need instance reboot): | |||||
"follow_redirect": ":true", | "follow_redirect": ":true", | ||||
"pool": ":upload" | "pool": ":upload" | ||||
} | } | ||||
}, | |||||
"dispatch": { | |||||
"tuple": ["/api/v1/streaming", "Pleroma.Web.MastodonAPI.WebsocketHandler", []] | |||||
} | } | ||||
} | } | ||||
} | } | ||||
@@ -632,7 +637,7 @@ Compile time settings (need instance reboot): | |||||
configs: [ | configs: [ | ||||
{ | { | ||||
"key": string, | "key": string, | ||||
"value": string or {} or [] | |||||
"value": string or {} or [] or {"tuple": []} | |||||
} | } | ||||
] | ] | ||||
} | } | ||||
@@ -77,6 +77,8 @@ defmodule Pleroma.Web.AdminAPI.Config do | |||||
defp do_convert({k, v} = value) when is_tuple(value), | defp do_convert({k, v} = value) when is_tuple(value), | ||||
do: %{k => do_convert(v)} | do: %{k => do_convert(v)} | ||||
defp do_convert(value) when is_tuple(value), do: %{"tuple" => do_convert(Tuple.to_list(value))} | |||||
defp do_convert(value) when is_binary(value) or is_map(value) or is_number(value), do: value | defp do_convert(value) when is_binary(value) or is_map(value) or is_number(value), do: value | ||||
defp do_convert(value) when is_atom(value) do | defp do_convert(value) when is_atom(value) do | ||||
@@ -108,11 +110,16 @@ defmodule Pleroma.Web.AdminAPI.Config do | |||||
defp do_transform(%Regex{} = value) when is_map(value), do: value | defp do_transform(%Regex{} = value) when is_map(value), do: value | ||||
defp do_transform(%{"tuple" => [k, values] = entity}) when length(entity) == 2 do | |||||
{do_transform(k), do_transform(values)} | |||||
end | |||||
defp do_transform(%{"tuple" => values}) do | |||||
Enum.reduce(values, {}, fn val, acc -> Tuple.append(acc, do_transform(val)) end) | |||||
end | |||||
defp do_transform(value) when is_map(value) do | defp do_transform(value) when is_map(value) do | ||||
values = | |||||
for {key, val} <- value, | |||||
into: [], | |||||
do: {String.to_atom(key), do_transform(val)} | |||||
values = for {key, val} <- value, into: [], do: {String.to_atom(key), do_transform(val)} | |||||
Enum.sort(values) | Enum.sort(values) | ||||
end | end | ||||
@@ -124,28 +131,27 @@ defmodule Pleroma.Web.AdminAPI.Config do | |||||
defp do_transform(entity) when is_list(entity) and length(entity) == 1, do: hd(entity) | defp do_transform(entity) when is_list(entity) and length(entity) == 1, do: hd(entity) | ||||
defp do_transform(value) when is_binary(value) do | defp do_transform(value) when is_binary(value) do | ||||
value = String.trim(value) | |||||
String.trim(value) | |||||
|> do_transform_string() | |||||
end | |||||
defp do_transform(value), do: value | |||||
case String.length(value) do | |||||
0 -> | |||||
nil | |||||
defp do_transform_string(value) when byte_size(value) == 0, do: nil | |||||
_ -> | |||||
cond do | |||||
String.starts_with?(value, "Pleroma") -> | |||||
String.to_existing_atom("Elixir." <> value) | |||||
defp do_transform_string(value) do | |||||
cond do | |||||
String.starts_with?(value, "Pleroma") or String.starts_with?(value, "Phoenix") -> | |||||
String.to_existing_atom("Elixir." <> value) | |||||
String.starts_with?(value, ":") -> | |||||
String.replace(value, ":", "") |> String.to_existing_atom() | |||||
String.starts_with?(value, ":") -> | |||||
String.replace(value, ":", "") |> String.to_existing_atom() | |||||
String.starts_with?(value, "i:") -> | |||||
String.replace(value, "i:", "") |> String.to_integer() | |||||
String.starts_with?(value, "i:") -> | |||||
String.replace(value, "i:", "") |> String.to_integer() | |||||
true -> | |||||
value | |||||
end | |||||
true -> | |||||
value | |||||
end | end | ||||
end | end | ||||
defp do_transform(value), do: value | |||||
end | end |
@@ -1343,6 +1343,8 @@ defmodule Pleroma.Web.AdminAPI.AdminAPIControllerTest do | |||||
Application.delete_env(:pleroma, :key4) | Application.delete_env(:pleroma, :key4) | ||||
Application.delete_env(:pleroma, :keyaa1) | Application.delete_env(:pleroma, :keyaa1) | ||||
Application.delete_env(:pleroma, :keyaa2) | Application.delete_env(:pleroma, :keyaa2) | ||||
Application.delete_env(:pleroma, Pleroma.Web.Endpoint.NotReal) | |||||
Application.delete_env(:pleroma, Pleroma.Captcha.NotReal) | |||||
:ok = File.rm(temp_file) | :ok = File.rm(temp_file) | ||||
end) | end) | ||||
@@ -1469,7 +1471,7 @@ defmodule Pleroma.Web.AdminAPI.AdminAPIControllerTest do | |||||
post(conn, "/api/pleroma/admin/config", %{ | post(conn, "/api/pleroma/admin/config", %{ | ||||
configs: [ | configs: [ | ||||
%{ | %{ | ||||
"key" => "Pleroma.Captcha", | |||||
"key" => "Pleroma.Captcha.NotReal", | |||||
"value" => %{ | "value" => %{ | ||||
"enabled" => ":false", | "enabled" => ":false", | ||||
"method" => "Pleroma.Captcha.Kocaptcha", | "method" => "Pleroma.Captcha.Kocaptcha", | ||||
@@ -1482,7 +1484,7 @@ defmodule Pleroma.Web.AdminAPI.AdminAPIControllerTest do | |||||
assert json_response(conn, 200) == %{ | assert json_response(conn, 200) == %{ | ||||
"configs" => [ | "configs" => [ | ||||
%{ | %{ | ||||
"key" => "Pleroma.Captcha", | |||||
"key" => "Pleroma.Captcha.NotReal", | |||||
"value" => [ | "value" => [ | ||||
%{"enabled" => false}, | %{"enabled" => false}, | ||||
%{"method" => "Pleroma.Captcha.Kocaptcha"}, | %{"method" => "Pleroma.Captcha.Kocaptcha"}, | ||||
@@ -1492,5 +1494,119 @@ defmodule Pleroma.Web.AdminAPI.AdminAPIControllerTest do | |||||
] | ] | ||||
} | } | ||||
end | end | ||||
test "tuples with more than two values", %{conn: conn} do | |||||
conn = | |||||
post(conn, "/api/pleroma/admin/config", %{ | |||||
configs: [ | |||||
%{ | |||||
"key" => "Pleroma.Web.Endpoint.NotReal", | |||||
"value" => [ | |||||
%{ | |||||
"http" => %{ | |||||
"dispatch" => [ | |||||
%{ | |||||
"tuple" => [ | |||||
":_", | |||||
[ | |||||
%{ | |||||
"tuple" => [ | |||||
"/api/v1/streaming", | |||||
"Pleroma.Web.MastodonAPI.WebsocketHandler", | |||||
[] | |||||
] | |||||
}, | |||||
%{ | |||||
"tuple" => [ | |||||
"/websocket", | |||||
"Phoenix.Endpoint.CowboyWebSocket", | |||||
%{ | |||||
"tuple" => [ | |||||
"Phoenix.Transports.WebSocket", | |||||
%{ | |||||
"tuple" => [ | |||||
"Pleroma.Web.Endpoint", | |||||
"Pleroma.Web.UserSocket", | |||||
[] | |||||
] | |||||
} | |||||
] | |||||
} | |||||
] | |||||
}, | |||||
%{ | |||||
"tuple" => [ | |||||
":_", | |||||
"Phoenix.Endpoint.Cowboy2Handler", | |||||
%{ | |||||
"tuple" => ["Pleroma.Web.Endpoint", []] | |||||
} | |||||
] | |||||
} | |||||
] | |||||
] | |||||
} | |||||
] | |||||
} | |||||
} | |||||
] | |||||
} | |||||
] | |||||
}) | |||||
assert json_response(conn, 200) == %{ | |||||
"configs" => [ | |||||
%{ | |||||
"key" => "Pleroma.Web.Endpoint.NotReal", | |||||
"value" => [ | |||||
%{ | |||||
"http" => %{ | |||||
"dispatch" => %{ | |||||
"_" => [ | |||||
%{ | |||||
"tuple" => [ | |||||
"/api/v1/streaming", | |||||
"Pleroma.Web.MastodonAPI.WebsocketHandler", | |||||
[] | |||||
] | |||||
}, | |||||
%{ | |||||
"tuple" => [ | |||||
"/websocket", | |||||
"Phoenix.Endpoint.CowboyWebSocket", | |||||
%{ | |||||
"Elixir.Phoenix.Transports.WebSocket" => %{ | |||||
"tuple" => [ | |||||
"Pleroma.Web.Endpoint", | |||||
"Pleroma.Web.UserSocket", | |||||
[] | |||||
] | |||||
} | |||||
} | |||||
] | |||||
}, | |||||
%{ | |||||
"tuple" => [ | |||||
"_", | |||||
"Phoenix.Endpoint.Cowboy2Handler", | |||||
%{"Elixir.Pleroma.Web.Endpoint" => []} | |||||
] | |||||
} | |||||
] | |||||
} | |||||
} | |||||
} | |||||
] | |||||
} | |||||
] | |||||
} | |||||
end | |||||
end | end | ||||
end | end | ||||
# Needed for testing | |||||
defmodule Pleroma.Web.Endpoint.NotReal do | |||||
end | |||||
defmodule Pleroma.Captcha.NotReal do | |||||
end |
@@ -179,5 +179,80 @@ defmodule Pleroma.Web.AdminAPI.ConfigTest do | |||||
assert Config.from_binary(binary) == | assert Config.from_binary(binary) == | ||||
[federated_timeline_removal: [], reject: [~r/comp[lL][aA][iI][nN]er/], replace: []] | [federated_timeline_removal: [], reject: [~r/comp[lL][aA][iI][nN]er/], replace: []] | ||||
end | end | ||||
test "complex map with tuples with more than 2 values" do | |||||
binary = | |||||
Config.transform(%{ | |||||
"http" => %{ | |||||
"dispatch" => [ | |||||
%{ | |||||
"tuple" => [ | |||||
":_", | |||||
[ | |||||
%{ | |||||
"tuple" => [ | |||||
"/api/v1/streaming", | |||||
"Pleroma.Web.MastodonAPI.WebsocketHandler", | |||||
[] | |||||
] | |||||
}, | |||||
%{ | |||||
"tuple" => [ | |||||
"/websocket", | |||||
"Phoenix.Endpoint.CowboyWebSocket", | |||||
%{ | |||||
"tuple" => [ | |||||
"Phoenix.Transports.WebSocket", | |||||
%{"tuple" => ["Pleroma.Web.Endpoint", "Pleroma.Web.UserSocket", []]} | |||||
] | |||||
} | |||||
] | |||||
}, | |||||
%{ | |||||
"tuple" => [ | |||||
":_", | |||||
"Phoenix.Endpoint.Cowboy2Handler", | |||||
%{ | |||||
"tuple" => ["Pleroma.Web.Endpoint", []] | |||||
} | |||||
] | |||||
} | |||||
] | |||||
] | |||||
} | |||||
] | |||||
} | |||||
}) | |||||
assert binary == | |||||
:erlang.term_to_binary( | |||||
http: [ | |||||
dispatch: [ | |||||
_: [ | |||||
{"/api/v1/streaming", Pleroma.Web.MastodonAPI.WebsocketHandler, []}, | |||||
{"/websocket", Phoenix.Endpoint.CowboyWebSocket, | |||||
{Phoenix.Transports.WebSocket, | |||||
{Pleroma.Web.Endpoint, Pleroma.Web.UserSocket, []}}}, | |||||
{:_, Phoenix.Endpoint.Cowboy2Handler, {Pleroma.Web.Endpoint, []}} | |||||
] | |||||
] | |||||
] | |||||
) | |||||
assert Config.from_binary(binary) == [ | |||||
http: [ | |||||
dispatch: [ | |||||
{:_, | |||||
[ | |||||
{"/api/v1/streaming", Pleroma.Web.MastodonAPI.WebsocketHandler, []}, | |||||
{"/websocket", Phoenix.Endpoint.CowboyWebSocket, | |||||
{Phoenix.Transports.WebSocket, | |||||
{Pleroma.Web.Endpoint, Pleroma.Web.UserSocket, []}}}, | |||||
{:_, Phoenix.Endpoint.Cowboy2Handler, {Pleroma.Web.Endpoint, []}} | |||||
]} | |||||
] | |||||
] | |||||
] | |||||
end | |||||
end | end | ||||
end | end |