diff options
Diffstat (limited to 'lib')
| -rw-r--r-- | lib/pleroma/plugs/authentication_plug.ex | 6 | ||||
| -rw-r--r-- | lib/pleroma/plugs/legacy_authentication_plug.ex | 3 | ||||
| -rw-r--r-- | lib/pleroma/plugs/plug_helper.ex | 24 | ||||
| -rw-r--r-- | lib/pleroma/web/web.ex | 28 | 
4 files changed, 42 insertions, 19 deletions
| diff --git a/lib/pleroma/plugs/authentication_plug.ex b/lib/pleroma/plugs/authentication_plug.ex index 089028d77..0061c69dc 100644 --- a/lib/pleroma/plugs/authentication_plug.ex +++ b/lib/pleroma/plugs/authentication_plug.ex @@ -4,8 +4,11 @@  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 @@ -37,6 +40,7 @@ defmodule Pleroma.Plugs.AuthenticationPlug do      if Pbkdf2.checkpw(password, password_hash) do        conn        |> assign(:user, auth_user) +      |> OAuthScopesPlug.skip_plug()      else        conn      end diff --git a/lib/pleroma/plugs/legacy_authentication_plug.ex b/lib/pleroma/plugs/legacy_authentication_plug.ex index 5c5c36c56..d346e01a6 100644 --- a/lib/pleroma/plugs/legacy_authentication_plug.ex +++ b/lib/pleroma/plugs/legacy_authentication_plug.ex @@ -4,6 +4,8 @@  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/plug_helper.ex b/lib/pleroma/plugs/plug_helper.ex index 4f83e9414..9c67be8ef 100644 --- a/lib/pleroma/plugs/plug_helper.ex +++ b/lib/pleroma/plugs/plug_helper.ex @@ -5,30 +5,32 @@  defmodule Pleroma.Plugs.PlugHelper do    @moduledoc "Pleroma Plug helper" -  def append_to_called_plugs(conn, plug_module) do -    append_to_private_list(conn, :called_plugs, plug_module) -  end +  @called_plugs_list_id :called_plugs +  def called_plugs_list_id, do: @called_plugs_list_id -  def append_to_skipped_plugs(conn, plug_module) do -    append_to_private_list(conn, :skipped_plugs, plug_module) -  end +  @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, plug_module) +    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, plug_module) +    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 -  defp append_to_private_list(conn, private_variable, value) do -    list = conn.private[private_variable] || [] +  # 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, private_variable, modified_list) +    Plug.Conn.put_private(conn, list_id, modified_list)    end    defp contained_in_private_list?(conn, private_variable, value) do diff --git a/lib/pleroma/web/web.ex b/lib/pleroma/web/web.ex index ae7c94640..bf48ce26c 100644 --- a/lib/pleroma/web/web.ex +++ b/lib/pleroma/web/web.ex @@ -40,17 +40,22 @@ defmodule Pleroma.Web do        # 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.ensure_skippable() +          plug_module.skip_plug(conn)          rescue            UndefinedFunctionError ->              raise "#{plug_module} is not skippable. Append `use Pleroma.Web, :plug` to its code."          end - -        PlugHelper.append_to_skipped_plugs(conn, plug_module)        end -      # Here we can apply before-action hooks (e.g. verify whether auth checks were preformed) +      # 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 @@ -60,7 +65,7 @@ defmodule Pleroma.Web do            )            |> halt()          else -          super(conn, params) +          conn          end        end      end @@ -129,7 +134,16 @@ defmodule Pleroma.Web do      quote do        alias Pleroma.Plugs.PlugHelper -      def ensure_skippable, do: :noop +      @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." @@ -138,7 +152,7 @@ defmodule Pleroma.Web do            conn          else            conn -          |> PlugHelper.append_to_called_plugs(__MODULE__) +          |> PlugHelper.append_to_private_list(PlugHelper.called_plugs_list_id(), __MODULE__)            |> perform(options)          end        end | 
