defmodule PhilomenaWeb.ModerationLogPlug do @moduledoc """ This plug writes moderation logs. ## Example plug PhilomenaWeb.ModerationLogPlug, [details: &log_details/2] """ @controller_regex ~r/PhilomenaWeb\.([\w\.]+)Controller\z/ alias Plug.Conn alias Phoenix.Controller alias Philomena.ModerationLogs @doc false @spec init(any()) :: any() def init(opts), do: opts @type log_details :: %{subject_path: String.t(), body: String.t()} @type details_func :: (Plug.Conn.t(), atom(), any() -> log_details()) @type call_opts :: [details: details_func, data: any()] @doc false @spec call(Conn.t(), call_opts) :: Conn.t() def call(conn, opts) do details_func = Keyword.fetch!(opts, :details) userdata = Keyword.get(opts, :data, nil) user = conn.assigns.current_user action = Controller.action_name(conn) %{subject_path: subject_path, body: body} = details_func.(conn, action, userdata) mod = Controller.controller_module(conn) [mod_name] = Regex.run(@controller_regex, to_string(mod), capture: :all_but_first) type = "#{mod_name}:#{action}" ModerationLogs.create_moderation_log(user, type, subject_path, body) conn end @doc false @spec moderation_log(Conn.t(), call_opts()) :: Conn.t() def moderation_log(conn, opts), do: call(conn, opts) end