Files

126 lines
2.5 KiB
Elixir
Raw Permalink Normal View History

defmodule Claper.Audit do
@moduledoc """
The Audit context for tracking actions in the system.
"""
import Ecto.Query, only: [from: 2]
alias Claper.{Accounts, Repo}
alias Claper.Audit.Log
@doc """
Logs an action.
## Examples
iex> log_action(user, "user.login", %{ip_address: "127.0.0.1"})
{:ok, %Log{}}
iex> log_action(nil, "system.startup", %{})
{:ok, %Log{}}
"""
def log_action(user, action, metadata \\ %{})
def log_action(%Accounts.User{} = user, action, metadata) do
create_log(%{
user_id: user.id,
action: action,
metadata: metadata
})
end
def log_action(nil, action, metadata) do
create_log(%{
action: action,
metadata: metadata
})
end
@doc """
Logs an action related to a specific resource.
## Examples
iex> log_resource_action(user, "event.create", "event", 123, %{})
{:ok, %Log{}}
"""
def log_resource_action(
%Accounts.User{} = user,
action,
resource_type,
resource_id,
metadata \\ %{}
) do
create_log(%{
user_id: user.id,
action: action,
resource_type: resource_type,
resource_id: resource_id,
metadata: metadata
})
end
@doc """
Returns a paginated, optionally filtered and sorted, list of audit logs.
"""
def list_logs(params \\ %{}) do
query = from l in Log, left_join: u in assoc(l, :user), as: :user, preload: [user: u]
Flop.validate_and_run!(query, params, for: Log, replace_invalid_params: true)
end
@doc """
Returns a list of distinct action types for filtering.
"""
def list_action_types do
from(l in Log,
distinct: true,
select: l.action,
order_by: l.action
)
|> Repo.all()
end
@doc """
Gets a single log.
Raises `Ecto.NoResultsError` if the Log does not exist.
## Examples
iex> get_log!(123)
%Log{}
iex> get_log!(456)
** (Ecto.NoResultsError)
"""
def get_log!(id) do
Repo.one!(
from l in Log, left_join: u in assoc(l, :user), where: l.id == ^id, preload: [user: u]
)
end
@doc """
Creates a log entry.
This is a simple wrapper over a low-level insert. You likely want to use
`log_action/3` and `log_resource_action/5` instead.
## Examples
iex> create_log(%{action: "user.login"})
{:ok, %Log{}}
iex> create_log(%{action: nil})
{:error, %Ecto.Changeset{}}
"""
def create_log(attrs \\ %{}) do
%Log{}
|> Log.changeset(attrs)
|> Repo.insert()
end
end