Enforcement of OAuth scopes check for authenticated API endpoints, :skip_plug plug...
[akkoma] / lib / pleroma / web / web.ex
index 30558e6926ad601355372e544e688e629a28b682..1af29ce788bcdadffb18871f372e1e76c256c252 100644 (file)
@@ -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 do
@@ -23,8 +23,40 @@ defmodule Pleroma.Web do
   def controller do
     quote do
       use Phoenix.Controller, namespace: Pleroma.Web
+
       import Plug.Conn
-      import Pleroma.Web.{Gettext, Router.Helpers}
+      import Pleroma.Web.Gettext
+      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 as intentionally skipped
+      #   (states that the plug is not called for a good reason, not by a mistake)
+      defp skip_plug(conn, plug_module) do
+        PlugHelper.append_to_skipped_plugs(conn, plug_module)
+      end
+
+      # Here we can apply before-action hooks (e.g. verify whether auth checks were preformed)
+      defp action(conn, params) do
+        if conn.private[:auth_expected] &&
+             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
+          super(conn, params)
+        end
+      end
     end
   end
 
@@ -37,7 +69,9 @@ defmodule Pleroma.Web do
       # Import convenience functions from controllers
       import Phoenix.Controller, only: [get_csrf_token: 0, get_flash: 2, view_module: 1]
 
-      import Pleroma.Web.{ErrorHelpers, Gettext, Router.Helpers}
+      import Pleroma.Web.ErrorHelpers
+      import Pleroma.Web.Gettext
+      import Pleroma.Web.Router.Helpers
 
       require Logger
 
@@ -47,10 +81,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
 
@@ -71,6 +105,7 @@ defmodule Pleroma.Web do
   def router do
     quote do
       use Phoenix.Router
+      # credo:disable-for-next-line Credo.Check.Consistency.MultiAliasImportRequireUse
       import Plug.Conn
       import Phoenix.Controller
     end
@@ -78,6 +113,7 @@ defmodule Pleroma.Web do
 
   def channel do
     quote do
+      # credo:disable-for-next-line Credo.Check.Consistency.MultiAliasImportRequireUse
       use Phoenix.Channel
       import Pleroma.Web.Gettext
     end