aboutsummaryrefslogtreecommitdiff
path: root/lib
diff options
context:
space:
mode:
authorMark Felder <feld@FreeBSD.org>2020-07-15 09:30:23 -0500
committerMark Felder <feld@FreeBSD.org>2020-07-15 09:30:23 -0500
commit9d30bacaceaaec9fe2a7993b55149faef3516846 (patch)
treed26ede9f244a11c7de36589cbf034bb2caf886a3 /lib
parent80c21100db306ce45856bbdb97d3439676babeeb (diff)
parent0fe36b311c010f9a4bd3c1600ce874c5403a7368 (diff)
downloadpleroma-9d30bacaceaaec9fe2a7993b55149faef3516846.tar.gz
Merge branch 'develop' into refactor/notification_settings
Diffstat (limited to 'lib')
-rw-r--r--lib/pleroma/application.ex4
-rw-r--r--lib/pleroma/config/deprecation_warnings.ex15
-rw-r--r--lib/pleroma/plugs/admin_secret_authentication_plug.ex27
-rw-r--r--lib/pleroma/plugs/http_security_plug.ex47
-rw-r--r--lib/pleroma/plugs/user_is_admin_plug.ex25
-rw-r--r--lib/pleroma/web/activity_pub/mrf/anti_followbot_policy.ex2
-rw-r--r--lib/pleroma/web/activity_pub/mrf/anti_link_spam_policy.ex7
-rw-r--r--lib/pleroma/web/activity_pub/mrf/hellthread_policy.ex4
-rw-r--r--lib/pleroma/web/activity_pub/mrf/keyword_policy.ex7
-rw-r--r--lib/pleroma/web/activity_pub/mrf/mention_policy.ex5
-rw-r--r--lib/pleroma/web/activity_pub/mrf/object_age_policy.ex8
-rw-r--r--lib/pleroma/web/activity_pub/mrf/reject_non_public.ex2
-rw-r--r--lib/pleroma/web/activity_pub/mrf/simple_policy.ex16
-rw-r--r--lib/pleroma/web/activity_pub/mrf/tag_policy.ex7
-rw-r--r--lib/pleroma/web/activity_pub/mrf/user_allow_list_policy.ex2
-rw-r--r--lib/pleroma/web/activity_pub/mrf/vocabulary_policy.ex18
-rw-r--r--lib/pleroma/web/activity_pub/publisher.ex20
-rw-r--r--lib/pleroma/web/activity_pub/transmogrifier.ex12
-rw-r--r--lib/pleroma/web/api_spec/helpers.ex4
-rw-r--r--lib/pleroma/web/api_spec/operations/admin/config_operation.ex3
-rw-r--r--lib/pleroma/web/api_spec/operations/admin/invite_operation.ex4
-rw-r--r--lib/pleroma/web/api_spec/operations/admin/media_proxy_cache_operation.ex3
-rw-r--r--lib/pleroma/web/api_spec/operations/admin/oauth_app_operation.ex6
-rw-r--r--lib/pleroma/web/api_spec/operations/admin/relay_operation.ex3
-rw-r--r--lib/pleroma/web/api_spec/operations/admin/report_operation.ex7
-rw-r--r--lib/pleroma/web/api_spec/operations/admin/status_operation.ex7
-rw-r--r--lib/pleroma/web/mastodon_api/controllers/status_controller.ex5
-rw-r--r--lib/pleroma/web/media_proxy/media_proxy.ex26
28 files changed, 191 insertions, 105 deletions
diff --git a/lib/pleroma/application.ex b/lib/pleroma/application.ex
index b68a373a4..3282c6882 100644
--- a/lib/pleroma/application.ex
+++ b/lib/pleroma/application.ex
@@ -35,6 +35,10 @@ defmodule Pleroma.Application do
# See http://elixir-lang.org/docs/stable/elixir/Application.html
# for more information on OTP Applications
def start(_type, _args) do
+ # Scrubbers are compiled at runtime and therefore will cause a conflict
+ # every time the application is restarted, so we disable module
+ # conflicts at runtime
+ Code.compiler_options(ignore_module_conflict: true)
Config.Holder.save_default()
Pleroma.HTML.compile_scrubbers()
Config.DeprecationWarnings.warn()
diff --git a/lib/pleroma/config/deprecation_warnings.ex b/lib/pleroma/config/deprecation_warnings.ex
index 0a6c724fb..026871c4f 100644
--- a/lib/pleroma/config/deprecation_warnings.ex
+++ b/lib/pleroma/config/deprecation_warnings.ex
@@ -54,6 +54,7 @@ defmodule Pleroma.Config.DeprecationWarnings do
check_hellthread_threshold()
mrf_user_allowlist()
check_old_mrf_config()
+ check_media_proxy_whitelist_config()
end
def check_old_mrf_config do
@@ -65,7 +66,7 @@ defmodule Pleroma.Config.DeprecationWarnings do
move_namespace_and_warn(@mrf_config_map, warning_preface)
end
- @spec move_namespace_and_warn([config_map()], String.t()) :: :ok
+ @spec move_namespace_and_warn([config_map()], String.t()) :: :ok | nil
def move_namespace_and_warn(config_map, warning_preface) do
warning =
Enum.reduce(config_map, "", fn
@@ -84,4 +85,16 @@ defmodule Pleroma.Config.DeprecationWarnings do
Logger.warn(warning_preface <> warning)
end
end
+
+ @spec check_media_proxy_whitelist_config() :: :ok | nil
+ def check_media_proxy_whitelist_config do
+ whitelist = Config.get([:media_proxy, :whitelist])
+
+ if Enum.any?(whitelist, &(not String.starts_with?(&1, "http"))) do
+ Logger.warn("""
+ !!!DEPRECATION WARNING!!!
+ Your config is using old format (only domain) for MediaProxy whitelist option. Setting should work for now, but you are advised to change format to scheme with port to prevent possible issues later.
+ """)
+ end
+ end
end
diff --git a/lib/pleroma/plugs/admin_secret_authentication_plug.ex b/lib/pleroma/plugs/admin_secret_authentication_plug.ex
index b4b47a31f..2e54df47a 100644
--- a/lib/pleroma/plugs/admin_secret_authentication_plug.ex
+++ b/lib/pleroma/plugs/admin_secret_authentication_plug.ex
@@ -4,6 +4,9 @@
defmodule Pleroma.Plugs.AdminSecretAuthenticationPlug do
import Plug.Conn
+
+ alias Pleroma.Plugs.OAuthScopesPlug
+ alias Pleroma.Plugs.RateLimiter
alias Pleroma.User
def init(options) do
@@ -11,7 +14,10 @@ defmodule Pleroma.Plugs.AdminSecretAuthenticationPlug do
end
def secret_token do
- Pleroma.Config.get(:admin_token)
+ case Pleroma.Config.get(:admin_token) do
+ blank when blank in [nil, ""] -> nil
+ token -> token
+ end
end
def call(%{assigns: %{user: %User{}}} = conn, _), do: conn
@@ -26,9 +32,9 @@ defmodule Pleroma.Plugs.AdminSecretAuthenticationPlug do
def authenticate(%{params: %{"admin_token" => admin_token}} = conn) do
if admin_token == secret_token() do
- assign(conn, :user, %User{is_admin: true})
+ assign_admin_user(conn)
else
- conn
+ handle_bad_token(conn)
end
end
@@ -36,8 +42,19 @@ defmodule Pleroma.Plugs.AdminSecretAuthenticationPlug do
token = secret_token()
case get_req_header(conn, "x-admin-token") do
- [^token] -> assign(conn, :user, %User{is_admin: true})
- _ -> conn
+ blank when blank in [[], [""]] -> conn
+ [^token] -> assign_admin_user(conn)
+ _ -> handle_bad_token(conn)
end
end
+
+ defp assign_admin_user(conn) do
+ conn
+ |> assign(:user, %User{is_admin: true})
+ |> OAuthScopesPlug.skip_plug()
+ end
+
+ defp handle_bad_token(conn) do
+ RateLimiter.call(conn, name: :authentication)
+ end
end
diff --git a/lib/pleroma/plugs/http_security_plug.ex b/lib/pleroma/plugs/http_security_plug.ex
index 7d65cf078..c363b193b 100644
--- a/lib/pleroma/plugs/http_security_plug.ex
+++ b/lib/pleroma/plugs/http_security_plug.ex
@@ -108,31 +108,48 @@ defmodule Pleroma.Plugs.HTTPSecurityPlug do
|> :erlang.iolist_to_binary()
end
- defp build_csp_multimedia_source_list do
- media_proxy_whitelist =
- Enum.reduce(Config.get([:media_proxy, :whitelist]), [], fn host, acc ->
- add_source(acc, host)
- end)
+ defp build_csp_from_whitelist([], acc), do: acc
- media_proxy_base_url = build_csp_param(Config.get([:media_proxy, :base_url]))
+ defp build_csp_from_whitelist([last], acc) do
+ [build_csp_param_from_whitelist(last) | acc]
+ end
- upload_base_url = build_csp_param(Config.get([Pleroma.Upload, :base_url]))
+ defp build_csp_from_whitelist([head | tail], acc) do
+ build_csp_from_whitelist(tail, [[?\s, build_csp_param_from_whitelist(head)] | acc])
+ end
- s3_endpoint = build_csp_param(Config.get([Pleroma.Uploaders.S3, :public_endpoint]))
+ # TODO: use `build_csp_param/1` after removing support bare domains for media proxy whitelist
+ defp build_csp_param_from_whitelist("http" <> _ = url) do
+ build_csp_param(url)
+ end
- captcha_method = Config.get([Pleroma.Captcha, :method])
+ defp build_csp_param_from_whitelist(url), do: url
- captcha_endpoint = build_csp_param(Config.get([captcha_method, :endpoint]))
+ defp build_csp_multimedia_source_list do
+ media_proxy_whitelist =
+ [:media_proxy, :whitelist]
+ |> Config.get()
+ |> build_csp_from_whitelist([])
- []
- |> add_source(media_proxy_base_url)
- |> add_source(upload_base_url)
- |> add_source(s3_endpoint)
+ captcha_method = Config.get([Pleroma.Captcha, :method])
+ captcha_endpoint = Config.get([captcha_method, :endpoint])
+
+ base_endpoints =
+ [
+ [:media_proxy, :base_url],
+ [Pleroma.Upload, :base_url],
+ [Pleroma.Uploaders.S3, :public_endpoint]
+ ]
+ |> Enum.map(&Config.get/1)
+
+ [captcha_endpoint | base_endpoints]
+ |> Enum.map(&build_csp_param/1)
+ |> Enum.reduce([], &add_source(&2, &1))
|> add_source(media_proxy_whitelist)
- |> add_source(captcha_endpoint)
end
defp add_source(iodata, nil), do: iodata
+ defp add_source(iodata, []), do: iodata
defp add_source(iodata, source), do: [[?\s, source] | iodata]
defp add_csp_param(csp_iodata, nil), do: csp_iodata
diff --git a/lib/pleroma/plugs/user_is_admin_plug.ex b/lib/pleroma/plugs/user_is_admin_plug.ex
index 2748102df..488a61d1d 100644
--- a/lib/pleroma/plugs/user_is_admin_plug.ex
+++ b/lib/pleroma/plugs/user_is_admin_plug.ex
@@ -7,37 +7,18 @@ defmodule Pleroma.Plugs.UserIsAdminPlug do
import Plug.Conn
alias Pleroma.User
- alias Pleroma.Web.OAuth
def init(options) do
options
end
- def call(%{assigns: %{user: %User{is_admin: true}} = assigns} = conn, _) do
- token = assigns[:token]
-
- cond do
- not Pleroma.Config.enforce_oauth_admin_scope_usage?() ->
- conn
-
- token && OAuth.Scopes.contains_admin_scopes?(token.scopes) ->
- # Note: checking for _any_ admin scope presence, not necessarily fitting requested action.
- # Thus, controller must explicitly invoke OAuthScopesPlug to verify scope requirements.
- # Admin might opt out of admin scope for some apps to block any admin actions from them.
- conn
-
- true ->
- fail(conn)
- end
+ def call(%{assigns: %{user: %User{is_admin: true}}} = conn, _) do
+ conn
end
def call(conn, _) do
- fail(conn)
- end
-
- defp fail(conn) do
conn
- |> render_error(:forbidden, "User is not an admin or OAuth admin scope is not granted.")
+ |> render_error(:forbidden, "User is not an admin.")
|> halt()
end
end
diff --git a/lib/pleroma/web/activity_pub/mrf/anti_followbot_policy.ex b/lib/pleroma/web/activity_pub/mrf/anti_followbot_policy.ex
index 0270b96ae..b96388489 100644
--- a/lib/pleroma/web/activity_pub/mrf/anti_followbot_policy.ex
+++ b/lib/pleroma/web/activity_pub/mrf/anti_followbot_policy.ex
@@ -60,7 +60,7 @@ defmodule Pleroma.Web.ActivityPub.MRF.AntiFollowbotPolicy do
if score < 0.8 do
{:ok, message}
else
- {:reject, nil}
+ {:reject, "[AntiFollowbotPolicy] Scored #{actor_id} as #{score}"}
end
end
diff --git a/lib/pleroma/web/activity_pub/mrf/anti_link_spam_policy.ex b/lib/pleroma/web/activity_pub/mrf/anti_link_spam_policy.ex
index a7e187b5e..b22464111 100644
--- a/lib/pleroma/web/activity_pub/mrf/anti_link_spam_policy.ex
+++ b/lib/pleroma/web/activity_pub/mrf/anti_link_spam_policy.ex
@@ -39,14 +39,13 @@ defmodule Pleroma.Web.ActivityPub.MRF.AntiLinkSpamPolicy do
{:ok, message}
{:old_user, false} ->
- {:reject, nil}
+ {:reject, "[AntiLinkSpamPolicy] User has no posts nor followers"}
{:error, _} ->
- {:reject, nil}
+ {:reject, "[AntiLinkSpamPolicy] Failed to get or fetch user by ap_id"}
e ->
- Logger.warn("[MRF anti-link-spam] WTF: unhandled error #{inspect(e)}")
- {:reject, nil}
+ {:reject, "[AntiLinkSpamPolicy] Unhandled error #{inspect(e)}"}
end
end
diff --git a/lib/pleroma/web/activity_pub/mrf/hellthread_policy.ex b/lib/pleroma/web/activity_pub/mrf/hellthread_policy.ex
index f6b2c4415..9ba07b4e3 100644
--- a/lib/pleroma/web/activity_pub/mrf/hellthread_policy.ex
+++ b/lib/pleroma/web/activity_pub/mrf/hellthread_policy.ex
@@ -43,7 +43,7 @@ defmodule Pleroma.Web.ActivityPub.MRF.HellthreadPolicy do
defp reject_message(message, threshold) when threshold > 0 do
with {_, recipients} <- get_recipient_count(message) do
if recipients > threshold do
- {:reject, nil}
+ {:reject, "[HellthreadPolicy] #{recipients} recipients is over the limit of #{threshold}"}
else
{:ok, message}
end
@@ -87,7 +87,7 @@ defmodule Pleroma.Web.ActivityPub.MRF.HellthreadPolicy do
{:ok, message} <- delist_message(message, delist_threshold) do
{:ok, message}
else
- _e -> {:reject, nil}
+ e -> e
end
end
diff --git a/lib/pleroma/web/activity_pub/mrf/keyword_policy.ex b/lib/pleroma/web/activity_pub/mrf/keyword_policy.ex
index 88b0d2b39..15e09dcf0 100644
--- a/lib/pleroma/web/activity_pub/mrf/keyword_policy.ex
+++ b/lib/pleroma/web/activity_pub/mrf/keyword_policy.ex
@@ -24,7 +24,7 @@ defmodule Pleroma.Web.ActivityPub.MRF.KeywordPolicy do
if Enum.any?(Pleroma.Config.get([:mrf_keyword, :reject]), fn pattern ->
string_matches?(content, pattern) or string_matches?(summary, pattern)
end) do
- {:reject, nil}
+ {:reject, "[KeywordPolicy] Matches with rejected keyword"}
else
{:ok, message}
end
@@ -89,8 +89,9 @@ defmodule Pleroma.Web.ActivityPub.MRF.KeywordPolicy do
{:ok, message} <- check_replace(message) do
{:ok, message}
else
- _e ->
- {:reject, nil}
+ {:reject, nil} -> {:reject, "[KeywordPolicy] "}
+ {:reject, _} = e -> e
+ _e -> {:reject, "[KeywordPolicy] "}
end
end
diff --git a/lib/pleroma/web/activity_pub/mrf/mention_policy.ex b/lib/pleroma/web/activity_pub/mrf/mention_policy.ex
index 06f003921..7910ca131 100644
--- a/lib/pleroma/web/activity_pub/mrf/mention_policy.ex
+++ b/lib/pleroma/web/activity_pub/mrf/mention_policy.ex
@@ -12,8 +12,9 @@ defmodule Pleroma.Web.ActivityPub.MRF.MentionPolicy do
reject_actors = Pleroma.Config.get([:mrf_mention, :actors], [])
recipients = (message["to"] || []) ++ (message["cc"] || [])
- if Enum.any?(recipients, fn recipient -> Enum.member?(reject_actors, recipient) end) do
- {:reject, nil}
+ if rejected_mention =
+ Enum.find(recipients, fn recipient -> Enum.member?(reject_actors, recipient) end) do
+ {:reject, "[MentionPolicy] Rejected for mention of #{rejected_mention}"}
else
{:ok, message}
end
diff --git a/lib/pleroma/web/activity_pub/mrf/object_age_policy.ex b/lib/pleroma/web/activity_pub/mrf/object_age_policy.ex
index a62914135..5f111c72f 100644
--- a/lib/pleroma/web/activity_pub/mrf/object_age_policy.ex
+++ b/lib/pleroma/web/activity_pub/mrf/object_age_policy.ex
@@ -28,7 +28,7 @@ defmodule Pleroma.Web.ActivityPub.MRF.ObjectAgePolicy do
defp check_reject(message, actions) do
if :reject in actions do
- {:reject, nil}
+ {:reject, "[ObjectAgePolicy]"}
else
{:ok, message}
end
@@ -47,9 +47,8 @@ defmodule Pleroma.Web.ActivityPub.MRF.ObjectAgePolicy do
{:ok, message}
else
- # Unhandleable error: somebody is messing around, just drop the message.
_e ->
- {:reject, nil}
+ {:reject, "[ObjectAgePolicy] Unhandled error"}
end
else
{:ok, message}
@@ -69,9 +68,8 @@ defmodule Pleroma.Web.ActivityPub.MRF.ObjectAgePolicy do
{:ok, message}
else
- # Unhandleable error: somebody is messing around, just drop the message.
_e ->
- {:reject, nil}
+ {:reject, "[ObjectAgePolicy] Unhandled error"}
end
else
{:ok, message}
diff --git a/lib/pleroma/web/activity_pub/mrf/reject_non_public.ex b/lib/pleroma/web/activity_pub/mrf/reject_non_public.ex
index 4fd63106d..0b9ed2224 100644
--- a/lib/pleroma/web/activity_pub/mrf/reject_non_public.ex
+++ b/lib/pleroma/web/activity_pub/mrf/reject_non_public.ex
@@ -38,7 +38,7 @@ defmodule Pleroma.Web.ActivityPub.MRF.RejectNonPublic do
{:ok, object}
true ->
- {:reject, nil}
+ {:reject, "[RejectNonPublic] visibility: #{visibility}"}
end
end
diff --git a/lib/pleroma/web/activity_pub/mrf/simple_policy.ex b/lib/pleroma/web/activity_pub/mrf/simple_policy.ex
index 70a2ca053..b77b8c7b4 100644
--- a/lib/pleroma/web/activity_pub/mrf/simple_policy.ex
+++ b/lib/pleroma/web/activity_pub/mrf/simple_policy.ex
@@ -21,7 +21,7 @@ defmodule Pleroma.Web.ActivityPub.MRF.SimplePolicy do
accepts == [] -> {:ok, object}
actor_host == Config.get([Pleroma.Web.Endpoint, :url, :host]) -> {:ok, object}
MRF.subdomain_match?(accepts, actor_host) -> {:ok, object}
- true -> {:reject, nil}
+ true -> {:reject, "[SimplePolicy] host not in accept list"}
end
end
@@ -31,7 +31,7 @@ defmodule Pleroma.Web.ActivityPub.MRF.SimplePolicy do
|> MRF.subdomains_regex()
if MRF.subdomain_match?(rejects, actor_host) do
- {:reject, nil}
+ {:reject, "[SimplePolicy] host in reject list"}
else
{:ok, object}
end
@@ -114,7 +114,7 @@ defmodule Pleroma.Web.ActivityPub.MRF.SimplePolicy do
|> MRF.subdomains_regex()
if MRF.subdomain_match?(report_removal, actor_host) do
- {:reject, nil}
+ {:reject, "[SimplePolicy] host in report_removal list"}
else
{:ok, object}
end
@@ -159,7 +159,7 @@ defmodule Pleroma.Web.ActivityPub.MRF.SimplePolicy do
|> MRF.subdomains_regex()
if MRF.subdomain_match?(reject_deletes, actor_host) do
- {:reject, nil}
+ {:reject, "[SimplePolicy] host in reject_deletes list"}
else
{:ok, object}
end
@@ -177,7 +177,9 @@ defmodule Pleroma.Web.ActivityPub.MRF.SimplePolicy do
{:ok, object} <- check_report_removal(actor_info, object) do
{:ok, object}
else
- _e -> {:reject, nil}
+ {:reject, nil} -> {:reject, "[SimplePolicy]"}
+ {:reject, _} = e -> e
+ _ -> {:reject, "[SimplePolicy]"}
end
end
@@ -191,7 +193,9 @@ defmodule Pleroma.Web.ActivityPub.MRF.SimplePolicy do
{:ok, object} <- check_banner_removal(actor_info, object) do
{:ok, object}
else
- _e -> {:reject, nil}
+ {:reject, nil} -> {:reject, "[SimplePolicy]"}
+ {:reject, _} = e -> e
+ _ -> {:reject, "[SimplePolicy]"}
end
end
diff --git a/lib/pleroma/web/activity_pub/mrf/tag_policy.ex b/lib/pleroma/web/activity_pub/mrf/tag_policy.ex
index c310462cb..febabda08 100644
--- a/lib/pleroma/web/activity_pub/mrf/tag_policy.ex
+++ b/lib/pleroma/web/activity_pub/mrf/tag_policy.ex
@@ -134,12 +134,13 @@ defmodule Pleroma.Web.ActivityPub.MRF.TagPolicy do
if user.local == true do
{:ok, message}
else
- {:reject, nil}
+ {:reject,
+ "[TagPolicy] Follow from #{actor} tagged with mrf_tag:disable-remote-subscription"}
end
end
- defp process_tag("mrf_tag:disable-any-subscription", %{"type" => "Follow"}),
- do: {:reject, nil}
+ defp process_tag("mrf_tag:disable-any-subscription", %{"type" => "Follow", "actor" => actor}),
+ do: {:reject, "[TagPolicy] Follow from #{actor} tagged with mrf_tag:disable-any-subscription"}
defp process_tag(_, message), do: {:ok, message}
diff --git a/lib/pleroma/web/activity_pub/mrf/user_allow_list_policy.ex b/lib/pleroma/web/activity_pub/mrf/user_allow_list_policy.ex
index 651aed70f..1a28f2ba2 100644
--- a/lib/pleroma/web/activity_pub/mrf/user_allow_list_policy.ex
+++ b/lib/pleroma/web/activity_pub/mrf/user_allow_list_policy.ex
@@ -14,7 +14,7 @@ defmodule Pleroma.Web.ActivityPub.MRF.UserAllowListPolicy do
if actor in allow_list do
{:ok, object}
else
- {:reject, nil}
+ {:reject, "[UserAllowListPolicy] #{actor} not in the list"}
end
end
diff --git a/lib/pleroma/web/activity_pub/mrf/vocabulary_policy.ex b/lib/pleroma/web/activity_pub/mrf/vocabulary_policy.ex
index 6167a74e2..a6c545570 100644
--- a/lib/pleroma/web/activity_pub/mrf/vocabulary_policy.ex
+++ b/lib/pleroma/web/activity_pub/mrf/vocabulary_policy.ex
@@ -11,22 +11,26 @@ defmodule Pleroma.Web.ActivityPub.MRF.VocabularyPolicy do
with {:ok, _} <- filter(child_message) do
{:ok, message}
else
- {:reject, nil} ->
- {:reject, nil}
+ {:reject, _} = e -> e
end
end
def filter(%{"type" => message_type} = message) do
with accepted_vocabulary <- Pleroma.Config.get([:mrf_vocabulary, :accept]),
rejected_vocabulary <- Pleroma.Config.get([:mrf_vocabulary, :reject]),
- true <-
- Enum.empty?(accepted_vocabulary) || Enum.member?(accepted_vocabulary, message_type),
- false <-
- length(rejected_vocabulary) > 0 && Enum.member?(rejected_vocabulary, message_type),
+ {_, true} <-
+ {:accepted,
+ Enum.empty?(accepted_vocabulary) || Enum.member?(accepted_vocabulary, message_type)},
+ {_, false} <-
+ {:rejected,
+ length(rejected_vocabulary) > 0 && Enum.member?(rejected_vocabulary, message_type)},
{:ok, _} <- filter(message["object"]) do
{:ok, message}
else
- _ -> {:reject, nil}
+ {:reject, _} = e -> e
+ {:accepted, _} -> {:reject, "[VocabularyPolicy] #{message_type} not in accept list"}
+ {:rejected, _} -> {:reject, "[VocabularyPolicy] #{message_type} in reject list"}
+ _ -> {:reject, "[VocabularyPolicy]"}
end
end
diff --git a/lib/pleroma/web/activity_pub/publisher.ex b/lib/pleroma/web/activity_pub/publisher.ex
index b70cbd043..d88f7f3ee 100644
--- a/lib/pleroma/web/activity_pub/publisher.ex
+++ b/lib/pleroma/web/activity_pub/publisher.ex
@@ -49,7 +49,8 @@ defmodule Pleroma.Web.ActivityPub.Publisher do
"""
def publish_one(%{inbox: inbox, json: json, actor: %User{} = actor, id: id} = params) do
Logger.debug("Federating #{id} to #{inbox}")
- %{host: host, path: path} = URI.parse(inbox)
+
+ uri = URI.parse(inbox)
digest = "SHA-256=" <> (:crypto.hash(:sha256, json) |> Base.encode64())
@@ -57,8 +58,8 @@ defmodule Pleroma.Web.ActivityPub.Publisher do
signature =
Pleroma.Signature.sign(actor, %{
- "(request-target)": "post #{path}",
- host: host,
+ "(request-target)": "post #{uri.path}",
+ host: signature_host(uri),
"content-length": byte_size(json),
digest: digest,
date: date
@@ -76,8 +77,9 @@ defmodule Pleroma.Web.ActivityPub.Publisher do
{"digest", digest}
]
) do
- if !Map.has_key?(params, :unreachable_since) || params[:unreachable_since],
- do: Instances.set_reachable(inbox)
+ if not Map.has_key?(params, :unreachable_since) || params[:unreachable_since] do
+ Instances.set_reachable(inbox)
+ end
result
else
@@ -96,6 +98,14 @@ defmodule Pleroma.Web.ActivityPub.Publisher do
|> publish_one()
end
+ defp signature_host(%URI{port: port, scheme: scheme, host: host}) do
+ if port == URI.default_port(scheme) do
+ host
+ else
+ "#{host}:#{port}"
+ end
+ end
+
defp should_federate?(inbox, public) do
if public do
true
diff --git a/lib/pleroma/web/activity_pub/transmogrifier.ex b/lib/pleroma/web/activity_pub/transmogrifier.ex
index 884646ceb..f37bcab3e 100644
--- a/lib/pleroma/web/activity_pub/transmogrifier.ex
+++ b/lib/pleroma/web/activity_pub/transmogrifier.ex
@@ -62,15 +62,17 @@ defmodule Pleroma.Web.ActivityPub.Transmogrifier do
def fix_summary(object), do: Map.put(object, "summary", "")
def fix_addressing_list(map, field) do
+ addrs = map[field]
+
cond do
- is_binary(map[field]) ->
- Map.put(map, field, [map[field]])
+ is_list(addrs) ->
+ Map.put(map, field, Enum.filter(addrs, &is_binary/1))
- is_nil(map[field]) ->
- Map.put(map, field, [])
+ is_binary(addrs) ->
+ Map.put(map, field, [addrs])
true ->
- map
+ Map.put(map, field, [])
end
end
diff --git a/lib/pleroma/web/api_spec/helpers.ex b/lib/pleroma/web/api_spec/helpers.ex
index a258e8421..2a7f1a706 100644
--- a/lib/pleroma/web/api_spec/helpers.ex
+++ b/lib/pleroma/web/api_spec/helpers.ex
@@ -29,6 +29,10 @@ defmodule Pleroma.Web.ApiSpec.Helpers do
}
end
+ def admin_api_params do
+ [Operation.parameter(:admin_token, :query, :string, "Allows authorization via admin token.")]
+ end
+
def pagination_params do
[
Operation.parameter(:max_id, :query, :string, "Return items older than this ID"),
diff --git a/lib/pleroma/web/api_spec/operations/admin/config_operation.ex b/lib/pleroma/web/api_spec/operations/admin/config_operation.ex
index 7b38a2ef4..3a8380797 100644
--- a/lib/pleroma/web/api_spec/operations/admin/config_operation.ex
+++ b/lib/pleroma/web/api_spec/operations/admin/config_operation.ex
@@ -26,6 +26,7 @@ defmodule Pleroma.Web.ApiSpec.Admin.ConfigOperation do
%Schema{type: :boolean, default: false},
"Get only saved in database settings"
)
+ | admin_api_params()
],
security: [%{"oAuth" => ["read"]}],
responses: %{
@@ -41,6 +42,7 @@ defmodule Pleroma.Web.ApiSpec.Admin.ConfigOperation do
summary: "Update config settings",
operationId: "AdminAPI.ConfigController.update",
security: [%{"oAuth" => ["write"]}],
+ parameters: admin_api_params(),
requestBody:
request_body("Parameters", %Schema{
type: :object,
@@ -73,6 +75,7 @@ defmodule Pleroma.Web.ApiSpec.Admin.ConfigOperation do
summary: "Get JSON with config descriptions.",
operationId: "AdminAPI.ConfigController.descriptions",
security: [%{"oAuth" => ["read"]}],
+ parameters: admin_api_params(),
responses: %{
200 =>
Operation.response("Config Descriptions", "application/json", %Schema{
diff --git a/lib/pleroma/web/api_spec/operations/admin/invite_operation.ex b/lib/pleroma/web/api_spec/operations/admin/invite_operation.ex
index d3af9db49..801024d75 100644
--- a/lib/pleroma/web/api_spec/operations/admin/invite_operation.ex
+++ b/lib/pleroma/web/api_spec/operations/admin/invite_operation.ex
@@ -20,6 +20,7 @@ defmodule Pleroma.Web.ApiSpec.Admin.InviteOperation do
summary: "Get a list of generated invites",
operationId: "AdminAPI.InviteController.index",
security: [%{"oAuth" => ["read:invites"]}],
+ parameters: admin_api_params(),
responses: %{
200 =>
Operation.response("Invites", "application/json", %Schema{
@@ -51,6 +52,7 @@ defmodule Pleroma.Web.ApiSpec.Admin.InviteOperation do
summary: "Create an account registration invite token",
operationId: "AdminAPI.InviteController.create",
security: [%{"oAuth" => ["write:invites"]}],
+ parameters: admin_api_params(),
requestBody:
request_body("Parameters", %Schema{
type: :object,
@@ -71,6 +73,7 @@ defmodule Pleroma.Web.ApiSpec.Admin.InviteOperation do
summary: "Revoke invite by token",
operationId: "AdminAPI.InviteController.revoke",
security: [%{"oAuth" => ["write:invites"]}],
+ parameters: admin_api_params(),
requestBody:
request_body(
"Parameters",
@@ -97,6 +100,7 @@ defmodule Pleroma.Web.ApiSpec.Admin.InviteOperation do
summary: "Sends registration invite via email",
operationId: "AdminAPI.InviteController.email",
security: [%{"oAuth" => ["write:invites"]}],
+ parameters: admin_api_params(),
requestBody:
request_body(
"Parameters",
diff --git a/lib/pleroma/web/api_spec/operations/admin/media_proxy_cache_operation.ex b/lib/pleroma/web/api_spec/operations/admin/media_proxy_cache_operation.ex
index 0358cfbad..20d033f66 100644
--- a/lib/pleroma/web/api_spec/operations/admin/media_proxy_cache_operation.ex
+++ b/lib/pleroma/web/api_spec/operations/admin/media_proxy_cache_operation.ex
@@ -33,6 +33,7 @@ defmodule Pleroma.Web.ApiSpec.Admin.MediaProxyCacheOperation do
%Schema{type: :integer, default: 50},
"Number of statuses to return"
)
+ | admin_api_params()
],
responses: %{
200 => success_response()
@@ -46,6 +47,7 @@ defmodule Pleroma.Web.ApiSpec.Admin.MediaProxyCacheOperation do
summary: "Remove a banned MediaProxy URL from Cachex",
operationId: "AdminAPI.MediaProxyCacheController.delete",
security: [%{"oAuth" => ["write:media_proxy_caches"]}],
+ parameters: admin_api_params(),
requestBody:
request_body(
"Parameters",
@@ -71,6 +73,7 @@ defmodule Pleroma.Web.ApiSpec.Admin.MediaProxyCacheOperation do
summary: "Purge and optionally ban a MediaProxy URL",
operationId: "AdminAPI.MediaProxyCacheController.purge",
security: [%{"oAuth" => ["write:media_proxy_caches"]}],
+ parameters: admin_api_params(),
requestBody:
request_body(
"Parameters",
diff --git a/lib/pleroma/web/api_spec/operations/admin/oauth_app_operation.ex b/lib/pleroma/web/api_spec/operations/admin/oauth_app_operation.ex
index fbc9f80d7..a75f3e622 100644
--- a/lib/pleroma/web/api_spec/operations/admin/oauth_app_operation.ex
+++ b/lib/pleroma/web/api_spec/operations/admin/oauth_app_operation.ex
@@ -36,6 +36,7 @@ defmodule Pleroma.Web.ApiSpec.Admin.OAuthAppOperation do
%Schema{type: :integer, default: 50},
"Number of apps to return"
)
+ | admin_api_params()
],
responses: %{
200 =>
@@ -72,6 +73,7 @@ defmodule Pleroma.Web.ApiSpec.Admin.OAuthAppOperation do
summary: "Create OAuth App",
operationId: "AdminAPI.OAuthAppController.create",
requestBody: request_body("Parameters", create_request()),
+ parameters: admin_api_params(),
security: [%{"oAuth" => ["write"]}],
responses: %{
200 => Operation.response("App", "application/json", oauth_app()),
@@ -85,7 +87,7 @@ defmodule Pleroma.Web.ApiSpec.Admin.OAuthAppOperation do
tags: ["Admin", "oAuth Apps"],
summary: "Update OAuth App",
operationId: "AdminAPI.OAuthAppController.update",
- parameters: [id_param()],
+ parameters: [id_param() | admin_api_params()],
security: [%{"oAuth" => ["write"]}],
requestBody: request_body("Parameters", update_request()),
responses: %{
@@ -103,7 +105,7 @@ defmodule Pleroma.Web.ApiSpec.Admin.OAuthAppOperation do
tags: ["Admin", "oAuth Apps"],
summary: "Delete OAuth App",
operationId: "AdminAPI.OAuthAppController.delete",
- parameters: [id_param()],
+ parameters: [id_param() | admin_api_params()],
security: [%{"oAuth" => ["write"]}],
responses: %{
204 => no_content_response(),
diff --git a/lib/pleroma/web/api_spec/operations/admin/relay_operation.ex b/lib/pleroma/web/api_spec/operations/admin/relay_operation.ex
index 7672cb467..67ee5eee0 100644
--- a/lib/pleroma/web/api_spec/operations/admin/relay_operation.ex
+++ b/lib/pleroma/web/api_spec/operations/admin/relay_operation.ex
@@ -19,6 +19,7 @@ defmodule Pleroma.Web.ApiSpec.Admin.RelayOperation do
summary: "List Relays",
operationId: "AdminAPI.RelayController.index",
security: [%{"oAuth" => ["read"]}],
+ parameters: admin_api_params(),
responses: %{
200 =>
Operation.response("Response", "application/json", %Schema{
@@ -41,6 +42,7 @@ defmodule Pleroma.Web.ApiSpec.Admin.RelayOperation do
summary: "Follow a Relay",
operationId: "AdminAPI.RelayController.follow",
security: [%{"oAuth" => ["write:follows"]}],
+ parameters: admin_api_params(),
requestBody:
request_body("Parameters", %Schema{
type: :object,
@@ -64,6 +66,7 @@ defmodule Pleroma.Web.ApiSpec.Admin.RelayOperation do
summary: "Unfollow a Relay",
operationId: "AdminAPI.RelayController.unfollow",
security: [%{"oAuth" => ["write:follows"]}],
+ parameters: admin_api_params(),
requestBody:
request_body("Parameters", %Schema{
type: :object,
diff --git a/lib/pleroma/web/api_spec/operations/admin/report_operation.ex b/lib/pleroma/web/api_spec/operations/admin/report_operation.ex
index 15e78bfaf..3bb7ec49e 100644
--- a/lib/pleroma/web/api_spec/operations/admin/report_operation.ex
+++ b/lib/pleroma/web/api_spec/operations/admin/report_operation.ex
@@ -48,6 +48,7 @@ defmodule Pleroma.Web.ApiSpec.Admin.ReportOperation do
%Schema{type: :integer, default: 50},
"Number number of log entries per page"
)
+ | admin_api_params()
],
responses: %{
200 =>
@@ -71,7 +72,7 @@ defmodule Pleroma.Web.ApiSpec.Admin.ReportOperation do
tags: ["Admin", "Reports"],
summary: "Get an individual report",
operationId: "AdminAPI.ReportController.show",
- parameters: [id_param()],
+ parameters: [id_param() | admin_api_params()],
security: [%{"oAuth" => ["read:reports"]}],
responses: %{
200 => Operation.response("Report", "application/json", report()),
@@ -86,6 +87,7 @@ defmodule Pleroma.Web.ApiSpec.Admin.ReportOperation do
summary: "Change the state of one or multiple reports",
operationId: "AdminAPI.ReportController.update",
security: [%{"oAuth" => ["write:reports"]}],
+ parameters: admin_api_params(),
requestBody: request_body("Parameters", update_request(), required: true),
responses: %{
204 => no_content_response(),
@@ -100,7 +102,7 @@ defmodule Pleroma.Web.ApiSpec.Admin.ReportOperation do
tags: ["Admin", "Reports"],
summary: "Create report note",
operationId: "AdminAPI.ReportController.notes_create",
- parameters: [id_param()],
+ parameters: [id_param() | admin_api_params()],
requestBody:
request_body("Parameters", %Schema{
type: :object,
@@ -124,6 +126,7 @@ defmodule Pleroma.Web.ApiSpec.Admin.ReportOperation do
parameters: [
Operation.parameter(:report_id, :path, :string, "Report ID"),
Operation.parameter(:id, :path, :string, "Note ID")
+ | admin_api_params()
],
security: [%{"oAuth" => ["write:reports"]}],
responses: %{
diff --git a/lib/pleroma/web/api_spec/operations/admin/status_operation.ex b/lib/pleroma/web/api_spec/operations/admin/status_operation.ex
index 745399b4b..c105838a4 100644
--- a/lib/pleroma/web/api_spec/operations/admin/status_operation.ex
+++ b/lib/pleroma/web/api_spec/operations/admin/status_operation.ex
@@ -55,6 +55,7 @@ defmodule Pleroma.Web.ApiSpec.Admin.StatusOperation do
%Schema{type: :integer, default: 50},
"Number of statuses to return"
)
+ | admin_api_params()
],
responses: %{
200 =>
@@ -71,7 +72,7 @@ defmodule Pleroma.Web.ApiSpec.Admin.StatusOperation do
tags: ["Admin", "Statuses"],
summary: "Show Status",
operationId: "AdminAPI.StatusController.show",
- parameters: [id_param()],
+ parameters: [id_param() | admin_api_params()],
security: [%{"oAuth" => ["read:statuses"]}],
responses: %{
200 => Operation.response("Status", "application/json", status()),
@@ -85,7 +86,7 @@ defmodule Pleroma.Web.ApiSpec.Admin.StatusOperation do
tags: ["Admin", "Statuses"],
summary: "Change the scope of an individual reported status",
operationId: "AdminAPI.StatusController.update",
- parameters: [id_param()],
+ parameters: [id_param() | admin_api_params()],
security: [%{"oAuth" => ["write:statuses"]}],
requestBody: request_body("Parameters", update_request(), required: true),
responses: %{
@@ -100,7 +101,7 @@ defmodule Pleroma.Web.ApiSpec.Admin.StatusOperation do
tags: ["Admin", "Statuses"],
summary: "Delete an individual reported status",
operationId: "AdminAPI.StatusController.delete",
- parameters: [id_param()],
+ parameters: [id_param() | admin_api_params()],
security: [%{"oAuth" => ["write:statuses"]}],
responses: %{
200 => empty_object_response(),
diff --git a/lib/pleroma/web/mastodon_api/controllers/status_controller.ex b/lib/pleroma/web/mastodon_api/controllers/status_controller.ex
index 12be530c9..9bb2ef117 100644
--- a/lib/pleroma/web/mastodon_api/controllers/status_controller.ex
+++ b/lib/pleroma/web/mastodon_api/controllers/status_controller.ex
@@ -172,6 +172,11 @@ defmodule Pleroma.Web.MastodonAPI.StatusController do
with_direct_conversation_id: true
)
else
+ {:error, {:reject, message}} ->
+ conn
+ |> put_status(:unprocessable_entity)
+ |> json(%{error: message})
+
{:error, message} ->
conn
|> put_status(:unprocessable_entity)
diff --git a/lib/pleroma/web/media_proxy/media_proxy.ex b/lib/pleroma/web/media_proxy/media_proxy.ex
index 6f35826da..dfbfcea6b 100644
--- a/lib/pleroma/web/media_proxy/media_proxy.ex
+++ b/lib/pleroma/web/media_proxy/media_proxy.ex
@@ -60,22 +60,28 @@ defmodule Pleroma.Web.MediaProxy do
defp whitelisted?(url) do
%{host: domain} = URI.parse(url)
- mediaproxy_whitelist = Config.get([:media_proxy, :whitelist])
-
- upload_base_url_domain =
- if !is_nil(Config.get([Upload, :base_url])) do
- [URI.parse(Config.get([Upload, :base_url])).host]
+ mediaproxy_whitelist_domains =
+ [:media_proxy, :whitelist]
+ |> Config.get()
+ |> Enum.map(&maybe_get_domain_from_url/1)
+
+ whitelist_domains =
+ if base_url = Config.get([Upload, :base_url]) do
+ %{host: base_domain} = URI.parse(base_url)
+ [base_domain | mediaproxy_whitelist_domains]
else
- []
+ mediaproxy_whitelist_domains
end
- whitelist = mediaproxy_whitelist ++ upload_base_url_domain
+ domain in whitelist_domains
+ end
- Enum.any?(whitelist, fn pattern ->
- String.equivalent?(domain, pattern)
- end)
+ defp maybe_get_domain_from_url("http" <> _ = url) do
+ URI.parse(url).host
end
+ defp maybe_get_domain_from_url(domain), do: domain
+
def encode_url(url) do
base64 = Base.url_encode64(url, @base64_opts)