Packages
ash_authentication
5.0.0-rc.12
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.
Current section
Files
Jump to
Current section
Files
lib/ash_authentication/token_resource/verifier.ex
# SPDX-FileCopyrightText: 2022 Alembic Pty Ltd
#
# SPDX-License-Identifier: MIT
defmodule AshAuthentication.TokenResource.Verifier do
@moduledoc """
The token resource verifier.
"""
use Spark.Dsl.Verifier
require Logger
alias Spark.{Dsl.Verifier, Error.DslError}
import AshAuthentication.Utils
import AshAuthentication.Validations, only: [warn_if_data_layer_cannot_lock: 2]
import AshAuthentication.Validations.Action
@doc false
@impl true
@spec verify(map) :: :ok | {:error, term}
def verify(dsl_state) do
with :ok <- validate_domain_presence(dsl_state),
:ok <- maybe_validate_is_revoked_action_arguments(dsl_state) do
warn_if_data_layer_cannot_lock(
Verifier.get_persisted(dsl_state, :module),
"Token revocation relies on a `SELECT FOR UPDATE` row lock to make concurrent revocation race-free."
)
end
end
defp maybe_validate_is_revoked_action_arguments(dsl_state) do
case Verifier.get_option(dsl_state, [:token, :revocation], :is_revoked_action_name, :revoked?) do
nil ->
:ok
action_name ->
case validate_action_exists(dsl_state, action_name) do
{:ok, action} -> validate_is_revoked_action(dsl_state, action)
{:error, _} -> :ok
end
end
end
defp validate_is_revoked_action(dsl_state, action) do
if action.type == :action do
with :ok <- validate_action_argument_option(action, :jti, :allow_nil?, [true]),
:ok <- validate_action_argument_option(action, :token, :allow_nil?, [true]),
:ok <- validate_action_option(action, :returns, [:boolean, Ash.Type.Boolean]) do
:ok
else
{:error, _} ->
Logger.warning("""
Warning while compiling #{inspect(Verifier.get_persisted(dsl_state, :module))}:
The `:jti` and `:token` options to the `#{inspect(action.name)}` action must allow nil values and it must return a `:boolean`.
This was an error in our igniter installer previous to version 4.4.9, which allowed revoked tokens to be reused.
To fix this, run the following command in your shell:
mix ash_authentication.upgrade 4.4.8 4.4.9
Or:
- remove `allow_nil?: false` from these action arguments, and
- ensure that the action returns `:boolean`.
like so:
action :revoked?, :boolean do
description "Returns true if a revocation token is found for the provided token"
argument :token, :string, sensitive?: true
argument :jti, :string, sensitive?: true
run AshAuthentication.TokenResource.IsRevoked
end
""")
:ok
end
else
:ok
end
end
defp validate_domain_presence(dsl_state) do
with domain when not is_nil(domain) <- Verifier.get_option(dsl_state, [:token], :domain),
:ok <- assert_is_module(domain),
true <- function_exported?(domain, :spark_is, 0),
Ash.Domain <- domain.spark_is() do
:ok
else
nil ->
{:error,
DslError.exception(
path: [:token, :domain],
message: "A domain module must be present"
)}
_ ->
{:error,
DslError.exception(
path: [:token, :domain],
message: "Module is not an `Ash.Domain`."
)}
end
end
end