Packages
ash_authentication
4.0.0-rc.0
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/strategies/custom/transformer.ex
defmodule AshAuthentication.Strategy.Custom.Transformer do
@moduledoc """
Transformer used by custom strategies.
It delegates transformation passes to the individual strategies.
"""
use Spark.Dsl.Transformer
alias AshAuthentication.{Info, Strategy}
alias Spark.{Dsl.Transformer, Error.DslError}
import AshAuthentication.Strategy.Custom.Helpers
@doc false
@impl true
@spec after?(module) :: boolean
def after?(AshAuthentication.Transformer), do: true
def after?(_), do: false
@doc false
@impl true
@spec before?(module) :: boolean
def before?(Resource.Transformers.DefaultAccept), do: true
def before?(_), do: false
@doc false
@impl true
@spec transform(map) ::
:ok
| {:ok, map()}
| {:error, term()}
| {:warn, map(), String.t() | [String.t()]}
| :halt
def transform(dsl_state) do
with {:ok, dsl_state} <- do_strategy_transforms(dsl_state) do
do_add_on_transforms(dsl_state)
end
end
defp do_strategy_transforms(dsl_state) do
dsl_state
|> Info.authentication_strategies()
|> Enum.reduce_while({:ok, dsl_state}, fn strategy, {:ok, dsl_state} ->
case do_transform(strategy, dsl_state, :strategy) do
{:ok, dsl_state} -> {:cont, {:ok, dsl_state}}
{:error, reason} -> {:halt, {:error, reason}}
end
end)
end
defp do_add_on_transforms(dsl_state) do
dsl_state
|> Info.authentication_add_ons()
|> Enum.reduce_while({:ok, dsl_state}, fn strategy, {:ok, dsl_state} ->
case do_transform(strategy, dsl_state, :add_on) do
{:ok, dsl_state} -> {:cont, {:ok, dsl_state}}
{:error, reason} -> {:halt, {:error, reason}}
end
end)
end
defp do_transform(strategy, _, _) when not is_map_key(strategy, :strategy_module) do
name = Strategy.name(strategy)
{:error,
DslError.exception(
path: [:authentication, name],
message:
"The struct defined by `#{inspect(strategy.__struct__)}` must contain a `strategy_module` field."
)}
end
defp do_transform(strategy, _, _) when not is_map_key(strategy, :resource) do
name = Strategy.name(strategy)
{:error,
DslError.exception(
path: [:authentication, name],
message:
"The struct defined by `#{inspect(strategy.__struct__)}` must contain a `resource` field."
)}
end
defp do_transform(strategy, dsl_state, :strategy) do
strategy = %{strategy | resource: Transformer.get_persisted(dsl_state, :module)}
dsl_state = put_strategy(dsl_state, strategy)
entity_module = strategy.__struct__
strategy
|> strategy.strategy_module.transform(dsl_state)
|> case do
{:ok, strategy} when is_struct(strategy, entity_module) ->
{:ok, put_strategy(dsl_state, strategy)}
{:ok, dsl_state} when is_map(dsl_state) ->
{:ok, dsl_state}
{:error, reason} ->
{:error, reason}
end
end
defp do_transform(strategy, dsl_state, :add_on) do
strategy = %{strategy | resource: Transformer.get_persisted(dsl_state, :module)}
dsl_state = put_add_on(dsl_state, strategy)
entity_module = strategy.__struct__
strategy
|> strategy.strategy_module.transform(dsl_state)
|> case do
{:ok, strategy} when is_struct(strategy, entity_module) ->
{:ok, put_add_on(dsl_state, strategy)}
{:ok, dsl_state} when is_map(dsl_state) ->
{:ok, dsl_state}
{:error, reason} ->
{:error, reason}
end
end
end