aboutsummaryrefslogtreecommitdiff
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.ex2
-rw-r--r--lib/pleroma/plugs/authentication_plug.ex15
-rw-r--r--lib/pleroma/plugs/basic_auth_decoder_plug.ex2
-rw-r--r--lib/pleroma/plugs/cache.ex2
-rw-r--r--lib/pleroma/plugs/digest.ex2
-rw-r--r--lib/pleroma/plugs/ensure_authenticated_plug.ex26
-rw-r--r--lib/pleroma/plugs/ensure_public_or_authenticated_plug.ex8
-rw-r--r--lib/pleroma/plugs/ensure_user_key_plug.ex2
-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.ex23
-rw-r--r--lib/pleroma/plugs/http_security_plug.ex4
-rw-r--r--lib/pleroma/plugs/http_signature.ex2
-rw-r--r--lib/pleroma/plugs/idempotency_plug.ex2
-rw-r--r--lib/pleroma/plugs/instance_static.ex9
-rw-r--r--lib/pleroma/plugs/legacy_authentication_plug.ex5
-rw-r--r--lib/pleroma/plugs/mapped_signature_to_identity_plug.ex13
-rw-r--r--lib/pleroma/plugs/oauth_plug.ex2
-rw-r--r--lib/pleroma/plugs/oauth_scopes_plug.ex30
-rw-r--r--lib/pleroma/plugs/plug_helper.ex40
-rw-r--r--lib/pleroma/plugs/rate_limiter/limiter_supervisor.ex10
-rw-r--r--lib/pleroma/plugs/rate_limiter/rate_limiter.ex187
-rw-r--r--lib/pleroma/plugs/remote_ip.ex2
-rw-r--r--lib/pleroma/plugs/session_authentication_plug.ex2
-rw-r--r--lib/pleroma/plugs/set_format_plug.ex2
-rw-r--r--lib/pleroma/plugs/set_locale_plug.ex2
-rw-r--r--lib/pleroma/plugs/set_user_session_id_plug.ex2
-rw-r--r--lib/pleroma/plugs/static_fe_plug.ex7
-rw-r--r--lib/pleroma/plugs/trailing_format_plug.ex2
-rw-r--r--lib/pleroma/plugs/uploaded_media.ex10
-rw-r--r--lib/pleroma/plugs/user_enabled_plug.ex2
-rw-r--r--lib/pleroma/plugs/user_fetcher_plug.ex2
-rw-r--r--lib/pleroma/plugs/user_is_admin_plug.ex2
33 files changed, 305 insertions, 157 deletions
diff --git a/lib/pleroma/plugs/admin_secret_authentication_plug.ex b/lib/pleroma/plugs/admin_secret_authentication_plug.ex
index 49dea452d..b4b47a31f 100644
--- a/lib/pleroma/plugs/admin_secret_authentication_plug.ex
+++ b/lib/pleroma/plugs/admin_secret_authentication_plug.ex
@@ -1,5 +1,5 @@
# Pleroma: A lightweight social networking server
-# Copyright © 2017-2019 Pleroma Authors <https://pleroma.social/>
+# Copyright © 2017-2020 Pleroma Authors <https://pleroma.social/>
# SPDX-License-Identifier: AGPL-3.0-only
defmodule Pleroma.Plugs.AdminSecretAuthenticationPlug do
diff --git a/lib/pleroma/plugs/authentication_plug.ex b/lib/pleroma/plugs/authentication_plug.ex
index 567674a0b..ae4a235bd 100644
--- a/lib/pleroma/plugs/authentication_plug.ex
+++ b/lib/pleroma/plugs/authentication_plug.ex
@@ -1,11 +1,13 @@
# Pleroma: A lightweight social networking server
-# Copyright © 2017-2019 Pleroma Authors <https://pleroma.social/>
+# Copyright © 2017-2020 Pleroma Authors <https://pleroma.social/>
# SPDX-License-Identifier: AGPL-3.0-only
defmodule Pleroma.Plugs.AuthenticationPlug do
- alias Comeonin.Pbkdf2
- import Plug.Conn
+ alias Pleroma.Plugs.OAuthScopesPlug
alias Pleroma.User
+
+ import Plug.Conn
+
require Logger
def init(options), do: options
@@ -15,7 +17,7 @@ defmodule Pleroma.Plugs.AuthenticationPlug do
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
@@ -34,16 +36,17 @@ defmodule Pleroma.Plugs.AuthenticationPlug do
} = conn,
_
) do
- if Pbkdf2.checkpw(password, password_hash) do
+ if Pbkdf2.verify_pass(password, password_hash) do
conn
|> assign(:user, auth_user)
+ |> OAuthScopesPlug.skip_plug()
else
conn
end
end
def call(%{assigns: %{auth_credentials: %{password: _}}} = conn, _) do
- Pbkdf2.dummy_checkpw()
+ Pbkdf2.no_user_verify()
conn
end
diff --git a/lib/pleroma/plugs/basic_auth_decoder_plug.ex b/lib/pleroma/plugs/basic_auth_decoder_plug.ex
index 7eeeb1e5d..af7ecb0d8 100644
--- a/lib/pleroma/plugs/basic_auth_decoder_plug.ex
+++ b/lib/pleroma/plugs/basic_auth_decoder_plug.ex
@@ -1,5 +1,5 @@
# Pleroma: A lightweight social networking server
-# Copyright © 2017-2019 Pleroma Authors <https://pleroma.social/>
+# Copyright © 2017-2020 Pleroma Authors <https://pleroma.social/>
# SPDX-License-Identifier: AGPL-3.0-only
defmodule Pleroma.Plugs.BasicAuthDecoderPlug do
diff --git a/lib/pleroma/plugs/cache.ex b/lib/pleroma/plugs/cache.ex
index 50b534e7b..f65c2a189 100644
--- a/lib/pleroma/plugs/cache.ex
+++ b/lib/pleroma/plugs/cache.ex
@@ -1,5 +1,5 @@
# Pleroma: A lightweight social networking server
-# Copyright © 2017-2019 Pleroma Authors <https://pleroma.social/>
+# Copyright © 2017-2020 Pleroma Authors <https://pleroma.social/>
# SPDX-License-Identifier: AGPL-3.0-only
defmodule Pleroma.Plugs.Cache do
diff --git a/lib/pleroma/plugs/digest.ex b/lib/pleroma/plugs/digest.ex
index 0ba00845a..b521b3073 100644
--- a/lib/pleroma/plugs/digest.ex
+++ b/lib/pleroma/plugs/digest.ex
@@ -1,5 +1,5 @@
# Pleroma: A lightweight social networking server
-# Copyright © 2017-2019 Pleroma Authors <https://pleroma.social/>
+# Copyright © 2017-2020 Pleroma Authors <https://pleroma.social/>
# SPDX-License-Identifier: AGPL-3.0-only
defmodule Pleroma.Web.Plugs.DigestPlug do
diff --git a/lib/pleroma/plugs/ensure_authenticated_plug.ex b/lib/pleroma/plugs/ensure_authenticated_plug.ex
index 27cd41aec..3fe550806 100644
--- a/lib/pleroma/plugs/ensure_authenticated_plug.ex
+++ b/lib/pleroma/plugs/ensure_authenticated_plug.ex
@@ -1,23 +1,41 @@
# Pleroma: A lightweight social networking server
-# Copyright © 2017-2019 Pleroma Authors <https://pleroma.social/>
+# Copyright © 2017-2020 Pleroma Authors <https://pleroma.social/>
# SPDX-License-Identifier: AGPL-3.0-only
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 a16f61435..7265bb87a 100644
--- a/lib/pleroma/plugs/ensure_public_or_authenticated_plug.ex
+++ b/lib/pleroma/plugs/ensure_public_or_authenticated_plug.ex
@@ -1,18 +1,22 @@
# Pleroma: A lightweight social networking server
-# Copyright © 2017-2019 Pleroma Authors <https://pleroma.social/>
+# Copyright © 2017-2020 Pleroma Authors <https://pleroma.social/>
# SPDX-License-Identifier: AGPL-3.0-only
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/ensure_user_key_plug.ex b/lib/pleroma/plugs/ensure_user_key_plug.ex
index c88ebfb3f..9795cdbde 100644
--- a/lib/pleroma/plugs/ensure_user_key_plug.ex
+++ b/lib/pleroma/plugs/ensure_user_key_plug.ex
@@ -1,5 +1,5 @@
# Pleroma: A lightweight social networking server
-# Copyright © 2017-2019 Pleroma Authors <https://pleroma.social/>
+# Copyright © 2017-2020 Pleroma Authors <https://pleroma.social/>
# SPDX-License-Identifier: AGPL-3.0-only
defmodule Pleroma.Plugs.EnsureUserKeyPlug 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 4dc4e9279..09038f3c6 100644
--- a/lib/pleroma/plugs/federating_plug.ex
+++ b/lib/pleroma/plugs/federating_plug.ex
@@ -1,5 +1,5 @@
# Pleroma: A lightweight social networking server
-# Copyright © 2017-2019 Pleroma Authors <https://pleroma.social/>
+# Copyright © 2017-2020 Pleroma Authors <https://pleroma.social/>
# SPDX-License-Identifier: AGPL-3.0-only
defmodule Pleroma.Web.FederatingPlug do
@@ -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/http_security_plug.ex b/lib/pleroma/plugs/http_security_plug.ex
index b04273979..6462797b6 100644
--- a/lib/pleroma/plugs/http_security_plug.ex
+++ b/lib/pleroma/plugs/http_security_plug.ex
@@ -1,5 +1,5 @@
# Pleroma: A lightweight social networking server
-# Copyright © 2017-2019 Pleroma Authors <https://pleroma.social/>
+# Copyright © 2017-2020 Pleroma Authors <https://pleroma.social/>
# SPDX-License-Identifier: AGPL-3.0-only
defmodule Pleroma.Plugs.HTTPSecurityPlug do
@@ -75,7 +75,7 @@ defmodule Pleroma.Plugs.HTTPSecurityPlug do
"default-src 'none'",
"base-uri 'self'",
"frame-ancestors 'none'",
- "img-src 'self' data: https:",
+ "img-src 'self' data: blob: https:",
"media-src 'self' https:",
"style-src 'self' 'unsafe-inline'",
"font-src 'self'",
diff --git a/lib/pleroma/plugs/http_signature.ex b/lib/pleroma/plugs/http_signature.ex
index 477a5b578..036e2a773 100644
--- a/lib/pleroma/plugs/http_signature.ex
+++ b/lib/pleroma/plugs/http_signature.ex
@@ -1,5 +1,5 @@
# Pleroma: A lightweight social networking server
-# Copyright © 2017-2019 Pleroma Authors <https://pleroma.social/>
+# Copyright © 2017-2020 Pleroma Authors <https://pleroma.social/>
# SPDX-License-Identifier: AGPL-3.0-only
defmodule Pleroma.Web.Plugs.HTTPSignaturePlug do
diff --git a/lib/pleroma/plugs/idempotency_plug.ex b/lib/pleroma/plugs/idempotency_plug.ex
index e99c5d279..f41397075 100644
--- a/lib/pleroma/plugs/idempotency_plug.ex
+++ b/lib/pleroma/plugs/idempotency_plug.ex
@@ -1,5 +1,5 @@
# Pleroma: A lightweight social networking server
-# Copyright © 2017-2019 Pleroma Authors <https://pleroma.social/>
+# Copyright © 2017-2020 Pleroma Authors <https://pleroma.social/>
# SPDX-License-Identifier: AGPL-3.0-only
defmodule Pleroma.Plugs.IdempotencyPlug do
diff --git a/lib/pleroma/plugs/instance_static.ex b/lib/pleroma/plugs/instance_static.ex
index a64f1ea80..7516f75c3 100644
--- a/lib/pleroma/plugs/instance_static.ex
+++ b/lib/pleroma/plugs/instance_static.ex
@@ -1,8 +1,10 @@
# Pleroma: A lightweight social networking server
-# Copyright © 2017-2019 Pleroma Authors <https://pleroma.social/>
+# Copyright © 2017-2020 Pleroma Authors <https://pleroma.social/>
# SPDX-License-Identifier: AGPL-3.0-only
defmodule Pleroma.Plugs.InstanceStatic do
+ require Pleroma.Constants
+
@moduledoc """
This is a shim to call `Plug.Static` but with runtime `from` configuration.
@@ -21,9 +23,6 @@ defmodule Pleroma.Plugs.InstanceStatic do
end
end
- @only ~w(index.html robots.txt static emoji packs sounds images instance favicon.png sw.js
- sw-pleroma.js)
-
def init(opts) do
opts
|> Keyword.put(:from, "__unconfigured_instance_static_plug")
@@ -31,7 +30,7 @@ defmodule Pleroma.Plugs.InstanceStatic do
|> Plug.Static.init()
end
- for only <- @only do
+ for only <- Pleroma.Constants.static_only_files() do
at = Plug.Router.Utils.split("/")
def call(%{request_path: "/" <> unquote(only) <> _} = conn, opts) do
diff --git a/lib/pleroma/plugs/legacy_authentication_plug.ex b/lib/pleroma/plugs/legacy_authentication_plug.ex
index 78b7e388f..d346e01a6 100644
--- a/lib/pleroma/plugs/legacy_authentication_plug.ex
+++ b/lib/pleroma/plugs/legacy_authentication_plug.ex
@@ -1,9 +1,11 @@
# Pleroma: A lightweight social networking server
-# Copyright © 2017-2019 Pleroma Authors <https://pleroma.social/>
+# Copyright © 2017-2020 Pleroma Authors <https://pleroma.social/>
# SPDX-License-Identifier: AGPL-3.0-only
defmodule Pleroma.Plugs.LegacyAuthenticationPlug do
import Plug.Conn
+
+ alias Pleroma.Plugs.OAuthScopesPlug
alias Pleroma.User
def init(options) do
@@ -27,6 +29,7 @@ defmodule Pleroma.Plugs.LegacyAuthenticationPlug do
conn
|> assign(:auth_user, user)
|> assign(:user, user)
+ |> OAuthScopesPlug.skip_plug()
else
_ ->
conn
diff --git a/lib/pleroma/plugs/mapped_signature_to_identity_plug.ex b/lib/pleroma/plugs/mapped_signature_to_identity_plug.ex
index ce8494b9d..f44d4dee5 100644
--- a/lib/pleroma/plugs/mapped_signature_to_identity_plug.ex
+++ b/lib/pleroma/plugs/mapped_signature_to_identity_plug.ex
@@ -1,5 +1,5 @@
# Pleroma: A lightweight social networking server
-# Copyright © 2017-2019 Pleroma Authors <https://pleroma.social/>
+# Copyright © 2017-2020 Pleroma Authors <https://pleroma.social/>
# SPDX-License-Identifier: AGPL-3.0-only
defmodule Pleroma.Web.Plugs.MappedSignatureToIdentityPlug do
@@ -13,8 +13,9 @@ defmodule Pleroma.Web.Plugs.MappedSignatureToIdentityPlug do
def init(options), do: options
defp key_id_from_conn(conn) do
- with %{"keyId" => key_id} <- HTTPSignatures.signature_for_conn(conn) do
- Signature.key_id_to_actor_id(key_id)
+ with %{"keyId" => key_id} <- HTTPSignatures.signature_for_conn(conn),
+ {:ok, ap_id} <- Signature.key_id_to_actor_id(key_id) do
+ ap_id
else
_ ->
nil
@@ -42,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
@@ -60,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_plug.ex b/lib/pleroma/plugs/oauth_plug.ex
index 11a5b7642..6fa71ef47 100644
--- a/lib/pleroma/plugs/oauth_plug.ex
+++ b/lib/pleroma/plugs/oauth_plug.ex
@@ -1,5 +1,5 @@
# Pleroma: A lightweight social networking server
-# Copyright © 2017-2019 Pleroma Authors <https://pleroma.social/>
+# Copyright © 2017-2020 Pleroma Authors <https://pleroma.social/>
# SPDX-License-Identifier: AGPL-3.0-only
defmodule Pleroma.Plugs.OAuthPlug do
diff --git a/lib/pleroma/plugs/oauth_scopes_plug.ex b/lib/pleroma/plugs/oauth_scopes_plug.ex
index 07c0f7fdb..efc25b79f 100644
--- a/lib/pleroma/plugs/oauth_scopes_plug.ex
+++ b/lib/pleroma/plugs/oauth_scopes_plug.ex
@@ -1,5 +1,5 @@
# Pleroma: A lightweight social networking server
-# Copyright © 2017-2019 Pleroma Authors <https://pleroma.social/>
+# Copyright © 2017-2020 Pleroma Authors <https://pleroma.social/>
# SPDX-License-Identifier: AGPL-3.0-only
defmodule Pleroma.Plugs.OAuthScopesPlug do
@@ -7,13 +7,13 @@ defmodule Pleroma.Plugs.OAuthScopesPlug do
import Pleroma.Web.Gettext
alias Pleroma.Config
- alias Pleroma.Plugs.EnsurePublicOrAuthenticatedPlug
- @behaviour Plug
+ use Pleroma.Web, :plug
def init(%{scopes: _} = options), do: options
- def call(%Plug.Conn{assigns: assigns} = conn, %{scopes: scopes} = options) do
+ @impl true
+ def perform(%Plug.Conn{assigns: assigns} = conn, %{scopes: scopes} = options) do
op = options[:op] || :|
token = assigns[:token]
@@ -28,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
@@ -47,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(
@@ -68,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/plug_helper.ex b/lib/pleroma/plugs/plug_helper.ex
new file mode 100644
index 000000000..9c67be8ef
--- /dev/null
+++ b/lib/pleroma/plugs/plug_helper.ex
@@ -0,0 +1,40 @@
+# Pleroma: A lightweight social networking server
+# Copyright © 2017-2020 Pleroma Authors <https://pleroma.social/>
+# SPDX-License-Identifier: AGPL-3.0-only
+
+defmodule Pleroma.Plugs.PlugHelper do
+ @moduledoc "Pleroma Plug helper"
+
+ @called_plugs_list_id :called_plugs
+ def called_plugs_list_id, do: @called_plugs_list_id
+
+ @skipped_plugs_list_id :skipped_plugs
+ def skipped_plugs_list_id, do: @skipped_plugs_list_id
+
+ @doc "Returns `true` if specified plug was called."
+ def plug_called?(conn, plug_module) do
+ contained_in_private_list?(conn, @called_plugs_list_id, plug_module)
+ end
+
+ @doc "Returns `true` if specified plug was explicitly marked as skipped."
+ def plug_skipped?(conn, plug_module) do
+ contained_in_private_list?(conn, @skipped_plugs_list_id, plug_module)
+ end
+
+ @doc "Returns `true` if specified plug was either called or explicitly marked as skipped."
+ def plug_called_or_skipped?(conn, plug_module) do
+ plug_called?(conn, plug_module) || plug_skipped?(conn, plug_module)
+ end
+
+ # Appends plug to known list (skipped, called). Intended to be used from within plug code only.
+ def append_to_private_list(conn, list_id, value) do
+ list = conn.private[list_id] || []
+ modified_list = Enum.uniq(list ++ [value])
+ Plug.Conn.put_private(conn, list_id, modified_list)
+ end
+
+ defp contained_in_private_list?(conn, private_variable, value) do
+ list = conn.private[private_variable] || []
+ value in list
+ end
+end
diff --git a/lib/pleroma/plugs/rate_limiter/limiter_supervisor.ex b/lib/pleroma/plugs/rate_limiter/limiter_supervisor.ex
index 187582ede..884268d96 100644
--- a/lib/pleroma/plugs/rate_limiter/limiter_supervisor.ex
+++ b/lib/pleroma/plugs/rate_limiter/limiter_supervisor.ex
@@ -7,8 +7,8 @@ defmodule Pleroma.Plugs.RateLimiter.LimiterSupervisor do
DynamicSupervisor.start_link(__MODULE__, init_arg, name: __MODULE__)
end
- def add_limiter(limiter_name, expiration) do
- {:ok, _pid} =
+ def add_or_return_limiter(limiter_name, expiration) do
+ result =
DynamicSupervisor.start_child(
__MODULE__,
%{
@@ -28,6 +28,12 @@ defmodule Pleroma.Plugs.RateLimiter.LimiterSupervisor do
]}
}
)
+
+ case result do
+ {:ok, _pid} = result -> result
+ {:error, {:already_started, pid}} -> {:ok, pid}
+ _ -> result
+ end
end
@impl true
diff --git a/lib/pleroma/plugs/rate_limiter/rate_limiter.ex b/lib/pleroma/plugs/rate_limiter/rate_limiter.ex
index 7fb92489c..c51e2c634 100644
--- a/lib/pleroma/plugs/rate_limiter/rate_limiter.ex
+++ b/lib/pleroma/plugs/rate_limiter/rate_limiter.ex
@@ -1,5 +1,5 @@
# Pleroma: A lightweight social networking server
-# Copyright © 2017-2019 Pleroma Authors <https://pleroma.social/>
+# Copyright © 2017-2020 Pleroma Authors <https://pleroma.social/>
# SPDX-License-Identifier: AGPL-3.0-only
defmodule Pleroma.Plugs.RateLimiter do
@@ -7,12 +7,14 @@ defmodule Pleroma.Plugs.RateLimiter do
## Configuration
- A keyword list of rate limiters where a key is a limiter name and value is the limiter configuration. The basic configuration is a tuple where:
+ A keyword list of rate limiters where a key is a limiter name and value is the limiter configuration.
+ The basic configuration is a tuple where:
* The first element: `scale` (Integer). The time scale in milliseconds.
* The second element: `limit` (Integer). How many requests to limit in the time scale provided.
- It is also possible to have different limits for unauthenticated and authenticated users: the keyword value must be a list of two tuples where the first one is a config for unauthenticated users and the second one is for authenticated.
+ It is also possible to have different limits for unauthenticated and authenticated users: the keyword value must be a
+ list of two tuples where the first one is a config for unauthenticated users and the second one is for authenticated.
To disable a limiter set its value to `nil`.
@@ -64,91 +66,96 @@ defmodule Pleroma.Plugs.RateLimiter do
import Pleroma.Web.TranslationHelpers
import Plug.Conn
+ alias Pleroma.Config
alias Pleroma.Plugs.RateLimiter.LimiterSupervisor
alias Pleroma.User
require Logger
- def init(opts) do
- limiter_name = Keyword.get(opts, :name)
-
- case Pleroma.Config.get([:rate_limit, limiter_name]) do
- nil ->
- nil
-
- config ->
- name_root = Keyword.get(opts, :bucket_name, limiter_name)
+ @doc false
+ def init(plug_opts) do
+ plug_opts
+ end
- %{
- name: name_root,
- limits: config,
- opts: opts
- }
+ def call(conn, plug_opts) do
+ if disabled?(conn) do
+ handle_disabled(conn)
+ else
+ action_settings = action_settings(plug_opts)
+ handle(conn, action_settings)
end
end
- # Do not limit if there is no limiter configuration
- def call(conn, nil), do: conn
+ defp handle_disabled(conn) do
+ Logger.warn(
+ "Rate limiter disabled due to forwarded IP not being found. Please ensure your reverse proxy is providing the X-Forwarded-For header or disable the RemoteIP plug/rate limiter."
+ )
- def call(conn, settings) do
- case disabled?() do
- true ->
- if Pleroma.Config.get(:env) == :prod,
- do: Logger.warn("Rate limiter is disabled for localhost/socket")
+ conn
+ end
+
+ defp handle(conn, nil), do: conn
+ defp handle(conn, action_settings) do
+ action_settings
+ |> incorporate_conn_info(conn)
+ |> check_rate()
+ |> case do
+ {:ok, _count} ->
conn
- false ->
- settings
- |> incorporate_conn_info(conn)
- |> check_rate()
- |> case do
- {:ok, _count} ->
- conn
-
- {:error, _count} ->
- render_throttled_error(conn)
- end
+ {:error, _count} ->
+ render_throttled_error(conn)
end
end
- def disabled? do
- localhost_or_socket =
- Pleroma.Config.get([Pleroma.Web.Endpoint, :http, :ip])
- |> Tuple.to_list()
- |> Enum.join(".")
- |> String.match?(~r/^local|^127.0.0.1/)
+ def disabled?(conn) do
+ if Map.has_key?(conn.assigns, :remote_ip_found),
+ do: !conn.assigns.remote_ip_found,
+ else: false
+ end
- remote_ip_disabled = not Pleroma.Config.get([Pleroma.Plugs.RemoteIp, :enabled])
+ @inspect_bucket_not_found {:error, :not_found}
- localhost_or_socket and remote_ip_disabled
- end
+ def inspect_bucket(conn, bucket_name_root, plug_opts) do
+ with %{name: _} = action_settings <- action_settings(plug_opts) do
+ action_settings = incorporate_conn_info(action_settings, conn)
+ bucket_name = make_bucket_name(%{action_settings | name: bucket_name_root})
+ key_name = make_key_name(action_settings)
+ limit = get_limits(action_settings)
- def inspect_bucket(conn, name_root, settings) do
- settings =
- settings
- |> incorporate_conn_info(conn)
+ case Cachex.get(bucket_name, key_name) do
+ {:error, :no_cache} ->
+ @inspect_bucket_not_found
- bucket_name = make_bucket_name(%{settings | name: name_root})
- key_name = make_key_name(settings)
- limit = get_limits(settings)
+ {:ok, nil} ->
+ {0, limit}
- case Cachex.get(bucket_name, key_name) do
- {:error, :no_cache} ->
- {:err, :not_found}
+ {:ok, value} ->
+ {value, limit - value}
+ end
+ else
+ _ -> @inspect_bucket_not_found
+ end
+ end
- {:ok, nil} ->
- {0, limit}
+ def action_settings(plug_opts) do
+ with limiter_name when is_atom(limiter_name) <- plug_opts[:name],
+ limits when not is_nil(limits) <- Config.get([:rate_limit, limiter_name]) do
+ bucket_name_root = Keyword.get(plug_opts, :bucket_name, limiter_name)
- {:ok, value} ->
- {value, limit - value}
+ %{
+ name: bucket_name_root,
+ limits: limits,
+ opts: plug_opts
+ }
end
end
- defp check_rate(settings) do
- bucket_name = make_bucket_name(settings)
- key_name = make_key_name(settings)
- limit = get_limits(settings)
+ defp check_rate(action_settings) do
+ bucket_name = make_bucket_name(action_settings)
+ key_name = make_key_name(action_settings)
+ limit = get_limits(action_settings)
case Cachex.get_and_update(bucket_name, key_name, &increment_value(&1, limit)) do
{:commit, value} ->
@@ -158,8 +165,8 @@ defmodule Pleroma.Plugs.RateLimiter do
{:error, value}
{:error, :no_cache} ->
- initialize_buckets(settings)
- check_rate(settings)
+ initialize_buckets!(action_settings)
+ check_rate(action_settings)
end
end
@@ -169,16 +176,19 @@ defmodule Pleroma.Plugs.RateLimiter do
defp increment_value(val, _limit), do: {:commit, val + 1}
- defp incorporate_conn_info(settings, %{assigns: %{user: %User{id: user_id}}, params: params}) do
- Map.merge(settings, %{
+ defp incorporate_conn_info(action_settings, %{
+ assigns: %{user: %User{id: user_id}},
+ params: params
+ }) do
+ Map.merge(action_settings, %{
mode: :user,
conn_params: params,
conn_info: "#{user_id}"
})
end
- defp incorporate_conn_info(settings, %{params: params} = conn) do
- Map.merge(settings, %{
+ defp incorporate_conn_info(action_settings, %{params: params} = conn) do
+ Map.merge(action_settings, %{
mode: :anon,
conn_params: params,
conn_info: "#{ip(conn)}"
@@ -197,10 +207,10 @@ defmodule Pleroma.Plugs.RateLimiter do
|> halt()
end
- defp make_key_name(settings) do
+ defp make_key_name(action_settings) do
""
- |> attach_params(settings)
- |> attach_identity(settings)
+ |> attach_selected_params(action_settings)
+ |> attach_identity(action_settings)
end
defp get_scale(_, {scale, _}), do: scale
@@ -215,28 +225,35 @@ defmodule Pleroma.Plugs.RateLimiter do
defp get_limits(%{limits: [{_, limit}, _]}), do: limit
- defp make_bucket_name(%{mode: :user, name: name_root}),
- do: user_bucket_name(name_root)
+ defp make_bucket_name(%{mode: :user, name: bucket_name_root}),
+ do: user_bucket_name(bucket_name_root)
- defp make_bucket_name(%{mode: :anon, name: name_root}),
- do: anon_bucket_name(name_root)
+ defp make_bucket_name(%{mode: :anon, name: bucket_name_root}),
+ do: anon_bucket_name(bucket_name_root)
- defp attach_params(input, %{conn_params: conn_params, opts: opts}) do
- param_string =
- opts
+ defp attach_selected_params(input, %{conn_params: conn_params, opts: plug_opts}) do
+ params_string =
+ plug_opts
|> Keyword.get(:params, [])
|> Enum.sort()
|> Enum.map(&Map.get(conn_params, &1, ""))
|> Enum.join(":")
- "#{input}#{param_string}"
+ [input, params_string]
+ |> Enum.join(":")
+ |> String.replace_leading(":", "")
end
- defp initialize_buckets(%{name: _name, limits: nil}), do: :ok
+ defp initialize_buckets!(%{name: _name, limits: nil}), do: :ok
+
+ defp initialize_buckets!(%{name: name, limits: limits}) do
+ {:ok, _pid} =
+ LimiterSupervisor.add_or_return_limiter(anon_bucket_name(name), get_scale(:anon, limits))
+
+ {:ok, _pid} =
+ LimiterSupervisor.add_or_return_limiter(user_bucket_name(name), get_scale(:user, limits))
- defp initialize_buckets(%{name: name, limits: limits}) do
- LimiterSupervisor.add_limiter(anon_bucket_name(name), get_scale(:anon, limits))
- LimiterSupervisor.add_limiter(user_bucket_name(name), get_scale(:user, limits))
+ :ok
end
defp attach_identity(base, %{mode: :user, conn_info: conn_info}),
@@ -245,6 +262,6 @@ defmodule Pleroma.Plugs.RateLimiter do
defp attach_identity(base, %{mode: :anon, conn_info: conn_info}),
do: "ip:#{base}:#{conn_info}"
- defp user_bucket_name(name_root), do: "user:#{name_root}" |> String.to_atom()
- defp anon_bucket_name(name_root), do: "anon:#{name_root}" |> String.to_atom()
+ defp user_bucket_name(bucket_name_root), do: "user:#{bucket_name_root}" |> String.to_atom()
+ defp anon_bucket_name(bucket_name_root), do: "anon:#{bucket_name_root}" |> String.to_atom()
end
diff --git a/lib/pleroma/plugs/remote_ip.ex b/lib/pleroma/plugs/remote_ip.ex
index 1cd5af48a..2eca4f8f6 100644
--- a/lib/pleroma/plugs/remote_ip.ex
+++ b/lib/pleroma/plugs/remote_ip.ex
@@ -1,5 +1,5 @@
# Pleroma: A lightweight social networking server
-# Copyright © 2017-2019 Pleroma Authors <https://pleroma.social/>
+# Copyright © 2017-2020 Pleroma Authors <https://pleroma.social/>
# SPDX-License-Identifier: AGPL-3.0-only
defmodule Pleroma.Plugs.RemoteIp do
diff --git a/lib/pleroma/plugs/session_authentication_plug.ex b/lib/pleroma/plugs/session_authentication_plug.ex
index a08484b65..0f83a5e53 100644
--- a/lib/pleroma/plugs/session_authentication_plug.ex
+++ b/lib/pleroma/plugs/session_authentication_plug.ex
@@ -1,5 +1,5 @@
# Pleroma: A lightweight social networking server
-# Copyright © 2017-2019 Pleroma Authors <https://pleroma.social/>
+# Copyright © 2017-2020 Pleroma Authors <https://pleroma.social/>
# SPDX-License-Identifier: AGPL-3.0-only
defmodule Pleroma.Plugs.SessionAuthenticationPlug do
diff --git a/lib/pleroma/plugs/set_format_plug.ex b/lib/pleroma/plugs/set_format_plug.ex
index 5ca741c64..c03fcb28d 100644
--- a/lib/pleroma/plugs/set_format_plug.ex
+++ b/lib/pleroma/plugs/set_format_plug.ex
@@ -1,5 +1,5 @@
# Pleroma: A lightweight social networking server
-# Copyright © 2017-2019 Pleroma Authors <https://pleroma.social/>
+# Copyright © 2017-2020 Pleroma Authors <https://pleroma.social/>
# SPDX-License-Identifier: AGPL-3.0-only
defmodule Pleroma.Plugs.SetFormatPlug do
diff --git a/lib/pleroma/plugs/set_locale_plug.ex b/lib/pleroma/plugs/set_locale_plug.ex
index 8646cb30d..9a21d0a9d 100644
--- a/lib/pleroma/plugs/set_locale_plug.ex
+++ b/lib/pleroma/plugs/set_locale_plug.ex
@@ -1,5 +1,5 @@
# Pleroma: A lightweight social networking server
-# Copyright © 2017-2019 Pleroma Authors <https://pleroma.social/>
+# Copyright © 2017-2020 Pleroma Authors <https://pleroma.social/>
# SPDX-License-Identifier: AGPL-3.0-only
# NOTE: this module is based on https://github.com/smeevil/set_locale
diff --git a/lib/pleroma/plugs/set_user_session_id_plug.ex b/lib/pleroma/plugs/set_user_session_id_plug.ex
index 9265cc116..730c4ac74 100644
--- a/lib/pleroma/plugs/set_user_session_id_plug.ex
+++ b/lib/pleroma/plugs/set_user_session_id_plug.ex
@@ -1,5 +1,5 @@
# Pleroma: A lightweight social networking server
-# Copyright © 2017-2019 Pleroma Authors <https://pleroma.social/>
+# Copyright © 2017-2020 Pleroma Authors <https://pleroma.social/>
# SPDX-License-Identifier: AGPL-3.0-only
defmodule Pleroma.Plugs.SetUserSessionIdPlug do
diff --git a/lib/pleroma/plugs/static_fe_plug.ex b/lib/pleroma/plugs/static_fe_plug.ex
index b3fb3c582..156e6788e 100644
--- a/lib/pleroma/plugs/static_fe_plug.ex
+++ b/lib/pleroma/plugs/static_fe_plug.ex
@@ -1,5 +1,5 @@
# Pleroma: A lightweight social networking server
-# Copyright © 2017-2019 Pleroma Authors <https://pleroma.social/>
+# Copyright © 2017-2020 Pleroma Authors <https://pleroma.social/>
# SPDX-License-Identifier: AGPL-3.0-only
defmodule Pleroma.Plugs.StaticFEPlug do
@@ -21,6 +21,9 @@ defmodule Pleroma.Plugs.StaticFEPlug do
defp enabled?, do: Pleroma.Config.get([:static_fe, :enabled], false)
defp accepts_html?(conn) do
- conn |> get_req_header("accept") |> List.first() |> String.contains?("text/html")
+ case get_req_header(conn, "accept") do
+ [accept | _] -> String.contains?(accept, "text/html")
+ _ -> false
+ end
end
end
diff --git a/lib/pleroma/plugs/trailing_format_plug.ex b/lib/pleroma/plugs/trailing_format_plug.ex
index a4b8a406d..8b4d5fc9f 100644
--- a/lib/pleroma/plugs/trailing_format_plug.ex
+++ b/lib/pleroma/plugs/trailing_format_plug.ex
@@ -1,5 +1,5 @@
# Pleroma: A lightweight social networking server
-# Copyright © 2017-2019 Pleroma Authors <https://pleroma.social/>
+# Copyright © 2017-2020 Pleroma Authors <https://pleroma.social/>
# SPDX-License-Identifier: AGPL-3.0-only
defmodule Pleroma.Plugs.TrailingFormatPlug do
diff --git a/lib/pleroma/plugs/uploaded_media.ex b/lib/pleroma/plugs/uploaded_media.ex
index 69c1ab942..94147e0c4 100644
--- a/lib/pleroma/plugs/uploaded_media.ex
+++ b/lib/pleroma/plugs/uploaded_media.ex
@@ -1,5 +1,5 @@
# Pleroma: A lightweight social networking server
-# Copyright © 2017-2019 Pleroma Authors <https://pleroma.social/>
+# Copyright © 2017-2020 Pleroma Authors <https://pleroma.social/>
# SPDX-License-Identifier: AGPL-3.0-only
defmodule Pleroma.Plugs.UploadedMedia do
@@ -14,9 +14,14 @@ defmodule Pleroma.Plugs.UploadedMedia do
# no slashes
@path "media"
+ @default_cache_control_header "public, max-age=1209600"
+
def init(_opts) do
static_plug_opts =
- []
+ [
+ headers: %{"cache-control" => @default_cache_control_header},
+ cache_control_for_etags: @default_cache_control_header
+ ]
|> Keyword.put(:from, "__unconfigured_media_plug")
|> Keyword.put(:at, "/__unconfigured_media_plug")
|> Plug.Static.init()
@@ -36,6 +41,7 @@ defmodule Pleroma.Plugs.UploadedMedia do
conn ->
conn
end
+ |> merge_resp_headers([{"content-security-policy", "sandbox"}])
config = Pleroma.Config.get(Pleroma.Upload)
diff --git a/lib/pleroma/plugs/user_enabled_plug.ex b/lib/pleroma/plugs/user_enabled_plug.ex
index 7b304eebc..23e800a74 100644
--- a/lib/pleroma/plugs/user_enabled_plug.ex
+++ b/lib/pleroma/plugs/user_enabled_plug.ex
@@ -1,5 +1,5 @@
# Pleroma: A lightweight social networking server
-# Copyright © 2017-2019 Pleroma Authors <https://pleroma.social/>
+# Copyright © 2017-2020 Pleroma Authors <https://pleroma.social/>
# SPDX-License-Identifier: AGPL-3.0-only
defmodule Pleroma.Plugs.UserEnabledPlug do
diff --git a/lib/pleroma/plugs/user_fetcher_plug.ex b/lib/pleroma/plugs/user_fetcher_plug.ex
index 4089aa958..235c77d85 100644
--- a/lib/pleroma/plugs/user_fetcher_plug.ex
+++ b/lib/pleroma/plugs/user_fetcher_plug.ex
@@ -1,5 +1,5 @@
# Pleroma: A lightweight social networking server
-# Copyright © 2017-2019 Pleroma Authors <https://pleroma.social/>
+# Copyright © 2017-2020 Pleroma Authors <https://pleroma.social/>
# SPDX-License-Identifier: AGPL-3.0-only
defmodule Pleroma.Plugs.UserFetcherPlug do
diff --git a/lib/pleroma/plugs/user_is_admin_plug.ex b/lib/pleroma/plugs/user_is_admin_plug.ex
index 3190163d3..2748102df 100644
--- a/lib/pleroma/plugs/user_is_admin_plug.ex
+++ b/lib/pleroma/plugs/user_is_admin_plug.ex
@@ -1,5 +1,5 @@
# Pleroma: A lightweight social networking server
-# Copyright © 2017-2019 Pleroma Authors <https://pleroma.social/>
+# Copyright © 2017-2020 Pleroma Authors <https://pleroma.social/>
# SPDX-License-Identifier: AGPL-3.0-only
defmodule Pleroma.Plugs.UserIsAdminPlug do