X-Git-Url: http://git.squeep.com/?a=blobdiff_plain;f=lib%2Fpleroma%2Fweb%2Fweb.ex;h=bf48ce26c8380202b9208095aed92f9d072abf7a;hb=2430b9bf90d6fde71885f5f0f8be767526be6208;hp=4bf07a6ef6eba6d6207a70532ec59507a125dc96;hpb=fd46edb473441fcf75492da4fcd30836d3382a0f;p=akkoma diff --git a/lib/pleroma/web/web.ex b/lib/pleroma/web/web.ex index 4bf07a6ef..bf48ce26c 100644 --- a/lib/pleroma/web/web.ex +++ b/lib/pleroma/web/web.ex @@ -1,5 +1,5 @@ # Pleroma: A lightweight social networking server -# Copyright © 2017-2019 Pleroma Authors +# Copyright © 2017-2020 Pleroma Authors # SPDX-License-Identifier: AGPL-3.0-only defmodule Pleroma.Web do @@ -23,11 +23,51 @@ defmodule Pleroma.Web do def controller do quote do use Phoenix.Controller, namespace: Pleroma.Web + import Plug.Conn import Pleroma.Web.Gettext import Pleroma.Web.Router.Helpers + import Pleroma.Web.TranslationHelpers + + alias Pleroma.Plugs.PlugHelper + + plug(:set_put_layout) - plug(:put_layout, Application.get_env(:pleroma, :app_layout, "app.html")) + 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 @@ -52,10 +92,10 @@ defmodule Pleroma.Web do rescue error -> Logger.error( - "#{__MODULE__} failed to render #{inspect({view, template})}: #{inspect(error)}" + "#{__MODULE__} failed to render #{inspect({view, template})}\n" <> + Exception.format(:error, error, __STACKTRACE__) ) - Logger.error(inspect(__STACKTRACE__)) nil end @@ -90,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. """