Packages
ash_authentication
4.2.1
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/verifier.ex
defmodule AshAuthentication.Verifier do
@moduledoc """
The Authentication verifier.
Checks configuration constraints after compile.
"""
use Spark.Dsl.Verifier
alias AshAuthentication.{Info, Strategy, Strategy.Password}
alias Spark.{Dsl.Transformer, Error.DslError}
import AshAuthentication.Utils
@doc false
@impl true
@spec verify(map) ::
:ok
| {:error, term}
| {:warn, String.t() | list(String.t())}
def verify(dsl_state) do
with {:ok, _domain} <- validate_domain_presence(dsl_state),
:ok <- validate_tokens_may_be_required(dsl_state) do
validate_token_resource(dsl_state)
end
end
defp validate_domain_presence(dsl_state) do
with domain when not is_nil(domain) <-
Transformer.get_option(dsl_state, [:authentication], :domain),
:ok <- assert_is_module(domain),
true <- function_exported?(domain, :spark_is, 0),
Ash.Domain <- domain.spark_is() do
{:ok, domain}
else
nil ->
{:error,
DslError.exception(
path: [:authentication, :domain],
message: "A domain module must be present"
)}
_ ->
{:error,
DslError.exception(
path: [:authentication, :domain],
message: "Module is not an `Ash.Domain`."
)}
end
end
defp validate_tokens_may_be_required(dsl_state) do
strategies_requiring_tokens =
dsl_state
|> Info.authentication_strategies()
|> Enum.filter(&Strategy.tokens_required?/1)
tokens_enabled? =
dsl_state
|> Info.authentication_tokens_enabled?()
case {strategies_requiring_tokens, tokens_enabled?} do
{[], _} ->
:ok
{_, true} ->
:ok
{[password | _], false}
when is_struct(password, Password) and is_map(password.resettable) ->
{:error,
DslError.exception(
path: [:authentication, :tokens, :enabled?],
message: """
The `#{password.name}` password authentication strategy requires tokens be enabled because reset tokens are in use.
To fix this error you can either:
1. disable password resets by removing the `resettable` configuration from your password strategy, or
2. enable tokens.
"""
)}
{[password | _], false}
when is_struct(password, Password) and password.sign_in_tokens_enabled? ->
{:error,
DslError.exception(
path: [:authentication, :tokens, :enabled?],
message: """
The `#{password.name}` password authentication strategy requires tokens be enabled because sign-in tokens are in use.
To fix this error you can either:
1. disable sign in tokens by setting `sign_in_tokens? false` your password strategy, or
2. enable tokens.
"""
)}
{[strategy | _], false} ->
{:error,
DslError.exception(
path: [:authentication, :tokens, :enabled?],
message: """
The `#{inspect(strategy.name)}` authentication strategy requires tokens be enabled.
To fix this error you can either:
1. disable the `#{inspect(strategy.name)}` strategy, or
2. enable tokens.
"""
)}
end
end
@spec token_resource?(any()) :: {boolean(), any()}
defp token_resource?(module) do
{Spark.Dsl.is?(module, Ash.Resource), module}
end
defp validate_token_resource(dsl_state) do
if_tokens_enabled(dsl_state, fn dsl_state ->
with {:ok, resource} when is_truthy(resource) <-
Info.authentication_tokens_token_resource(dsl_state),
{true, _resource} <- token_resource?(resource) do
:ok
else
{:ok, falsy} when is_falsy(falsy) ->
:ok
{false, bad_token_resource} ->
{:error,
DslError.exception(
path: [:authentication, :tokens, :token_resource],
message: "`#{inspect(bad_token_resource)}` is not a valid token resource module name"
)}
end
end)
end
defp if_tokens_enabled(dsl_state, validator) when is_function(validator, 1) do
if Info.authentication_tokens_enabled?(dsl_state) do
validator.(dsl_state)
else
:ok
end
end
end