Packages
ash_authentication
5.0.0-rc.6
5.0.0-rc.12
5.0.0-rc.11
5.0.0-rc.10
5.0.0-rc.9
5.0.0-rc.8
5.0.0-rc.7
5.0.0-rc.6
5.0.0-rc.5
5.0.0-rc.4
5.0.0-rc.3
5.0.0-rc.2
5.0.0-rc.1
5.0.0-rc.0
4.14.1
4.14.0
4.13.7
4.13.6
4.13.5
4.13.4
4.13.3
4.13.2
retired
4.13.1
retired
4.13.0
4.12.0
4.11.0
4.10.0
4.9.9
4.9.8
4.9.7
4.9.6
4.9.5
4.9.4
4.9.3
4.9.2
4.9.1
4.9.0
4.8.7
4.8.6
4.8.5
4.8.3
4.8.2
4.8.1
4.8.0
4.7.6
4.7.5
4.7.4
4.7.3
4.7.2
4.7.1
4.7.0
4.6.4
4.6.3
4.6.2
4.6.1
4.6.0
4.5.6
4.5.5
4.5.4
4.5.3
4.5.2
4.5.1
4.5.0
4.4.9
4.4.8
4.4.7
4.4.6
4.4.5
4.4.4
4.4.3
4.4.2
4.4.1
4.4.0
4.3.12
4.3.11
4.3.10
4.3.9
4.3.8
4.3.7
4.3.6
4.3.5
4.3.4
4.3.3
4.3.2
4.3.1
4.3.0
4.2.7
4.2.6
4.2.5
4.2.4
4.2.3
4.2.2
4.2.1
4.2.0
4.1.0
4.0.4
4.0.3
4.0.2
4.0.1
4.0.0
4.0.0-rc.6
4.0.0-rc.5
4.0.0-rc.3
4.0.0-rc.2
4.0.0-rc.1
4.0.0-rc.0
3.12.4
3.12.3
3.12.2
3.12.1
3.12.0
3.11.16
3.11.15
3.11.14
3.11.13
3.11.12
3.11.11
3.11.10
3.11.9
3.11.8
3.11.7
3.11.6
3.11.5
3.11.4
3.11.3
3.11.2
3.11.1
3.11.0
3.10.8
3.10.7
3.10.6
3.10.5
3.10.4
3.10.3
3.10.2
3.10.1
3.10.0
3.9.6
3.9.5
3.9.4
3.9.3
3.9.2
3.9.1
3.9.0
3.8.0
3.7.9
3.7.8
3.7.6
3.7.5
3.7.4
3.7.3
3.7.2
3.7.1
3.7.0
3.6.1
3.6.0
3.5.3
3.5.2
3.5.1
3.5.0
3.3.1
3.3.0
3.2.2
3.2.1
3.2.0
3.1.0
3.0.3
Authentication extension for the Ash Framework.
Security advisory:
This version has known vulnerabilities.
View advisories
Current section
Files
Jump to
Current section
Files
lib/ash_authentication/audit_log_resource/expunger.ex
# SPDX-FileCopyrightText: 2022 Alembic Pty Ltd
#
# SPDX-License-Identifier: MIT
defmodule AshAuthentication.AuditLogResource.Expunger do
@moduledoc """
A `GenServer` which removes old audit log entries once they're no longer relevant.
Scans all audit log resources based on their configured lifetime options.
```elixir
defmodule MyApp.Accounts.AuditLog do
use Ash.Resource,
extensions: [AshAuthentication.AuditLogResource],
domain: MyApp.Accounts
audit_log do
log_lifetime 90 # days
expunge_interval 12 # hours
end
end
```
This GenServer is started by the `AshAuthentication.Supervisor` which should be added to your app's supervision tree.
"""
use GenServer
alias AshAuthentication.AuditLogResource
alias AshAuthentication.AuditLogResource.Info
require Ash.Query
@hibernate_timeout :timer.seconds(5)
@doc false
def start_link(opts), do: GenServer.start_link(__MODULE__, opts)
@doc false
@impl true
def init(opts) do
opts
|> Keyword.fetch!(:otp_app)
|> Spark.sparks(Ash.Resource)
|> Stream.filter(&(AuditLogResource in Spark.extensions(&1)))
|> Enum.reduce([], fn resource, configs ->
with {:ok, lifetime_days} when is_integer(lifetime_days) and lifetime_days > 0 <-
Info.audit_log_log_lifetime(resource),
{:ok, sweep_hrs} <- Info.audit_log_expunge_interval(resource),
{:ok, action_name} <- Info.audit_log_destroy_action_name(resource),
{:ok, logged_at} <- Info.audit_log_attributes_logged_at(resource) do
timer = Process.send_after(self(), {:expunge, resource}, :timer.hours(sweep_hrs))
config = %{
lifetime: lifetime_days,
interval: sweep_hrs,
resource: resource,
action_name: action_name,
timer: timer,
logged_at: logged_at
}
[config | configs]
else
_ -> configs
end
end)
|> case do
[] -> :ignore
configs -> {:ok, Map.new(configs, &{&1.resource, &1}), @hibernate_timeout}
end
end
@doc false
@impl true
def handle_info({:expunge, resource}, state) do
state
|> Map.get(resource)
|> case do
nil ->
{:noreply, state, :hibernate}
config ->
logged_at = config.logged_at
lifetime = config.lifetime
import Ash.Expr
resource
|> Ash.Query.set_context(%{private: %{ash_authentication?: true}})
|> Ash.Query.filter(^ref(logged_at) <= ago(^lifetime, :day))
|> Ash.bulk_destroy(config.action_name, %{}, authorize?: false)
timer = Process.send_after(self(), {:expunge, resource}, :timer.hours(config.interval))
state = Map.put(state, resource, %{config | timer: timer})
{:noreply, state, @hibernate_timeout}
end
end
def handle_info(:timeout, state), do: {:noreply, state, :hibernate}
end