philomena/lib/philomena_web/plugs/moderation_log_plug.ex
2024-06-23 10:45:37 -04:00

46 lines
1.3 KiB
Elixir

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 :: (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.(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