summaryrefslogtreecommitdiff
path: root/lib/pleroma/web/web.ex
diff options
context:
space:
mode:
Diffstat (limited to 'lib/pleroma/web/web.ex')
-rw-r--r--lib/pleroma/web/web.ex63
1 files changed, 63 insertions, 0 deletions
diff --git a/lib/pleroma/web/web.ex b/lib/pleroma/web/web.ex
index cf3ac1287..bf48ce26c 100644
--- a/lib/pleroma/web/web.ex
+++ b/lib/pleroma/web/web.ex
@@ -29,11 +29,45 @@ defmodule Pleroma.Web do
import Pleroma.Web.Router.Helpers
import Pleroma.Web.TranslationHelpers
+ alias Pleroma.Plugs.PlugHelper
+
plug(:set_put_layout)
defp set_put_layout(conn, _) do
put_layout(conn, Pleroma.Config.get(:app_layout, "app.html"))
end
+
+ # Marks a plug intentionally skipped and blocks its execution if it's present in plugs chain
+ defp skip_plug(conn, plug_module) do
+ try do
+ plug_module.skip_plug(conn)
+ rescue
+ UndefinedFunctionError ->
+ raise "#{plug_module} is not skippable. Append `use Pleroma.Web, :plug` to its code."
+ end
+ end
+
+ # Executed just before actual controller action, invokes before-action hooks (callbacks)
+ defp action(conn, params) do
+ with %Plug.Conn{halted: false} <- maybe_halt_on_missing_oauth_scopes_check(conn) do
+ super(conn, params)
+ end
+ end
+
+ # Halts if authenticated API action neither performs nor explicitly skips OAuth scopes check
+ defp maybe_halt_on_missing_oauth_scopes_check(conn) do
+ if Pleroma.Plugs.AuthExpectedPlug.auth_expected?(conn) &&
+ not PlugHelper.plug_called_or_skipped?(conn, Pleroma.Plugs.OAuthScopesPlug) do
+ conn
+ |> render_error(
+ :forbidden,
+ "Security violation: OAuth scopes check was neither handled nor explicitly skipped."
+ )
+ |> halt()
+ else
+ conn
+ end
+ end
end
end
@@ -96,6 +130,35 @@ defmodule Pleroma.Web do
end
end
+ def plug do
+ quote do
+ alias Pleroma.Plugs.PlugHelper
+
+ @doc """
+ Marks a plug intentionally skipped and blocks its execution if it's present in plugs chain.
+ """
+ def skip_plug(conn) do
+ PlugHelper.append_to_private_list(
+ conn,
+ PlugHelper.skipped_plugs_list_id(),
+ __MODULE__
+ )
+ end
+
+ @impl Plug
+ @doc "If marked as skipped, returns `conn`, and calls `perform/2` otherwise."
+ def call(%Plug.Conn{} = conn, options) do
+ if PlugHelper.plug_skipped?(conn, __MODULE__) do
+ conn
+ else
+ conn
+ |> PlugHelper.append_to_private_list(PlugHelper.called_plugs_list_id(), __MODULE__)
+ |> perform(options)
+ end
+ end
+ end
+ end
+
@doc """
When used, dispatch to the appropriate controller/view/etc.
"""