Runtime configuration
Related to #85 Everything should now be configured at runtime, with the exception of the `Pleroma.HTML` scrubbers (the scrubbers used can be changed at runtime, but their configuration is compile-time) because it's building a module with a macro.
This commit is contained in:
parent
25512aa29c
commit
5bb88fd174
|
@ -1,13 +1,29 @@
|
||||||
defmodule Pleroma.Config do
|
defmodule Pleroma.Config do
|
||||||
def get([key]), do: get(key)
|
defmodule Error do
|
||||||
|
defexception [:message]
|
||||||
def get([parent_key | keys]) do
|
|
||||||
Application.get_env(:pleroma, parent_key)
|
|
||||||
|> get_in(keys)
|
|
||||||
end
|
end
|
||||||
|
|
||||||
def get(key) do
|
def get(key), do: get(key, nil)
|
||||||
Application.get_env(:pleroma, key)
|
|
||||||
|
def get([key], default), do: get(key, default)
|
||||||
|
|
||||||
|
def get([parent_key | keys], default) do
|
||||||
|
Application.get_env(:pleroma, parent_key)
|
||||||
|
|> get_in(keys) || default
|
||||||
|
end
|
||||||
|
|
||||||
|
def get(key, default) do
|
||||||
|
Application.get_env(:pleroma, key, default)
|
||||||
|
end
|
||||||
|
|
||||||
|
def get!(key) do
|
||||||
|
value = get(key, nil)
|
||||||
|
|
||||||
|
if value == nil do
|
||||||
|
raise(Error, message: "Missing configuration value: #{inspect(key)}")
|
||||||
|
else
|
||||||
|
value
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
def put([key], value), do: put(key, value)
|
def put([key], value), do: put(key, value)
|
||||||
|
|
|
@ -29,8 +29,6 @@ def parse_mentions(text) do
|
||||||
|> Enum.filter(fn {_match, user} -> user end)
|
|> Enum.filter(fn {_match, user} -> user end)
|
||||||
end
|
end
|
||||||
|
|
||||||
@instance Application.get_env(:pleroma, :instance)
|
|
||||||
|
|
||||||
def emojify(text) do
|
def emojify(text) do
|
||||||
emojify(text, Emoji.get_all())
|
emojify(text, Emoji.get_all())
|
||||||
end
|
end
|
||||||
|
|
|
@ -1,16 +1,16 @@
|
||||||
defmodule Pleroma.Gopher.Server do
|
defmodule Pleroma.Gopher.Server do
|
||||||
use GenServer
|
use GenServer
|
||||||
require Logger
|
require Logger
|
||||||
@gopher Application.get_env(:pleroma, :gopher)
|
|
||||||
|
|
||||||
def start_link() do
|
def start_link() do
|
||||||
ip = Keyword.get(@gopher, :ip, {0, 0, 0, 0})
|
config = Pleroma.Config.get(:gopher, [])
|
||||||
port = Keyword.get(@gopher, :port, 1234)
|
ip = Keyword.get(config, :ip, {0, 0, 0, 0})
|
||||||
|
port = Keyword.get(config, :port, 1234)
|
||||||
GenServer.start_link(__MODULE__, [ip, port], [])
|
GenServer.start_link(__MODULE__, [ip, port], [])
|
||||||
end
|
end
|
||||||
|
|
||||||
def init([ip, port]) do
|
def init([ip, port]) do
|
||||||
if Keyword.get(@gopher, :enabled, false) do
|
if Pleroma.Config.get([:gopher, :enabled], false) do
|
||||||
Logger.info("Starting gopher server on #{port}")
|
Logger.info("Starting gopher server on #{port}")
|
||||||
|
|
||||||
:ranch.start_listener(
|
:ranch.start_listener(
|
||||||
|
@ -37,9 +37,6 @@ defmodule Pleroma.Gopher.Server.ProtocolHandler do
|
||||||
alias Pleroma.Repo
|
alias Pleroma.Repo
|
||||||
alias Pleroma.HTML
|
alias Pleroma.HTML
|
||||||
|
|
||||||
@instance Application.get_env(:pleroma, :instance)
|
|
||||||
@gopher Application.get_env(:pleroma, :gopher)
|
|
||||||
|
|
||||||
def start_link(ref, socket, transport, opts) do
|
def start_link(ref, socket, transport, opts) do
|
||||||
pid = spawn_link(__MODULE__, :init, [ref, socket, transport, opts])
|
pid = spawn_link(__MODULE__, :init, [ref, socket, transport, opts])
|
||||||
{:ok, pid}
|
{:ok, pid}
|
||||||
|
@ -62,7 +59,7 @@ def info(text) do
|
||||||
|
|
||||||
def link(name, selector, type \\ 1) do
|
def link(name, selector, type \\ 1) do
|
||||||
address = Pleroma.Web.Endpoint.host()
|
address = Pleroma.Web.Endpoint.host()
|
||||||
port = Keyword.get(@gopher, :port, 1234)
|
port = Pleroma.Config.get([:gopher, :port], 1234)
|
||||||
"#{type}#{name}\t#{selector}\t#{address}\t#{port}\r\n"
|
"#{type}#{name}\t#{selector}\t#{address}\t#{port}\r\n"
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -85,7 +82,7 @@ def render_activities(activities) do
|
||||||
end
|
end
|
||||||
|
|
||||||
def response("") do
|
def response("") do
|
||||||
info("Welcome to #{Keyword.get(@instance, :name, "Pleroma")}!") <>
|
info("Welcome to #{Pleroma.Config.get([:instance, :name], "Pleroma")}!") <>
|
||||||
link("Public Timeline", "/main/public") <>
|
link("Public Timeline", "/main/public") <>
|
||||||
link("Federated Timeline", "/main/all") <> ".\r\n"
|
link("Federated Timeline", "/main/all") <> ".\r\n"
|
||||||
end
|
end
|
||||||
|
|
|
@ -1,14 +1,12 @@
|
||||||
defmodule Pleroma.HTML do
|
defmodule Pleroma.HTML do
|
||||||
alias HtmlSanitizeEx.Scrubber
|
alias HtmlSanitizeEx.Scrubber
|
||||||
|
|
||||||
@markup Application.get_env(:pleroma, :markup)
|
|
||||||
|
|
||||||
defp get_scrubbers(scrubber) when is_atom(scrubber), do: [scrubber]
|
defp get_scrubbers(scrubber) when is_atom(scrubber), do: [scrubber]
|
||||||
defp get_scrubbers(scrubbers) when is_list(scrubbers), do: scrubbers
|
defp get_scrubbers(scrubbers) when is_list(scrubbers), do: scrubbers
|
||||||
defp get_scrubbers(_), do: [Pleroma.HTML.Scrubber.Default]
|
defp get_scrubbers(_), do: [Pleroma.HTML.Scrubber.Default]
|
||||||
|
|
||||||
def get_scrubbers() do
|
def get_scrubbers() do
|
||||||
Keyword.get(@markup, :scrub_policy)
|
Pleroma.Config.get([:markup, :scrub_policy])
|
||||||
|> get_scrubbers
|
|> get_scrubbers
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
|
@ -1,9 +1,6 @@
|
||||||
defmodule Pleroma.Upload do
|
defmodule Pleroma.Upload do
|
||||||
alias Ecto.UUID
|
alias Ecto.UUID
|
||||||
|
|
||||||
@storage_backend Application.get_env(:pleroma, Pleroma.Upload)
|
|
||||||
|> Keyword.fetch!(:uploader)
|
|
||||||
|
|
||||||
def check_file_size(path, nil), do: true
|
def check_file_size(path, nil), do: true
|
||||||
|
|
||||||
def check_file_size(path, size_limit) do
|
def check_file_size(path, size_limit) do
|
||||||
|
@ -21,8 +18,7 @@ def store(%Plug.Upload{} = file, should_dedupe, size_limit) do
|
||||||
true <- check_file_size(file.path, size_limit) do
|
true <- check_file_size(file.path, size_limit) do
|
||||||
strip_exif_data(content_type, file.path)
|
strip_exif_data(content_type, file.path)
|
||||||
|
|
||||||
{:ok, url_path} =
|
{:ok, url_path} = uploader().put_file(name, uuid, file.path, content_type, should_dedupe)
|
||||||
@storage_backend.put_file(name, uuid, file.path, content_type, should_dedupe)
|
|
||||||
|
|
||||||
%{
|
%{
|
||||||
"type" => "Document",
|
"type" => "Document",
|
||||||
|
@ -57,8 +53,7 @@ def store(%{"img" => "data:image/" <> image_data}, should_dedupe, size_limit) do
|
||||||
content_type
|
content_type
|
||||||
)
|
)
|
||||||
|
|
||||||
{:ok, url_path} =
|
{:ok, url_path} = uploader().put_file(name, uuid, tmp_path, content_type, should_dedupe)
|
||||||
@storage_backend.put_file(name, uuid, tmp_path, content_type, should_dedupe)
|
|
||||||
|
|
||||||
%{
|
%{
|
||||||
"type" => "Image",
|
"type" => "Image",
|
||||||
|
@ -182,4 +177,8 @@ def get_content_type(file) do
|
||||||
_e -> "application/octet-stream"
|
_e -> "application/octet-stream"
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
defp uploader() do
|
||||||
|
Pleroma.Config.get!([Pleroma.Upload, :uploader])
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -1,11 +1,9 @@
|
||||||
defmodule Pleroma.Uploaders.Swift.Keystone do
|
defmodule Pleroma.Uploaders.Swift.Keystone do
|
||||||
use HTTPoison.Base
|
use HTTPoison.Base
|
||||||
|
|
||||||
@settings Application.get_env(:pleroma, Pleroma.Uploaders.Swift)
|
|
||||||
|
|
||||||
def process_url(url) do
|
def process_url(url) do
|
||||||
Enum.join(
|
Enum.join(
|
||||||
[Keyword.fetch!(@settings, :auth_url), url],
|
[Pleroma.Config.get!([Pleroma.Uploaders.Swift, :auth_url]), url],
|
||||||
"/"
|
"/"
|
||||||
)
|
)
|
||||||
end
|
end
|
||||||
|
@ -16,9 +14,10 @@ def process_response_body(body) do
|
||||||
end
|
end
|
||||||
|
|
||||||
def get_token() do
|
def get_token() do
|
||||||
username = Keyword.fetch!(@settings, :username)
|
settings = Pleroma.Config.get(Pleroma.Uploaders.Swift)
|
||||||
password = Keyword.fetch!(@settings, :password)
|
username = Keyword.fetch!(settings, :username)
|
||||||
tenant_id = Keyword.fetch!(@settings, :tenant_id)
|
password = Keyword.fetch!(settings, :password)
|
||||||
|
tenant_id = Keyword.fetch!(settings, :tenant_id)
|
||||||
|
|
||||||
case post(
|
case post(
|
||||||
"/tokens",
|
"/tokens",
|
||||||
|
|
|
@ -1,17 +1,15 @@
|
||||||
defmodule Pleroma.Uploaders.Swift.Client do
|
defmodule Pleroma.Uploaders.Swift.Client do
|
||||||
use HTTPoison.Base
|
use HTTPoison.Base
|
||||||
|
|
||||||
@settings Application.get_env(:pleroma, Pleroma.Uploaders.Swift)
|
|
||||||
|
|
||||||
def process_url(url) do
|
def process_url(url) do
|
||||||
Enum.join(
|
Enum.join(
|
||||||
[Keyword.fetch!(@settings, :storage_url), url],
|
[Pleroma.Config.get!([Pleroma.Uploaders.Swift, :storage_url]), url],
|
||||||
"/"
|
"/"
|
||||||
)
|
)
|
||||||
end
|
end
|
||||||
|
|
||||||
def upload_file(filename, body, content_type) do
|
def upload_file(filename, body, content_type) do
|
||||||
object_url = Keyword.fetch!(@settings, :object_url)
|
object_url = Pleroma.Config.get!([Pleroma.Uploaders.Swift, :object_url])
|
||||||
token = Pleroma.Uploaders.Swift.Keystone.get_token()
|
token = Pleroma.Uploaders.Swift.Keystone.get_token()
|
||||||
|
|
||||||
case put("#{filename}", body, "X-Auth-Token": token, "Content-Type": content_type) do
|
case put("#{filename}", body, "X-Auth-Token": token, "Content-Type": content_type) do
|
||||||
|
|
|
@ -10,8 +10,6 @@ defmodule Pleroma.Web.ActivityPub.ActivityPub do
|
||||||
|
|
||||||
@httpoison Application.get_env(:pleroma, :httpoison)
|
@httpoison Application.get_env(:pleroma, :httpoison)
|
||||||
|
|
||||||
@instance Application.get_env(:pleroma, :instance)
|
|
||||||
|
|
||||||
# For Announce activities, we filter the recipients based on following status for any actors
|
# For Announce activities, we filter the recipients based on following status for any actors
|
||||||
# that match actual users. See issue #164 for more information about why this is necessary.
|
# that match actual users. See issue #164 for more information about why this is necessary.
|
||||||
defp get_recipients(%{"type" => "Announce"} = data) do
|
defp get_recipients(%{"type" => "Announce"} = data) do
|
||||||
|
@ -659,14 +657,12 @@ def make_user_from_nickname(nickname) do
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
@quarantined_instances Keyword.get(@instance, :quarantined_instances, [])
|
|
||||||
|
|
||||||
def should_federate?(inbox, public) do
|
def should_federate?(inbox, public) do
|
||||||
if public do
|
if public do
|
||||||
true
|
true
|
||||||
else
|
else
|
||||||
inbox_info = URI.parse(inbox)
|
inbox_info = URI.parse(inbox)
|
||||||
inbox_info.host not in @quarantined_instances
|
!Enum.member?(Pleroma.Config.get([:instance, :quarantined_instances], []), inbox_info.host)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
|
@ -3,10 +3,8 @@ defmodule Pleroma.Web.ActivityPub.MRF.NormalizeMarkup do
|
||||||
|
|
||||||
@behaviour Pleroma.Web.ActivityPub.MRF
|
@behaviour Pleroma.Web.ActivityPub.MRF
|
||||||
|
|
||||||
@mrf_normalize_markup Application.get_env(:pleroma, :mrf_normalize_markup)
|
|
||||||
|
|
||||||
def filter(%{"type" => activity_type} = object) when activity_type == "Create" do
|
def filter(%{"type" => activity_type} = object) when activity_type == "Create" do
|
||||||
scrub_policy = Keyword.get(@mrf_normalize_markup, :scrub_policy)
|
scrub_policy = Pleroma.Config.get([:mrf_normalize_markup, :scrub_policy])
|
||||||
|
|
||||||
child = object["object"]
|
child = object["object"]
|
||||||
|
|
||||||
|
|
|
@ -2,10 +2,6 @@ defmodule Pleroma.Web.ActivityPub.MRF.RejectNonPublic do
|
||||||
alias Pleroma.User
|
alias Pleroma.User
|
||||||
@behaviour Pleroma.Web.ActivityPub.MRF
|
@behaviour Pleroma.Web.ActivityPub.MRF
|
||||||
|
|
||||||
@mrf_rejectnonpublic Application.get_env(:pleroma, :mrf_rejectnonpublic)
|
|
||||||
@allow_followersonly Keyword.get(@mrf_rejectnonpublic, :allow_followersonly)
|
|
||||||
@allow_direct Keyword.get(@mrf_rejectnonpublic, :allow_direct)
|
|
||||||
|
|
||||||
@impl true
|
@impl true
|
||||||
def filter(%{"type" => "Create"} = object) do
|
def filter(%{"type" => "Create"} = object) do
|
||||||
user = User.get_cached_by_ap_id(object["actor"])
|
user = User.get_cached_by_ap_id(object["actor"])
|
||||||
|
@ -20,6 +16,8 @@ def filter(%{"type" => "Create"} = object) do
|
||||||
true -> "direct"
|
true -> "direct"
|
||||||
end
|
end
|
||||||
|
|
||||||
|
policy = Pleroma.Config.get(:mrf_rejectnonpublic)
|
||||||
|
|
||||||
case visibility do
|
case visibility do
|
||||||
"public" ->
|
"public" ->
|
||||||
{:ok, object}
|
{:ok, object}
|
||||||
|
@ -28,14 +26,14 @@ def filter(%{"type" => "Create"} = object) do
|
||||||
{:ok, object}
|
{:ok, object}
|
||||||
|
|
||||||
"followers" ->
|
"followers" ->
|
||||||
with true <- @allow_followersonly do
|
with true <- Keyword.get(policy, :allow_followersonly) do
|
||||||
{:ok, object}
|
{:ok, object}
|
||||||
else
|
else
|
||||||
_e -> {:reject, nil}
|
_e -> {:reject, nil}
|
||||||
end
|
end
|
||||||
|
|
||||||
"direct" ->
|
"direct" ->
|
||||||
with true <- @allow_direct do
|
with true <- Keyword.get(policy, :allow_direct) do
|
||||||
{:ok, object}
|
{:ok, object}
|
||||||
else
|
else
|
||||||
_e -> {:reject, nil}
|
_e -> {:reject, nil}
|
||||||
|
|
|
@ -2,60 +2,75 @@ defmodule Pleroma.Web.ActivityPub.MRF.SimplePolicy do
|
||||||
alias Pleroma.User
|
alias Pleroma.User
|
||||||
@behaviour Pleroma.Web.ActivityPub.MRF
|
@behaviour Pleroma.Web.ActivityPub.MRF
|
||||||
|
|
||||||
@mrf_policy Application.get_env(:pleroma, :mrf_simple)
|
defp check_accept(%{host: actor_host} = _actor_info, object) do
|
||||||
|
accepts = Pleroma.Config.get([:mrf_simple, :accept])
|
||||||
|
|
||||||
@accept Keyword.get(@mrf_policy, :accept)
|
cond do
|
||||||
defp check_accept(%{host: actor_host} = actor_info, object)
|
accepts == [] -> {:ok, object}
|
||||||
when length(@accept) > 0 and not (actor_host in @accept) do
|
Enum.member?(accepts, actor_host) -> {:ok, object}
|
||||||
{:reject, nil}
|
true -> {:reject, nil}
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
defp check_accept(actor_info, object), do: {:ok, object}
|
defp check_reject(%{host: actor_host} = _actor_info, object) do
|
||||||
|
if Enum.member?(Pleroma.Config.get([:mrf_simple, :reject]), actor_host) do
|
||||||
@reject Keyword.get(@mrf_policy, :reject)
|
|
||||||
defp check_reject(%{host: actor_host} = actor_info, object) when actor_host in @reject do
|
|
||||||
{:reject, nil}
|
{:reject, nil}
|
||||||
|
else
|
||||||
|
{:ok, object}
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
defp check_reject(actor_info, object), do: {:ok, object}
|
defp check_media_removal(
|
||||||
|
%{host: actor_host} = _actor_info,
|
||||||
@media_removal Keyword.get(@mrf_policy, :media_removal)
|
%{"type" => "Create", "object" => %{"attachement" => child_attachement}} = object
|
||||||
defp check_media_removal(%{host: actor_host} = actor_info, %{"type" => "Create"} = object)
|
)
|
||||||
when actor_host in @media_removal do
|
when length(child_attachement) > 0 do
|
||||||
|
object =
|
||||||
|
if Enum.member?(Pleroma.Config.get([:mrf_simple, :media_removal]), actor_host) do
|
||||||
child_object = Map.delete(object["object"], "attachment")
|
child_object = Map.delete(object["object"], "attachment")
|
||||||
object = Map.put(object, "object", child_object)
|
Map.put(object, "object", child_object)
|
||||||
|
else
|
||||||
|
object
|
||||||
|
end
|
||||||
|
|
||||||
{:ok, object}
|
{:ok, object}
|
||||||
end
|
end
|
||||||
|
|
||||||
defp check_media_removal(actor_info, object), do: {:ok, object}
|
defp check_media_removal(_actor_info, object), do: {:ok, object}
|
||||||
|
|
||||||
@media_nsfw Keyword.get(@mrf_policy, :media_nsfw)
|
|
||||||
defp check_media_nsfw(
|
defp check_media_nsfw(
|
||||||
%{host: actor_host} = actor_info,
|
%{host: actor_host} = _actor_info,
|
||||||
%{
|
%{
|
||||||
"type" => "Create",
|
"type" => "Create",
|
||||||
"object" => %{"attachment" => child_attachment} = child_object
|
"object" => %{"attachment" => child_attachment} = child_object
|
||||||
} = object
|
} = object
|
||||||
)
|
)
|
||||||
when actor_host in @media_nsfw and length(child_attachment) > 0 do
|
when length(child_attachment) > 0 do
|
||||||
|
object =
|
||||||
|
if Enum.member?(Pleroma.Config.get([:mrf_simple, :media_nsfw]), actor_host) do
|
||||||
tags = (child_object["tag"] || []) ++ ["nsfw"]
|
tags = (child_object["tag"] || []) ++ ["nsfw"]
|
||||||
child_object = Map.put(child_object, "tags", tags)
|
child_object = Map.put(child_object, "tags", tags)
|
||||||
child_object = Map.put(child_object, "sensitive", true)
|
child_object = Map.put(child_object, "sensitive", true)
|
||||||
object = Map.put(object, "object", child_object)
|
Map.put(object, "object", child_object)
|
||||||
|
else
|
||||||
|
object
|
||||||
|
end
|
||||||
|
|
||||||
{:ok, object}
|
{:ok, object}
|
||||||
end
|
end
|
||||||
|
|
||||||
defp check_media_nsfw(actor_info, object), do: {:ok, object}
|
defp check_media_nsfw(_actor_info, object), do: {:ok, object}
|
||||||
|
|
||||||
@ftl_removal Keyword.get(@mrf_policy, :federated_timeline_removal)
|
defp check_ftl_removal(%{host: actor_host} = _actor_info, object) do
|
||||||
defp check_ftl_removal(%{host: actor_host} = actor_info, object)
|
|
||||||
when actor_host in @ftl_removal do
|
|
||||||
user = User.get_by_ap_id(object["actor"])
|
|
||||||
|
|
||||||
# flip to/cc relationship to make the post unlisted
|
|
||||||
object =
|
object =
|
||||||
if "https://www.w3.org/ns/activitystreams#Public" in object["to"] and
|
with true <-
|
||||||
user.follower_address in object["cc"] do
|
Enum.member?(
|
||||||
|
Pleroma.Config.get([:mrf_simple, :federated_timeline_removal]),
|
||||||
|
actor_host
|
||||||
|
),
|
||||||
|
user <- User.get_by_ap_id(object["actor"]),
|
||||||
|
true <- "https://www.w3.org/ns/activitystreams#Public" in object["to"],
|
||||||
|
true <- user.follower_address in object["cc"] do
|
||||||
to =
|
to =
|
||||||
List.delete(object["to"], "https://www.w3.org/ns/activitystreams#Public") ++
|
List.delete(object["to"], "https://www.w3.org/ns/activitystreams#Public") ++
|
||||||
[user.follower_address]
|
[user.follower_address]
|
||||||
|
@ -68,14 +83,12 @@ defp check_ftl_removal(%{host: actor_host} = actor_info, object)
|
||||||
|> Map.put("to", to)
|
|> Map.put("to", to)
|
||||||
|> Map.put("cc", cc)
|
|> Map.put("cc", cc)
|
||||||
else
|
else
|
||||||
object
|
_ -> object
|
||||||
end
|
end
|
||||||
|
|
||||||
{:ok, object}
|
{:ok, object}
|
||||||
end
|
end
|
||||||
|
|
||||||
defp check_ftl_removal(actor_info, object), do: {:ok, object}
|
|
||||||
|
|
||||||
@impl true
|
@impl true
|
||||||
def filter(object) do
|
def filter(object) do
|
||||||
actor_info = URI.parse(object["actor"])
|
actor_info = URI.parse(object["actor"])
|
||||||
|
|
|
@ -506,9 +506,6 @@ def handle_incoming(
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
@ap_config Application.get_env(:pleroma, :activitypub)
|
|
||||||
@accept_blocks Keyword.get(@ap_config, :accept_blocks)
|
|
||||||
|
|
||||||
def handle_incoming(
|
def handle_incoming(
|
||||||
%{
|
%{
|
||||||
"type" => "Undo",
|
"type" => "Undo",
|
||||||
|
@ -517,7 +514,7 @@ def handle_incoming(
|
||||||
"id" => id
|
"id" => id
|
||||||
} = _data
|
} = _data
|
||||||
) do
|
) do
|
||||||
with true <- @accept_blocks,
|
with true <- Pleroma.Config.get([:activitypub, :accept_blocks]),
|
||||||
%User{local: true} = blocked <- User.get_cached_by_ap_id(blocked),
|
%User{local: true} = blocked <- User.get_cached_by_ap_id(blocked),
|
||||||
%User{} = blocker <- User.get_or_fetch_by_ap_id(blocker),
|
%User{} = blocker <- User.get_or_fetch_by_ap_id(blocker),
|
||||||
{:ok, activity} <- ActivityPub.unblock(blocker, blocked, id, false) do
|
{:ok, activity} <- ActivityPub.unblock(blocker, blocked, id, false) do
|
||||||
|
@ -531,7 +528,7 @@ def handle_incoming(
|
||||||
def handle_incoming(
|
def handle_incoming(
|
||||||
%{"type" => "Block", "object" => blocked, "actor" => blocker, "id" => id} = data
|
%{"type" => "Block", "object" => blocked, "actor" => blocker, "id" => id} = data
|
||||||
) do
|
) do
|
||||||
with true <- @accept_blocks,
|
with true <- Pleroma.Config.get([:activitypub, :accept_blocks]),
|
||||||
%User{local: true} = blocked = User.get_cached_by_ap_id(blocked),
|
%User{local: true} = blocked = User.get_cached_by_ap_id(blocked),
|
||||||
%User{} = blocker = User.get_or_fetch_by_ap_id(blocker),
|
%User{} = blocker = User.get_or_fetch_by_ap_id(blocker),
|
||||||
{:ok, activity} <- ActivityPub.block(blocker, blocked, id, false) do
|
{:ok, activity} <- ActivityPub.block(blocker, blocked, id, false) do
|
||||||
|
|
|
@ -70,15 +70,17 @@ def get_visibility(%{"in_reply_to_status_id" => status_id}) when not is_nil(stat
|
||||||
|
|
||||||
def get_visibility(_), do: "public"
|
def get_visibility(_), do: "public"
|
||||||
|
|
||||||
@instance Application.get_env(:pleroma, :instance)
|
defp get_content_type(content_type) do
|
||||||
@allowed_post_formats Keyword.get(@instance, :allowed_post_formats)
|
if Enum.member?(Pleroma.Config.get([:instance, :allowed_post_formats]), content_type) do
|
||||||
|
content_type
|
||||||
|
else
|
||||||
|
"text/plain"
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
defp get_content_type(content_type) when content_type in @allowed_post_formats, do: content_type
|
|
||||||
defp get_content_type(_), do: "text/plain"
|
|
||||||
|
|
||||||
@limit Keyword.get(@instance, :limit)
|
|
||||||
def post(user, %{"status" => status} = data) do
|
def post(user, %{"status" => status} = data) do
|
||||||
visibility = get_visibility(data)
|
visibility = get_visibility(data)
|
||||||
|
limit = Pleroma.Config.get([:instance, :limit])
|
||||||
|
|
||||||
with status <- String.trim(status),
|
with status <- String.trim(status),
|
||||||
attachments <- attachments_from_ids(data["media_ids"]),
|
attachments <- attachments_from_ids(data["media_ids"]),
|
||||||
|
@ -98,7 +100,7 @@ def post(user, %{"status" => status} = data) do
|
||||||
context <- make_context(inReplyTo),
|
context <- make_context(inReplyTo),
|
||||||
cw <- data["spoiler_text"],
|
cw <- data["spoiler_text"],
|
||||||
full_payload <- String.trim(status <> (data["spoiler_text"] || "")),
|
full_payload <- String.trim(status <> (data["spoiler_text"] || "")),
|
||||||
length when length in 1..@limit <- String.length(full_payload),
|
length when length in 1..limit <- String.length(full_payload),
|
||||||
object <-
|
object <-
|
||||||
make_note_data(
|
make_note_data(
|
||||||
user.ap_id,
|
user.ap_id,
|
||||||
|
|
|
@ -12,8 +12,6 @@ defmodule Pleroma.Web.Federator do
|
||||||
@websub Application.get_env(:pleroma, :websub)
|
@websub Application.get_env(:pleroma, :websub)
|
||||||
@ostatus Application.get_env(:pleroma, :ostatus)
|
@ostatus Application.get_env(:pleroma, :ostatus)
|
||||||
@httpoison Application.get_env(:pleroma, :httpoison)
|
@httpoison Application.get_env(:pleroma, :httpoison)
|
||||||
@instance Application.get_env(:pleroma, :instance)
|
|
||||||
@federating Keyword.get(@instance, :federating)
|
|
||||||
@max_jobs 20
|
@max_jobs 20
|
||||||
|
|
||||||
def init(args) do
|
def init(args) do
|
||||||
|
@ -147,7 +145,7 @@ def handle(type, _) do
|
||||||
end
|
end
|
||||||
|
|
||||||
def enqueue(type, payload, priority \\ 1) do
|
def enqueue(type, payload, priority \\ 1) do
|
||||||
if @federating do
|
if Pleroma.Config.get([:instance, :federating]) do
|
||||||
if Mix.env() == :test do
|
if Mix.env() == :test do
|
||||||
handle(type, payload)
|
handle(type, payload)
|
||||||
else
|
else
|
||||||
|
|
|
@ -132,22 +132,23 @@ def user(%{assigns: %{user: for_user}} = conn, %{"id" => id}) do
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
@instance Application.get_env(:pleroma, :instance)
|
|
||||||
@mastodon_api_level "2.5.0"
|
@mastodon_api_level "2.5.0"
|
||||||
|
|
||||||
def masto_instance(conn, _params) do
|
def masto_instance(conn, _params) do
|
||||||
|
instance = Pleroma.Config.get(:instance)
|
||||||
|
|
||||||
response = %{
|
response = %{
|
||||||
uri: Web.base_url(),
|
uri: Web.base_url(),
|
||||||
title: Keyword.get(@instance, :name),
|
title: Keyword.get(instance, :name),
|
||||||
description: Keyword.get(@instance, :description),
|
description: Keyword.get(instance, :description),
|
||||||
version: "#{@mastodon_api_level} (compatible; #{Keyword.get(@instance, :version)})",
|
version: "#{@mastodon_api_level} (compatible; #{Keyword.get(instance, :version)})",
|
||||||
email: Keyword.get(@instance, :email),
|
email: Keyword.get(instance, :email),
|
||||||
urls: %{
|
urls: %{
|
||||||
streaming_api: String.replace(Pleroma.Web.Endpoint.static_url(), "http", "ws")
|
streaming_api: String.replace(Pleroma.Web.Endpoint.static_url(), "http", "ws")
|
||||||
},
|
},
|
||||||
stats: Stats.get_stats(),
|
stats: Stats.get_stats(),
|
||||||
thumbnail: Web.base_url() <> "/instance/thumbnail.jpeg",
|
thumbnail: Web.base_url() <> "/instance/thumbnail.jpeg",
|
||||||
max_toot_chars: Keyword.get(@instance, :limit)
|
max_toot_chars: Keyword.get(instance, :limit)
|
||||||
}
|
}
|
||||||
|
|
||||||
json(conn, response)
|
json(conn, response)
|
||||||
|
@ -581,15 +582,16 @@ def reject_follow_request(%{assigns: %{user: followed}} = conn, %{"id" => id}) d
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
@activitypub Application.get_env(:pleroma, :activitypub)
|
|
||||||
@follow_handshake_timeout Keyword.get(@activitypub, :follow_handshake_timeout)
|
|
||||||
|
|
||||||
def follow(%{assigns: %{user: follower}} = conn, %{"id" => id}) do
|
def follow(%{assigns: %{user: follower}} = conn, %{"id" => id}) do
|
||||||
with %User{} = followed <- Repo.get(User, id),
|
with %User{} = followed <- Repo.get(User, id),
|
||||||
{:ok, follower} <- User.maybe_direct_follow(follower, followed),
|
{:ok, follower} <- User.maybe_direct_follow(follower, followed),
|
||||||
{:ok, _activity} <- ActivityPub.follow(follower, followed),
|
{:ok, _activity} <- ActivityPub.follow(follower, followed),
|
||||||
{:ok, follower, followed} <-
|
{:ok, follower, followed} <-
|
||||||
User.wait_and_refresh(@follow_handshake_timeout, follower, followed) do
|
User.wait_and_refresh(
|
||||||
|
Pleroma.Config.get([:activitypub, :follow_handshake_timeout]),
|
||||||
|
follower,
|
||||||
|
followed
|
||||||
|
) do
|
||||||
render(conn, AccountView, "relationship.json", %{user: follower, target: followed})
|
render(conn, AccountView, "relationship.json", %{user: follower, target: followed})
|
||||||
else
|
else
|
||||||
{:error, message} ->
|
{:error, message} ->
|
||||||
|
@ -880,6 +882,8 @@ def index(%{assigns: %{user: user}} = conn, _params) do
|
||||||
if user && token do
|
if user && token do
|
||||||
mastodon_emoji = mastodonized_emoji()
|
mastodon_emoji = mastodonized_emoji()
|
||||||
|
|
||||||
|
limit = Pleroma.Config.get([:instance, :limit])
|
||||||
|
|
||||||
accounts =
|
accounts =
|
||||||
Map.put(%{}, user.id, AccountView.render("account.json", %{user: user, for: user}))
|
Map.put(%{}, user.id, AccountView.render("account.json", %{user: user, for: user}))
|
||||||
|
|
||||||
|
@ -899,7 +903,7 @@ def index(%{assigns: %{user: user}} = conn, _params) do
|
||||||
auto_play_gif: false,
|
auto_play_gif: false,
|
||||||
display_sensitive_media: false,
|
display_sensitive_media: false,
|
||||||
reduce_motion: false,
|
reduce_motion: false,
|
||||||
max_toot_chars: Keyword.get(@instance, :limit)
|
max_toot_chars: limit
|
||||||
},
|
},
|
||||||
rights: %{
|
rights: %{
|
||||||
delete_others_notice: !!user.info["is_moderator"]
|
delete_others_notice: !!user.info["is_moderator"]
|
||||||
|
@ -959,7 +963,7 @@ def index(%{assigns: %{user: user}} = conn, _params) do
|
||||||
push_subscription: nil,
|
push_subscription: nil,
|
||||||
accounts: accounts,
|
accounts: accounts,
|
||||||
custom_emojis: mastodon_emoji,
|
custom_emojis: mastodon_emoji,
|
||||||
char_limit: Keyword.get(@instance, :limit)
|
char_limit: limit
|
||||||
}
|
}
|
||||||
|> Jason.encode!()
|
|> Jason.encode!()
|
||||||
|
|
||||||
|
@ -1165,18 +1169,15 @@ def errors(conn, _) do
|
||||||
|> json("Something went wrong")
|
|> json("Something went wrong")
|
||||||
end
|
end
|
||||||
|
|
||||||
@suggestions Application.get_env(:pleroma, :suggestions)
|
|
||||||
|
|
||||||
def suggestions(%{assigns: %{user: user}} = conn, _) do
|
def suggestions(%{assigns: %{user: user}} = conn, _) do
|
||||||
if Keyword.get(@suggestions, :enabled, false) do
|
suggestions = Pleroma.Config.get(:suggestions)
|
||||||
api = Keyword.get(@suggestions, :third_party_engine, "")
|
|
||||||
timeout = Keyword.get(@suggestions, :timeout, 5000)
|
|
||||||
limit = Keyword.get(@suggestions, :limit, 23)
|
|
||||||
|
|
||||||
host =
|
if Keyword.get(suggestions, :enabled, false) do
|
||||||
Application.get_env(:pleroma, Pleroma.Web.Endpoint)
|
api = Keyword.get(suggestions, :third_party_engine, "")
|
||||||
|> Keyword.get(:url)
|
timeout = Keyword.get(suggestions, :timeout, 5000)
|
||||||
|> Keyword.get(:host)
|
limit = Keyword.get(suggestions, :limit, 23)
|
||||||
|
|
||||||
|
host = Pleroma.Config.get([Pleroma.Web.Endpoint, :url, :host])
|
||||||
|
|
||||||
user = user.nickname
|
user = user.nickname
|
||||||
url = String.replace(api, "{{host}}", host) |> String.replace("{{user}}", user)
|
url = String.replace(api, "{{host}}", host) |> String.replace("{{user}}", user)
|
||||||
|
|
|
@ -134,19 +134,20 @@ def do_remote_follow(%{assigns: %{user: user}} = conn, %{"user" => %{"id" => id}
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
@instance Application.get_env(:pleroma, :instance)
|
|
||||||
@instance_fe Application.get_env(:pleroma, :fe)
|
|
||||||
@instance_chat Application.get_env(:pleroma, :chat)
|
|
||||||
def config(conn, _params) do
|
def config(conn, _params) do
|
||||||
|
instance = Pleroma.Config.get(:instance)
|
||||||
|
instance_fe = Pleroma.Config.get(:fe)
|
||||||
|
instance_chat = Pleroma.Config.get(:chat)
|
||||||
|
|
||||||
case get_format(conn) do
|
case get_format(conn) do
|
||||||
"xml" ->
|
"xml" ->
|
||||||
response = """
|
response = """
|
||||||
<config>
|
<config>
|
||||||
<site>
|
<site>
|
||||||
<name>#{Keyword.get(@instance, :name)}</name>
|
<name>#{Keyword.get(instance, :name)}</name>
|
||||||
<site>#{Web.base_url()}</site>
|
<site>#{Web.base_url()}</site>
|
||||||
<textlimit>#{Keyword.get(@instance, :limit)}</textlimit>
|
<textlimit>#{Keyword.get(instance, :limit)}</textlimit>
|
||||||
<closed>#{!Keyword.get(@instance, :registrations_open)}</closed>
|
<closed>#{!Keyword.get(instance, :registrations_open)}</closed>
|
||||||
</site>
|
</site>
|
||||||
</config>
|
</config>
|
||||||
"""
|
"""
|
||||||
|
@ -157,32 +158,32 @@ def config(conn, _params) do
|
||||||
|
|
||||||
_ ->
|
_ ->
|
||||||
data = %{
|
data = %{
|
||||||
name: Keyword.get(@instance, :name),
|
name: Keyword.get(instance, :name),
|
||||||
description: Keyword.get(@instance, :description),
|
description: Keyword.get(instance, :description),
|
||||||
server: Web.base_url(),
|
server: Web.base_url(),
|
||||||
textlimit: to_string(Keyword.get(@instance, :limit)),
|
textlimit: to_string(Keyword.get(instance, :limit)),
|
||||||
closed: if(Keyword.get(@instance, :registrations_open), do: "0", else: "1"),
|
closed: if(Keyword.get(instance, :registrations_open), do: "0", else: "1"),
|
||||||
private: if(Keyword.get(@instance, :public, true), do: "0", else: "1")
|
private: if(Keyword.get(instance, :public, true), do: "0", else: "1")
|
||||||
}
|
}
|
||||||
|
|
||||||
pleroma_fe = %{
|
pleroma_fe = %{
|
||||||
theme: Keyword.get(@instance_fe, :theme),
|
theme: Keyword.get(instance_fe, :theme),
|
||||||
background: Keyword.get(@instance_fe, :background),
|
background: Keyword.get(instance_fe, :background),
|
||||||
logo: Keyword.get(@instance_fe, :logo),
|
logo: Keyword.get(instance_fe, :logo),
|
||||||
logoMask: Keyword.get(@instance_fe, :logo_mask),
|
logoMask: Keyword.get(instance_fe, :logo_mask),
|
||||||
logoMargin: Keyword.get(@instance_fe, :logo_margin),
|
logoMargin: Keyword.get(instance_fe, :logo_margin),
|
||||||
redirectRootNoLogin: Keyword.get(@instance_fe, :redirect_root_no_login),
|
redirectRootNoLogin: Keyword.get(instance_fe, :redirect_root_no_login),
|
||||||
redirectRootLogin: Keyword.get(@instance_fe, :redirect_root_login),
|
redirectRootLogin: Keyword.get(instance_fe, :redirect_root_login),
|
||||||
chatDisabled: !Keyword.get(@instance_chat, :enabled),
|
chatDisabled: !Keyword.get(instance_chat, :enabled),
|
||||||
showInstanceSpecificPanel: Keyword.get(@instance_fe, :show_instance_panel),
|
showInstanceSpecificPanel: Keyword.get(instance_fe, :show_instance_panel),
|
||||||
scopeOptionsEnabled: Keyword.get(@instance_fe, :scope_options_enabled),
|
scopeOptionsEnabled: Keyword.get(instance_fe, :scope_options_enabled),
|
||||||
formattingOptionsEnabled: Keyword.get(@instance_fe, :formatting_options_enabled),
|
formattingOptionsEnabled: Keyword.get(instance_fe, :formatting_options_enabled),
|
||||||
collapseMessageWithSubject: Keyword.get(@instance_fe, :collapse_message_with_subject),
|
collapseMessageWithSubject: Keyword.get(instance_fe, :collapse_message_with_subject),
|
||||||
hidePostStats: Keyword.get(@instance_fe, :hide_post_stats),
|
hidePostStats: Keyword.get(instance_fe, :hide_post_stats),
|
||||||
hideUserStats: Keyword.get(@instance_fe, :hide_user_stats)
|
hideUserStats: Keyword.get(instance_fe, :hide_user_stats)
|
||||||
}
|
}
|
||||||
|
|
||||||
managed_config = Keyword.get(@instance, :managed_config)
|
managed_config = Keyword.get(instance, :managed_config)
|
||||||
|
|
||||||
data =
|
data =
|
||||||
if managed_config do
|
if managed_config do
|
||||||
|
@ -196,7 +197,7 @@ def config(conn, _params) do
|
||||||
end
|
end
|
||||||
|
|
||||||
def version(conn, _params) do
|
def version(conn, _params) do
|
||||||
version = Keyword.get(@instance, :version)
|
version = Pleroma.Config.get([:instance, :version])
|
||||||
|
|
||||||
case get_format(conn) do
|
case get_format(conn) do
|
||||||
"xml" ->
|
"xml" ->
|
||||||
|
|
|
@ -6,9 +6,7 @@ defmodule Pleroma.Web.TwitterAPI.TwitterAPI do
|
||||||
alias Pleroma.Web.MediaProxy
|
alias Pleroma.Web.MediaProxy
|
||||||
import Ecto.Query
|
import Ecto.Query
|
||||||
|
|
||||||
@instance Application.get_env(:pleroma, :instance)
|
|
||||||
@httpoison Application.get_env(:pleroma, :httpoison)
|
@httpoison Application.get_env(:pleroma, :httpoison)
|
||||||
@registrations_open Keyword.get(@instance, :registrations_open)
|
|
||||||
|
|
||||||
def create_status(%User{} = user, %{"status" => _} = data) do
|
def create_status(%User{} = user, %{"status" => _} = data) do
|
||||||
CommonAPI.post(user, data)
|
CommonAPI.post(user, data)
|
||||||
|
@ -21,15 +19,16 @@ def delete(%User{} = user, id) do
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
@activitypub Application.get_env(:pleroma, :activitypub)
|
|
||||||
@follow_handshake_timeout Keyword.get(@activitypub, :follow_handshake_timeout)
|
|
||||||
|
|
||||||
def follow(%User{} = follower, params) do
|
def follow(%User{} = follower, params) do
|
||||||
with {:ok, %User{} = followed} <- get_user(params),
|
with {:ok, %User{} = followed} <- get_user(params),
|
||||||
{:ok, follower} <- User.maybe_direct_follow(follower, followed),
|
{:ok, follower} <- User.maybe_direct_follow(follower, followed),
|
||||||
{:ok, activity} <- ActivityPub.follow(follower, followed),
|
{:ok, activity} <- ActivityPub.follow(follower, followed),
|
||||||
{:ok, follower, followed} <-
|
{:ok, follower, followed} <-
|
||||||
User.wait_and_refresh(@follow_handshake_timeout, follower, followed) do
|
User.wait_and_refresh(
|
||||||
|
Pleroma.Config.get([:activitypub, :follow_handshake_timeout]),
|
||||||
|
follower,
|
||||||
|
followed
|
||||||
|
) do
|
||||||
{:ok, follower, followed, activity}
|
{:ok, follower, followed, activity}
|
||||||
else
|
else
|
||||||
err -> err
|
err -> err
|
||||||
|
@ -139,18 +138,20 @@ def register_user(params) do
|
||||||
password_confirmation: params["confirm"]
|
password_confirmation: params["confirm"]
|
||||||
}
|
}
|
||||||
|
|
||||||
|
registrations_open = Pleroma.Config.get([:instance, :registrations_open])
|
||||||
|
|
||||||
# no need to query DB if registration is open
|
# no need to query DB if registration is open
|
||||||
token =
|
token =
|
||||||
unless @registrations_open || is_nil(tokenString) do
|
unless registrations_open || is_nil(tokenString) do
|
||||||
Repo.get_by(UserInviteToken, %{token: tokenString})
|
Repo.get_by(UserInviteToken, %{token: tokenString})
|
||||||
end
|
end
|
||||||
|
|
||||||
cond do
|
cond do
|
||||||
@registrations_open || (!is_nil(token) && !token.used) ->
|
registrations_open || (!is_nil(token) && !token.used) ->
|
||||||
changeset = User.register_changeset(%User{}, params)
|
changeset = User.register_changeset(%User{}, params)
|
||||||
|
|
||||||
with {:ok, user} <- Repo.insert(changeset) do
|
with {:ok, user} <- Repo.insert(changeset) do
|
||||||
!@registrations_open && UserInviteToken.mark_as_used(token.token)
|
!registrations_open && UserInviteToken.mark_as_used(token.token)
|
||||||
{:ok, user}
|
{:ok, user}
|
||||||
else
|
else
|
||||||
{:error, changeset} ->
|
{:error, changeset} ->
|
||||||
|
@ -161,10 +162,10 @@ def register_user(params) do
|
||||||
{:error, %{error: errors}}
|
{:error, %{error: errors}}
|
||||||
end
|
end
|
||||||
|
|
||||||
!@registrations_open && is_nil(token) ->
|
!registrations_open && is_nil(token) ->
|
||||||
{:error, "Invalid token"}
|
{:error, "Invalid token"}
|
||||||
|
|
||||||
!@registrations_open && token.used ->
|
!registrations_open && token.used ->
|
||||||
{:error, "Expired token"}
|
{:error, "Expired token"}
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -4,6 +4,7 @@ defmodule Pleroma.ConfigTest do
|
||||||
test "get/1 with an atom" do
|
test "get/1 with an atom" do
|
||||||
assert Pleroma.Config.get(:instance) == Application.get_env(:pleroma, :instance)
|
assert Pleroma.Config.get(:instance) == Application.get_env(:pleroma, :instance)
|
||||||
assert Pleroma.Config.get(:azertyuiop) == nil
|
assert Pleroma.Config.get(:azertyuiop) == nil
|
||||||
|
assert Pleroma.Config.get(:azertyuiop, true) == true
|
||||||
end
|
end
|
||||||
|
|
||||||
test "get/1 with a list of keys" do
|
test "get/1 with a list of keys" do
|
||||||
|
@ -20,6 +21,22 @@ test "get/1 with a list of keys" do
|
||||||
)
|
)
|
||||||
|
|
||||||
assert Pleroma.Config.get([:azerty, :uiop]) == nil
|
assert Pleroma.Config.get([:azerty, :uiop]) == nil
|
||||||
|
assert Pleroma.Config.get([:azerty, :uiop], true) == true
|
||||||
|
end
|
||||||
|
|
||||||
|
test "get!/1" do
|
||||||
|
assert Pleroma.Config.get!(:instance) == Application.get_env(:pleroma, :instance)
|
||||||
|
|
||||||
|
assert Pleroma.Config.get!([:instance, :public]) ==
|
||||||
|
Keyword.get(Application.get_env(:pleroma, :instance), :public)
|
||||||
|
|
||||||
|
assert_raise(Pleroma.Config.Error, fn ->
|
||||||
|
Pleroma.Config.get!(:azertyuiop)
|
||||||
|
end)
|
||||||
|
|
||||||
|
assert_raise(Pleroma.Config.Error, fn ->
|
||||||
|
Pleroma.Config.get!([:azerty, :uiop])
|
||||||
|
end)
|
||||||
end
|
end
|
||||||
|
|
||||||
test "put/2 with a key" do
|
test "put/2 with a key" do
|
||||||
|
|
Loading…
Reference in New Issue