Packages
ash_authentication
4.4.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/strategies/custom.ex
defmodule AshAuthentication.Strategy.Custom do
@moduledoc """
Define your own custom authentication strategy.
See [the Custom Strategies guide](/documentation/topics/custom-strategy.md)
for more information.
"""
alias Spark.Dsl
@typedoc """
A Strategy DSL Entity.
See `Spark.Dsl.Entity` for more information.
"""
@type entity :: Spark.Dsl.Entity.t()
@typedoc """
This is the DSL target for your entity and the struct for which you will
implement the `AshAuthentication.Strategy` protocol.
The only required field is `strategy_module` which is used to keep track of
which custom strategy created which strategy.
"""
@type strategy :: %{
required(:__struct__) => module,
required(:strategy_module) => module,
required(:resource) => module,
optional(atom) => any
}
@doc """
If your strategy needs to modify either the entity or the parent resource then
you can implement this callback.
This callback can return one of three results:
- `{:ok, Entity.t}` - an updated DSL entity - useful if you're just changing
the entity itself and not changing the wider DSL state of the resource.
If this is the response then the transformer will take care of updating
the entity in the DSL state.
- `{:ok, Dsl.t}` - an updated DSL state for the entire resource.
- `{:error, Exception.t}` - a compilation-stopping problem was found. Any
exception can be returned, but we strongly advise you to return a
`Spark.Error.DslError`.
"""
@callback transform(strategy, Dsl.t()) ::
{:ok, strategy} | {:ok, Dsl.t()} | {:error, Exception.t()}
@doc """
If your strategy needs to verify either the entity or the parent resource then
you can implement this callback.
This is called post-compilation in the `@after_verify` hook - see `Module` for
more information.
This callback can return one of the following results:
- `:ok` - everything is A-Okay.
- `{:error, Exception.t}` - a compilation-stopping problem was found. Any
exception can be returned, but we strongly advise you to return a
`Spark.Error.DslError`.
"""
@callback verify(strategy, Dsl.t()) :: :ok | {:error, Exception.t()}
@doc false
@spec __using__(keyword) :: Macro.t()
defmacro __using__(opts) do
quote generated: true do
@behaviour unquote(__MODULE__)
import unquote(__MODULE__).Helpers
def transform(entity, _dsl_state), do: {:ok, entity}
def verify(_entity, _dsl_state), do: :ok
defoverridable transform: 2, verify: 2
opts = unquote(opts)
path =
opts
|> Keyword.get(:style, :strategy)
|> case do
:strategy -> ~w[authentication strategies]a
:add_on -> ~w[authentication add_ons]a
end
entity =
opts
|> Keyword.get(:entity)
|> case do
%Dsl.Entity{} = entity ->
%{
entity
| auto_set_fields:
Keyword.merge([strategy_module: __MODULE__], entity.auto_set_fields || [])
}
_ ->
raise CompileError,
file: __ENV__.file,
line: __ENV__.line,
description:
"You must provide a `Spark.Dsl.Entity` as the `entity` argument to `use AshAuthentication.Strategy.Custom`."
end
use Spark.Dsl.Extension,
dsl_patches: [%Dsl.Patch.AddEntity{section_path: path, entity: entity}]
end
end
@doc """
Sets default values for a DSL schema based on a set of defaults.
If a given default is in the schema, it can be overriden, so we just set the default
and mark it not required.
If not, then we add it to `auto_set_fields`, and the user cannot override it.
"""
def set_defaults(dsl, defaults) do
Enum.reduce(defaults, dsl, fn {key, value}, dsl ->
if dsl.schema[key] do
set_default(dsl, key, value)
else
Map.update!(dsl, :auto_set_fields, &Keyword.put(&1, key, value))
end
end)
end
defp set_default(dsl, key, value) do
Map.update!(dsl, :schema, fn schema ->
Keyword.update(
schema,
key,
[
type: :any,
default: value,
hide: true
],
fn config ->
config
|> Keyword.put(:default, value)
|> Keyword.delete(:required)
end
)
end)
end
end