Packages
ash_authentication
5.0.0-rc.8
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/mix/tasks/ash_authentication.add_add_on.audit_log.ex
# SPDX-FileCopyrightText: 2022 Alembic Pty Ltd
#
# SPDX-License-Identifier: MIT
# credo:disable-for-this-file Credo.Check.Design.AliasUsage
if Code.ensure_loaded?(Igniter) do
defmodule Mix.Tasks.AshAuthentication.AddAddOn.AuditLog do
use Igniter.Mix.Task
@example "mix ash_authentication.add_add_on.audit_log"
@shortdoc "Adds an audit log add-on to your user resource"
@moduledoc """
#{@shortdoc}
Track authentication events for security and compliance.
## Example
```bash
#{@example}
```
## Options
* `--user`, `-u` - The user resource. Defaults to `YourApp.Accounts.User`
* `--audit-log`, `-a` - The audit log resource name. Defaults to `<domain>.AuditLog`.
* `--include-fields` - Comma-separated list of sensitive fields to include in audit logs.
* `--exclude-strategies` - Comma-separated list of authentication strategies to exclude from logging.
* `--exclude-actions` - Comma-separated list of actions to exclude from logging.
"""
def info(_argv, _composing_task) do
%Igniter.Mix.Task.Info{
group: :ash,
example: @example,
extra_args?: false,
only: nil,
positional: [],
schema: [
user: :string,
audit_log: :string,
include_fields: :csv,
exclude_strategies: :csv,
exclude_actions: :csv
],
aliases: [
u: :user,
a: :audit_log
]
}
end
def igniter(igniter) do
default_user = Igniter.Project.Module.module_name(igniter, "Accounts.User")
options =
igniter.args.options
|> Keyword.update(:user, default_user, &Igniter.Project.Module.parse/1)
case Igniter.Project.Module.module_exists(igniter, options[:user]) do
{true, igniter} ->
igniter
|> audit_log(options)
|> Ash.Igniter.codegen("add_audit_log")
{false, igniter} ->
Igniter.add_issue(igniter, """
User module #{inspect(options[:user])} was not found.
Perhaps you have not yet installed ash_authentication?
""")
end
end
defp audit_log(igniter, options) do
audit_log_resource =
if audit_log = options[:audit_log] do
Igniter.Project.Module.parse(audit_log)
else
options[:user]
|> Module.split()
|> :lists.droplast()
|> Enum.concat([AuditLog])
|> Module.concat()
end
{exists?, igniter} = Igniter.Project.Module.module_exists(igniter, audit_log_resource)
if exists? do
Igniter.add_issue(
igniter,
"""
Audit log resource already exists: #{inspect(audit_log_resource)}.
Please use the `--audit-log` option to provide a different name.
"""
)
else
otp_app = Igniter.Project.Application.app_name(igniter)
extensions =
cond do
Code.ensure_loaded?(AshPostgres.DataLayer) ->
"postgres"
Code.ensure_loaded?(AshSqlite.DataLayer) ->
"sqlite"
true ->
nil
end
domain =
options[:user]
|> Module.split()
|> :lists.droplast()
|> Module.concat()
{igniter, resource_args, _repo} = data_layer_args(igniter, options)
resource_args =
if extensions do
resource_args ++ ["--extend", extensions, "--domain", inspect(domain)]
else
resource_args ++ ["--domain", inspect(domain)]
end
igniter
|> Igniter.compose_task("ash.gen.resource", [
inspect(audit_log_resource),
"--default-actions",
"read"
| resource_args
])
|> Igniter.compose_task("ash.extend", [
inspect(audit_log_resource),
"AshAuthentication.AuditLogResource"
])
|> add_audit_log_add_on(options[:user], audit_log_resource, options)
|> ensure_supervisor(otp_app)
end
end
defp add_audit_log_add_on(igniter, user_resource, audit_log_resource, options) do
include_fields = options[:include_fields] || []
exclude_strategies = options[:exclude_strategies] || []
exclude_actions = options[:exclude_actions] || []
include_fields_config =
if include_fields != [] do
fields = Enum.map_join(include_fields, ", ", &":#{&1}")
"include_fields [#{fields}]"
else
""
end
exclude_strategies_config =
if exclude_strategies != [] do
strategies = Enum.map_join(exclude_strategies, ", ", &":#{&1}")
"exclude_strategies [#{strategies}]"
else
""
end
exclude_actions_config =
if exclude_actions != [] do
actions = Enum.map_join(exclude_actions, ", ", &":#{&1}")
"exclude_actions [#{actions}]"
else
""
end
configs =
[include_fields_config, exclude_strategies_config, exclude_actions_config]
|> Enum.reject(&(&1 == ""))
|> Enum.join("\n ")
configs_section = if configs != "", do: "\n #{configs}", else: ""
AshAuthentication.Igniter.add_new_add_on(
igniter,
user_resource,
:audit_log,
nil,
"""
audit_log do
audit_log_resource #{inspect(audit_log_resource)}#{configs_section}
end
"""
)
end
defp ensure_supervisor(igniter, otp_app) do
Igniter.Project.Application.add_new_child(
igniter,
{AshAuthentication.Supervisor, otp_app: otp_app},
after: fn _ -> true end
)
end
cond do
Code.ensure_loaded?(AshPostgres.Igniter) ->
def data_layer_args(igniter, opts) do
{igniter, repo} =
AshPostgres.Igniter.select_repo(igniter, generate?: false, yes: opts[:yes])
{igniter, ["--repo", inspect(repo)], repo}
end
Code.ensure_loaded?(AshSqlite.Igniter) ->
def data_layer_args(igniter, opts) do
{igniter, repo} =
AshSqlite.Igniter.select_repo(igniter, generate?: false, yes: opts[:yes])
{igniter, ["--repo", inspect(repo)], repo}
end
true ->
def data_layer_args(igniter, _) do
{igniter, [], nil}
end
end
end
else
defmodule Mix.Tasks.AshAuthentication.AddAddOn.AuditLog do
@shortdoc "Adds an audit log add-on to your user resource"
@moduledoc @shortdoc
use Mix.Task
def run(_argv) do
Mix.shell().error("""
The task 'ash_authentication.add_add_on.audit_log' requires igniter to be run.
Please install igniter and try again.
For more information, see: https://hexdocs.pm/igniter
""")
exit({:shutdown, 1})
end
end
end