summaryrefslogtreecommitdiff
path: root/lib/pleroma/plugs
diff options
context:
space:
mode:
Diffstat (limited to 'lib/pleroma/plugs')
-rw-r--r--lib/pleroma/plugs/admin_secret_authentication_plug.ex27
-rw-r--r--lib/pleroma/plugs/auth_expected_plug.ex17
-rw-r--r--lib/pleroma/plugs/authentication_plug.ex33
-rw-r--r--lib/pleroma/plugs/ensure_authenticated_plug.ex24
-rw-r--r--lib/pleroma/plugs/ensure_public_or_authenticated_plug.ex6
-rw-r--r--lib/pleroma/plugs/expect_authenticated_check_plug.ex20
-rw-r--r--lib/pleroma/plugs/expect_public_or_authenticated_check_plug.ex21
-rw-r--r--lib/pleroma/plugs/federating_plug.ex21
-rw-r--r--lib/pleroma/plugs/frontend_static.ex55
-rw-r--r--lib/pleroma/plugs/http_security_plug.ex77
-rw-r--r--lib/pleroma/plugs/instance_static.ex15
-rw-r--r--lib/pleroma/plugs/mapped_signature_to_identity_plug.ex6
-rw-r--r--lib/pleroma/plugs/oauth_scopes_plug.ex27
-rw-r--r--lib/pleroma/plugs/rate_limiter/rate_limiter.ex17
-rw-r--r--lib/pleroma/plugs/static_fe_plug.ex9
-rw-r--r--lib/pleroma/plugs/uploaded_media.ex16
-rw-r--r--lib/pleroma/plugs/user_is_admin_plug.ex25
17 files changed, 281 insertions, 135 deletions
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/auth_expected_plug.ex b/lib/pleroma/plugs/auth_expected_plug.ex
deleted file mode 100644
index f79597dc3..000000000
--- a/lib/pleroma/plugs/auth_expected_plug.ex
+++ /dev/null
@@ -1,17 +0,0 @@
-# Pleroma: A lightweight social networking server
-# Copyright © 2017-2020 Pleroma Authors <https://pleroma.social/>
-# SPDX-License-Identifier: AGPL-3.0-only
-
-defmodule Pleroma.Plugs.AuthExpectedPlug do
- import Plug.Conn
-
- def init(options), do: options
-
- def call(conn, _) do
- put_private(conn, :auth_expected, true)
- end
-
- def auth_expected?(conn) do
- conn.private[:auth_expected]
- end
-end
diff --git a/lib/pleroma/plugs/authentication_plug.ex b/lib/pleroma/plugs/authentication_plug.ex
index 0061c69dc..057ea42f1 100644
--- a/lib/pleroma/plugs/authentication_plug.ex
+++ b/lib/pleroma/plugs/authentication_plug.ex
@@ -3,7 +3,6 @@
# SPDX-License-Identifier: AGPL-3.0-only
defmodule Pleroma.Plugs.AuthenticationPlug do
- alias Comeonin.Pbkdf2
alias Pleroma.Plugs.OAuthScopesPlug
alias Pleroma.User
@@ -17,8 +16,13 @@ defmodule Pleroma.Plugs.AuthenticationPlug do
:crypt.crypt(password, password_hash) == password_hash
end
+ def checkpw(password, "$2" <> _ = password_hash) do
+ # Handle bcrypt passwords for Mastodon migration
+ Bcrypt.verify_pass(password, password_hash)
+ end
+
def checkpw(password, "$pbkdf2" <> _ = password_hash) do
- Pbkdf2.checkpw(password, password_hash)
+ Pbkdf2.verify_pass(password, password_hash)
end
def checkpw(_password, _password_hash) do
@@ -26,6 +30,25 @@ defmodule Pleroma.Plugs.AuthenticationPlug do
false
end
+ def maybe_update_password(%User{password_hash: "$2" <> _} = user, password) do
+ do_update_password(user, password)
+ end
+
+ def maybe_update_password(%User{password_hash: "$6" <> _} = user, password) do
+ do_update_password(user, password)
+ end
+
+ def maybe_update_password(user, _), do: {:ok, user}
+
+ defp do_update_password(user, password) do
+ user
+ |> User.password_update_changeset(%{
+ "password" => password,
+ "password_confirmation" => password
+ })
+ |> Pleroma.Repo.update()
+ end
+
def call(%{assigns: %{user: %User{}}} = conn, _), do: conn
def call(
@@ -37,7 +60,9 @@ defmodule Pleroma.Plugs.AuthenticationPlug do
} = conn,
_
) do
- if Pbkdf2.checkpw(password, password_hash) do
+ if checkpw(password, password_hash) do
+ {:ok, auth_user} = maybe_update_password(auth_user, password)
+
conn
|> assign(:user, auth_user)
|> OAuthScopesPlug.skip_plug()
@@ -47,7 +72,7 @@ defmodule Pleroma.Plugs.AuthenticationPlug do
end
def call(%{assigns: %{auth_credentials: %{password: _}}} = conn, _) do
- Pbkdf2.dummy_checkpw()
+ Pbkdf2.no_user_verify()
conn
end
diff --git a/lib/pleroma/plugs/ensure_authenticated_plug.ex b/lib/pleroma/plugs/ensure_authenticated_plug.ex
index 6f9b840a9..3fe550806 100644
--- a/lib/pleroma/plugs/ensure_authenticated_plug.ex
+++ b/lib/pleroma/plugs/ensure_authenticated_plug.ex
@@ -5,19 +5,37 @@
defmodule Pleroma.Plugs.EnsureAuthenticatedPlug do
import Plug.Conn
import Pleroma.Web.TranslationHelpers
+
alias Pleroma.User
+ use Pleroma.Web, :plug
+
def init(options) do
options
end
- def call(%{assigns: %{user: %User{}}} = conn, _) do
+ @impl true
+ def perform(
+ %{
+ assigns: %{
+ auth_credentials: %{password: _},
+ user: %User{multi_factor_authentication_settings: %{enabled: true}}
+ }
+ } = conn,
+ _
+ ) do
+ conn
+ |> render_error(:forbidden, "Two-factor authentication enabled, you must use a access token.")
+ |> halt()
+ end
+
+ def perform(%{assigns: %{user: %User{}}} = conn, _) do
conn
end
- def call(conn, _) do
+ def perform(conn, _) do
conn
|> render_error(:forbidden, "Invalid credentials.")
- |> halt
+ |> halt()
end
end
diff --git a/lib/pleroma/plugs/ensure_public_or_authenticated_plug.ex b/lib/pleroma/plugs/ensure_public_or_authenticated_plug.ex
index d980ff13d..7265bb87a 100644
--- a/lib/pleroma/plugs/ensure_public_or_authenticated_plug.ex
+++ b/lib/pleroma/plugs/ensure_public_or_authenticated_plug.ex
@@ -5,14 +5,18 @@
defmodule Pleroma.Plugs.EnsurePublicOrAuthenticatedPlug do
import Pleroma.Web.TranslationHelpers
import Plug.Conn
+
alias Pleroma.Config
alias Pleroma.User
+ use Pleroma.Web, :plug
+
def init(options) do
options
end
- def call(conn, _) do
+ @impl true
+ def perform(conn, _) do
public? = Config.get!([:instance, :public])
case {public?, conn} do
diff --git a/lib/pleroma/plugs/expect_authenticated_check_plug.ex b/lib/pleroma/plugs/expect_authenticated_check_plug.ex
new file mode 100644
index 000000000..66b8d5de5
--- /dev/null
+++ b/lib/pleroma/plugs/expect_authenticated_check_plug.ex
@@ -0,0 +1,20 @@
+# Pleroma: A lightweight social networking server
+# Copyright © 2017-2020 Pleroma Authors <https://pleroma.social/>
+# SPDX-License-Identifier: AGPL-3.0-only
+
+defmodule Pleroma.Plugs.ExpectAuthenticatedCheckPlug do
+ @moduledoc """
+ Marks `Pleroma.Plugs.EnsureAuthenticatedPlug` as expected to be executed later in plug chain.
+
+ No-op plug which affects `Pleroma.Web` operation (is checked with `PlugHelper.plug_called?/2`).
+ """
+
+ use Pleroma.Web, :plug
+
+ def init(options), do: options
+
+ @impl true
+ def perform(conn, _) do
+ conn
+ end
+end
diff --git a/lib/pleroma/plugs/expect_public_or_authenticated_check_plug.ex b/lib/pleroma/plugs/expect_public_or_authenticated_check_plug.ex
new file mode 100644
index 000000000..ba0ef76bd
--- /dev/null
+++ b/lib/pleroma/plugs/expect_public_or_authenticated_check_plug.ex
@@ -0,0 +1,21 @@
+# Pleroma: A lightweight social networking server
+# Copyright © 2017-2020 Pleroma Authors <https://pleroma.social/>
+# SPDX-License-Identifier: AGPL-3.0-only
+
+defmodule Pleroma.Plugs.ExpectPublicOrAuthenticatedCheckPlug do
+ @moduledoc """
+ Marks `Pleroma.Plugs.EnsurePublicOrAuthenticatedPlug` as expected to be executed later in plug
+ chain.
+
+ No-op plug which affects `Pleroma.Web` operation (is checked with `PlugHelper.plug_called?/2`).
+ """
+
+ use Pleroma.Web, :plug
+
+ def init(options), do: options
+
+ @impl true
+ def perform(conn, _) do
+ conn
+ end
+end
diff --git a/lib/pleroma/plugs/federating_plug.ex b/lib/pleroma/plugs/federating_plug.ex
index d3943586d..09038f3c6 100644
--- a/lib/pleroma/plugs/federating_plug.ex
+++ b/lib/pleroma/plugs/federating_plug.ex
@@ -10,14 +10,23 @@ defmodule Pleroma.Web.FederatingPlug do
end
def call(conn, _opts) do
- if Pleroma.Config.get([:instance, :federating]) do
+ if federating?() do
conn
else
- conn
- |> put_status(404)
- |> Phoenix.Controller.put_view(Pleroma.Web.ErrorView)
- |> Phoenix.Controller.render("404.json")
- |> halt()
+ fail(conn)
end
end
+
+ def federating?, do: Pleroma.Config.get([:instance, :federating])
+
+ # Definition for the use in :if_func / :unless_func plug options
+ def federating?(_conn), do: federating?()
+
+ defp fail(conn) do
+ conn
+ |> put_status(404)
+ |> Phoenix.Controller.put_view(Pleroma.Web.ErrorView)
+ |> Phoenix.Controller.render("404.json")
+ |> halt()
+ end
end
diff --git a/lib/pleroma/plugs/frontend_static.ex b/lib/pleroma/plugs/frontend_static.ex
new file mode 100644
index 000000000..11a0d5382
--- /dev/null
+++ b/lib/pleroma/plugs/frontend_static.ex
@@ -0,0 +1,55 @@
+# Pleroma: A lightweight social networking server
+# Copyright © 2017-2020 Pleroma Authors <https://pleroma.social/>
+# SPDX-License-Identifier: AGPL-3.0-only
+
+defmodule Pleroma.Plugs.FrontendStatic do
+ require Pleroma.Constants
+
+ @moduledoc """
+ This is a shim to call `Plug.Static` but with runtime `from` configuration`. It dispatches to the different frontends.
+ """
+ @behaviour Plug
+
+ def file_path(path, frontend_type \\ :primary) do
+ if configuration = Pleroma.Config.get([:frontends, frontend_type]) do
+ instance_static_path = Pleroma.Config.get([:instance, :static_dir], "instance/static")
+
+ Path.join([
+ instance_static_path,
+ "frontends",
+ configuration["name"],
+ configuration["ref"],
+ path
+ ])
+ else
+ nil
+ end
+ end
+
+ def init(opts) do
+ opts
+ |> Keyword.put(:from, "__unconfigured_frontend_static_plug")
+ |> Plug.Static.init()
+ |> Map.put(:frontend_type, opts[:frontend_type])
+ end
+
+ def call(conn, opts) do
+ frontend_type = Map.get(opts, :frontend_type, :primary)
+ path = file_path("", frontend_type)
+
+ if path do
+ conn
+ |> call_static(opts, path)
+ else
+ conn
+ end
+ end
+
+ defp call_static(conn, opts, from) do
+ opts =
+ opts
+ |> Map.put(:from, from)
+
+ Plug.Static.call(conn, opts)
+ end
+end
diff --git a/lib/pleroma/plugs/http_security_plug.ex b/lib/pleroma/plugs/http_security_plug.ex
index cad0ad4a0..c363b193b 100644
--- a/lib/pleroma/plugs/http_security_plug.ex
+++ b/lib/pleroma/plugs/http_security_plug.ex
@@ -69,26 +69,27 @@ defmodule Pleroma.Plugs.HTTPSecurityPlug do
img_src = "img-src 'self' data: blob:"
media_src = "media-src 'self'"
+ # Strict multimedia CSP enforcement only when MediaProxy is enabled
{img_src, media_src} =
if Config.get([:media_proxy, :enabled]) &&
!Config.get([:media_proxy, :proxy_opts, :redirect_on_failure]) do
- sources = get_proxy_and_attachment_sources()
+ sources = build_csp_multimedia_source_list()
{[img_src, sources], [media_src, sources]}
else
{[img_src, " https:"], [media_src, " https:"]}
end
- connect_src = ["connect-src 'self' ", static_url, ?\s, websocket_url]
+ connect_src = ["connect-src 'self' blob: ", static_url, ?\s, websocket_url]
connect_src =
- if Pleroma.Config.get(:env) == :dev do
+ if Config.get(:env) == :dev do
[connect_src, " http://localhost:3035/"]
else
connect_src
end
script_src =
- if Pleroma.Config.get(:env) == :dev do
+ if Config.get(:env) == :dev do
"script-src 'self' 'unsafe-eval'"
else
"script-src 'self'"
@@ -107,38 +108,64 @@ defmodule Pleroma.Plugs.HTTPSecurityPlug do
|> :erlang.iolist_to_binary()
end
- defp get_proxy_and_attachment_sources do
+ defp build_csp_from_whitelist([], acc), do: acc
+
+ defp build_csp_from_whitelist([last], acc) do
+ [build_csp_param_from_whitelist(last) | acc]
+ end
+
+ defp build_csp_from_whitelist([head | tail], acc) do
+ build_csp_from_whitelist(tail, [[?\s, build_csp_param_from_whitelist(head)] | acc])
+ end
+
+ # 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
+
+ defp build_csp_param_from_whitelist(url), do: url
+
+ 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)
-
- media_proxy_base_url =
- if Config.get([:media_proxy, :base_url]),
- do: URI.parse(Config.get([:media_proxy, :base_url])).host
-
- upload_base_url =
- if Config.get([Pleroma.Upload, :base_url]),
- do: URI.parse(Config.get([Pleroma.Upload, :base_url])).host
-
- s3_endpoint =
- if Config.get([Pleroma.Upload, :uploader]) == Pleroma.Uploaders.S3,
- do: URI.parse(Config.get([Pleroma.Uploaders.S3, :public_endpoint])).host
-
- []
- |> add_source(media_proxy_base_url)
- |> add_source(upload_base_url)
- |> add_source(s3_endpoint)
+ [:media_proxy, :whitelist]
+ |> Config.get()
+ |> build_csp_from_whitelist([])
+
+ 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)
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
defp add_csp_param(csp_iodata, param), do: [[param, ?;] | csp_iodata]
+ defp build_csp_param(nil), do: nil
+
+ defp build_csp_param(url) when is_binary(url) do
+ %{host: host, scheme: scheme} = URI.parse(url)
+
+ if scheme do
+ [scheme, "://", host]
+ end
+ end
+
def warn_if_disabled do
unless Config.get([:http_security, :enabled]) do
Logger.warn("
diff --git a/lib/pleroma/plugs/instance_static.ex b/lib/pleroma/plugs/instance_static.ex
index 7516f75c3..0fb57e422 100644
--- a/lib/pleroma/plugs/instance_static.ex
+++ b/lib/pleroma/plugs/instance_static.ex
@@ -16,28 +16,24 @@ defmodule Pleroma.Plugs.InstanceStatic do
instance_path =
Path.join(Pleroma.Config.get([:instance, :static_dir], "instance/static/"), path)
- if File.exists?(instance_path) do
- instance_path
- else
+ frontend_path = Pleroma.Plugs.FrontendStatic.file_path(path, :primary)
+
+ (File.exists?(instance_path) && instance_path) ||
+ (frontend_path && File.exists?(frontend_path) && frontend_path) ||
Path.join(Application.app_dir(:pleroma, "priv/static/"), path)
- end
end
def init(opts) do
opts
|> Keyword.put(:from, "__unconfigured_instance_static_plug")
- |> Keyword.put(:at, "/__unconfigured_instance_static_plug")
|> Plug.Static.init()
end
for only <- Pleroma.Constants.static_only_files() do
- at = Plug.Router.Utils.split("/")
-
def call(%{request_path: "/" <> unquote(only) <> _} = conn, opts) do
call_static(
conn,
opts,
- unquote(at),
Pleroma.Config.get([:instance, :static_dir], "instance/static")
)
end
@@ -47,11 +43,10 @@ defmodule Pleroma.Plugs.InstanceStatic do
conn
end
- defp call_static(conn, opts, at, from) do
+ defp call_static(conn, opts, from) do
opts =
opts
|> Map.put(:from, from)
- |> Map.put(:at, at)
Plug.Static.call(conn, opts)
end
diff --git a/lib/pleroma/plugs/mapped_signature_to_identity_plug.ex b/lib/pleroma/plugs/mapped_signature_to_identity_plug.ex
index 4cc93adb0..f44d4dee5 100644
--- a/lib/pleroma/plugs/mapped_signature_to_identity_plug.ex
+++ b/lib/pleroma/plugs/mapped_signature_to_identity_plug.ex
@@ -43,13 +43,13 @@ defmodule Pleroma.Web.Plugs.MappedSignatureToIdentityPlug do
else
{:user_match, false} ->
Logger.debug("Failed to map identity from signature (payload actor mismatch)")
- Logger.debug("key_id=#{key_id_from_conn(conn)}, actor=#{actor}")
+ Logger.debug("key_id=#{inspect(key_id_from_conn(conn))}, actor=#{inspect(actor)}")
assign(conn, :valid_signature, false)
# remove me once testsuite uses mapped capabilities instead of what we do now
{:user, nil} ->
Logger.debug("Failed to map identity from signature (lookup failure)")
- Logger.debug("key_id=#{key_id_from_conn(conn)}, actor=#{actor}")
+ Logger.debug("key_id=#{inspect(key_id_from_conn(conn))}, actor=#{actor}")
conn
end
end
@@ -61,7 +61,7 @@ defmodule Pleroma.Web.Plugs.MappedSignatureToIdentityPlug do
else
_ ->
Logger.debug("Failed to map identity from signature (no payload actor mismatch)")
- Logger.debug("key_id=#{key_id_from_conn(conn)}")
+ Logger.debug("key_id=#{inspect(key_id_from_conn(conn))}")
assign(conn, :valid_signature, false)
end
end
diff --git a/lib/pleroma/plugs/oauth_scopes_plug.ex b/lib/pleroma/plugs/oauth_scopes_plug.ex
index 66f48c28c..efc25b79f 100644
--- a/lib/pleroma/plugs/oauth_scopes_plug.ex
+++ b/lib/pleroma/plugs/oauth_scopes_plug.ex
@@ -7,15 +7,12 @@ defmodule Pleroma.Plugs.OAuthScopesPlug do
import Pleroma.Web.Gettext
alias Pleroma.Config
- alias Pleroma.Plugs.EnsurePublicOrAuthenticatedPlug
- alias Pleroma.Plugs.PlugHelper
use Pleroma.Web, :plug
- @behaviour Plug
-
def init(%{scopes: _} = options), do: options
+ @impl true
def perform(%Plug.Conn{assigns: assigns} = conn, %{scopes: scopes} = options) do
op = options[:op] || :|
token = assigns[:token]
@@ -31,10 +28,7 @@ defmodule Pleroma.Plugs.OAuthScopesPlug do
conn
options[:fallback] == :proceed_unauthenticated ->
- conn
- |> assign(:user, nil)
- |> assign(:token, nil)
- |> maybe_perform_instance_privacy_check(options)
+ drop_auth_info(conn)
true ->
missing_scopes = scopes -- matched_scopes
@@ -50,6 +44,15 @@ defmodule Pleroma.Plugs.OAuthScopesPlug do
end
end
+ @doc "Drops authentication info from connection"
+ def drop_auth_info(conn) do
+ # To simplify debugging, setting a private variable on `conn` if auth info is dropped
+ conn
+ |> put_private(:authentication_ignored, true)
+ |> assign(:user, nil)
+ |> assign(:token, nil)
+ end
+
@doc "Filters descendants of supported scopes"
def filter_descendants(scopes, supported_scopes) do
Enum.filter(
@@ -71,12 +74,4 @@ defmodule Pleroma.Plugs.OAuthScopesPlug do
scopes
end
end
-
- defp maybe_perform_instance_privacy_check(%Plug.Conn{} = conn, options) do
- if options[:skip_instance_privacy_check] do
- conn
- else
- EnsurePublicOrAuthenticatedPlug.call(conn, [])
- end
- end
end
diff --git a/lib/pleroma/plugs/rate_limiter/rate_limiter.ex b/lib/pleroma/plugs/rate_limiter/rate_limiter.ex
index 1529da717..c51e2c634 100644
--- a/lib/pleroma/plugs/rate_limiter/rate_limiter.ex
+++ b/lib/pleroma/plugs/rate_limiter/rate_limiter.ex
@@ -110,20 +110,9 @@ defmodule Pleroma.Plugs.RateLimiter do
end
def disabled?(conn) do
- localhost_or_socket =
- case Config.get([Pleroma.Web.Endpoint, :http, :ip]) do
- {127, 0, 0, 1} -> true
- {0, 0, 0, 0, 0, 0, 0, 1} -> true
- {:local, _} -> true
- _ -> false
- end
-
- remote_ip_not_found =
- if Map.has_key?(conn.assigns, :remote_ip_found),
- do: !conn.assigns.remote_ip_found,
- else: false
-
- localhost_or_socket and remote_ip_not_found
+ if Map.has_key?(conn.assigns, :remote_ip_found),
+ do: !conn.assigns.remote_ip_found,
+ else: false
end
@inspect_bucket_not_found {:error, :not_found}
diff --git a/lib/pleroma/plugs/static_fe_plug.ex b/lib/pleroma/plugs/static_fe_plug.ex
index 156e6788e..143665c71 100644
--- a/lib/pleroma/plugs/static_fe_plug.ex
+++ b/lib/pleroma/plugs/static_fe_plug.ex
@@ -9,7 +9,7 @@ defmodule Pleroma.Plugs.StaticFEPlug do
def init(options), do: options
def call(conn, _) do
- if enabled?() and accepts_html?(conn) do
+ if enabled?() and requires_html?(conn) do
conn
|> StaticFEController.call(:show)
|> halt()
@@ -20,10 +20,7 @@ defmodule Pleroma.Plugs.StaticFEPlug do
defp enabled?, do: Pleroma.Config.get([:static_fe, :enabled], false)
- defp accepts_html?(conn) do
- case get_req_header(conn, "accept") do
- [accept | _] -> String.contains?(accept, "text/html")
- _ -> false
- end
+ defp requires_html?(conn) do
+ Phoenix.Controller.get_format(conn) == "html"
end
end
diff --git a/lib/pleroma/plugs/uploaded_media.ex b/lib/pleroma/plugs/uploaded_media.ex
index 94147e0c4..40984cfc0 100644
--- a/lib/pleroma/plugs/uploaded_media.ex
+++ b/lib/pleroma/plugs/uploaded_media.ex
@@ -10,6 +10,8 @@ defmodule Pleroma.Plugs.UploadedMedia do
import Pleroma.Web.Gettext
require Logger
+ alias Pleroma.Web.MediaProxy
+
@behaviour Plug
# no slashes
@path "media"
@@ -35,8 +37,7 @@ defmodule Pleroma.Plugs.UploadedMedia do
%{query_params: %{"name" => name}} = conn ->
name = String.replace(name, "\"", "\\\"")
- conn
- |> put_resp_header("content-disposition", "filename=\"#{name}\"")
+ put_resp_header(conn, "content-disposition", "filename=\"#{name}\"")
conn ->
conn
@@ -47,7 +48,8 @@ defmodule Pleroma.Plugs.UploadedMedia do
with uploader <- Keyword.fetch!(config, :uploader),
proxy_remote = Keyword.get(config, :proxy_remote, false),
- {:ok, get_method} <- uploader.get_file(file) do
+ {:ok, get_method} <- uploader.get_file(file),
+ false <- media_is_banned(conn, get_method) do
get_media(conn, get_method, proxy_remote, opts)
else
_ ->
@@ -59,6 +61,14 @@ defmodule Pleroma.Plugs.UploadedMedia do
def call(conn, _opts), do: conn
+ defp media_is_banned(%{request_path: path} = _conn, {:static_dir, _}) do
+ MediaProxy.in_banned_urls(Pleroma.Web.base_url() <> path)
+ end
+
+ defp media_is_banned(_, {:url, url}), do: MediaProxy.in_banned_urls(url)
+
+ defp media_is_banned(_, _), do: false
+
defp get_media(conn, {:static_dir, directory}, _, opts) do
static_opts =
Map.get(opts, :static_plug_opts)
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