Apply suggestion to lib/pleroma/web/activity_pub/activity_pub.ex
[akkoma] / lib / pleroma / web / web.ex
1 # Pleroma: A lightweight social networking server
2 # Copyright © 2017-2020 Pleroma Authors <https://pleroma.social/>
3 # SPDX-License-Identifier: AGPL-3.0-only
4
5 defmodule Pleroma.Web do
6 @moduledoc """
7 A module that keeps using definitions for controllers,
8 views and so on.
9
10 This can be used in your application as:
11
12 use Pleroma.Web, :controller
13 use Pleroma.Web, :view
14
15 The definitions below will be executed for every view,
16 controller, etc, so keep them short and clean, focused
17 on imports, uses and aliases.
18
19 Do NOT define functions inside the quoted expressions
20 below.
21 """
22
23 def controller do
24 quote do
25 use Phoenix.Controller, namespace: Pleroma.Web
26
27 import Plug.Conn
28 import Pleroma.Web.Gettext
29 import Pleroma.Web.Router.Helpers
30 import Pleroma.Web.TranslationHelpers
31
32 alias Pleroma.Plugs.PlugHelper
33
34 plug(:set_put_layout)
35
36 defp set_put_layout(conn, _) do
37 put_layout(conn, Pleroma.Config.get(:app_layout, "app.html"))
38 end
39
40 # Marks a plug intentionally skipped and blocks its execution if it's present in plugs chain
41 defp skip_plug(conn, plug_module) do
42 try do
43 plug_module.ensure_skippable()
44 rescue
45 UndefinedFunctionError ->
46 raise "#{plug_module} is not skippable. Append `use Pleroma.Web, :plug` to its code."
47 end
48
49 PlugHelper.append_to_skipped_plugs(conn, plug_module)
50 end
51
52 # Here we can apply before-action hooks (e.g. verify whether auth checks were preformed)
53 defp action(conn, params) do
54 if Pleroma.Plugs.AuthExpectedPlug.auth_expected?(conn) &&
55 not PlugHelper.plug_called_or_skipped?(conn, Pleroma.Plugs.OAuthScopesPlug) do
56 conn
57 |> render_error(
58 :forbidden,
59 "Security violation: OAuth scopes check was neither handled nor explicitly skipped."
60 )
61 |> halt()
62 else
63 super(conn, params)
64 end
65 end
66 end
67 end
68
69 def view do
70 quote do
71 use Phoenix.View,
72 root: "lib/pleroma/web/templates",
73 namespace: Pleroma.Web
74
75 # Import convenience functions from controllers
76 import Phoenix.Controller, only: [get_csrf_token: 0, get_flash: 2, view_module: 1]
77
78 import Pleroma.Web.ErrorHelpers
79 import Pleroma.Web.Gettext
80 import Pleroma.Web.Router.Helpers
81
82 require Logger
83
84 @doc "Same as `render/3` but wrapped in a rescue block"
85 def safe_render(view, template, assigns \\ %{}) do
86 Phoenix.View.render(view, template, assigns)
87 rescue
88 error ->
89 Logger.error(
90 "#{__MODULE__} failed to render #{inspect({view, template})}\n" <>
91 Exception.format(:error, error, __STACKTRACE__)
92 )
93
94 nil
95 end
96
97 @doc """
98 Same as `render_many/4` but wrapped in rescue block.
99 """
100 def safe_render_many(collection, view, template, assigns \\ %{}) do
101 Enum.map(collection, fn resource ->
102 as = Map.get(assigns, :as) || view.__resource__
103 assigns = Map.put(assigns, as, resource)
104 safe_render(view, template, assigns)
105 end)
106 |> Enum.filter(& &1)
107 end
108 end
109 end
110
111 def router do
112 quote do
113 use Phoenix.Router
114 # credo:disable-for-next-line Credo.Check.Consistency.MultiAliasImportRequireUse
115 import Plug.Conn
116 import Phoenix.Controller
117 end
118 end
119
120 def channel do
121 quote do
122 # credo:disable-for-next-line Credo.Check.Consistency.MultiAliasImportRequireUse
123 use Phoenix.Channel
124 import Pleroma.Web.Gettext
125 end
126 end
127
128 def plug do
129 quote do
130 alias Pleroma.Plugs.PlugHelper
131
132 def ensure_skippable, do: :noop
133
134 @impl Plug
135 @doc "If marked as skipped, returns `conn`, and calls `perform/2` otherwise."
136 def call(%Plug.Conn{} = conn, options) do
137 if PlugHelper.plug_skipped?(conn, __MODULE__) do
138 conn
139 else
140 conn
141 |> PlugHelper.append_to_called_plugs(__MODULE__)
142 |> perform(options)
143 end
144 end
145 end
146 end
147
148 @doc """
149 When used, dispatch to the appropriate controller/view/etc.
150 """
151 defmacro __using__(which) when is_atom(which) do
152 apply(__MODULE__, which, [])
153 end
154
155 def base_url do
156 Pleroma.Web.Endpoint.url()
157 end
158 end