Packages
ash_authentication
5.0.0-rc.11
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/strategies/dynamic_oidc/strategy.ex
# SPDX-FileCopyrightText: 2022 Alembic Pty Ltd
#
# SPDX-License-Identifier: MIT
defimpl AshAuthentication.Strategy, for: AshAuthentication.Strategy.DynamicOidc do
@moduledoc """
Implementation of `AshAuthentication.Strategy` for
`AshAuthentication.Strategy.DynamicOidc`.
Generates two routes:
- `/<subject>/<strategy>/:connection_id/request` — initiate sign-in for
a specific connection.
- `/<subject>/<strategy>/callback` — single shared callback URL.
Both phases delegate to `AshAuthentication.Strategy.DynamicOidc.Plug`,
which handles connection lookup and ephemeral OAuth2 strategy
construction before reusing the standard OAuth2 plug logic.
"""
alias Ash.Resource
alias AshAuthentication.{Info, Strategy, Strategy.DynamicOidc}
alias Plug.Conn
@typedoc "The request phases supported by this strategy"
@type phase :: :request | :callback
@typedoc "The actions supported by this strategy"
@type action :: :register | :sign_in
@doc false
@spec name(DynamicOidc.t()) :: atom
def name(strategy), do: strategy.name
@doc false
@spec phases(DynamicOidc.t()) :: [phase]
def phases(_), do: [:request, :callback]
@doc false
@spec actions(DynamicOidc.t()) :: [action]
def actions(%DynamicOidc{registration_enabled?: true}), do: [:register]
def actions(%DynamicOidc{registration_enabled?: false}), do: [:sign_in]
@doc false
@spec method_for_phase(DynamicOidc.t(), phase) :: Strategy.http_method()
def method_for_phase(_, :request), do: :get
def method_for_phase(_, :callback), do: :get
@doc """
Return a list of routes for use by the strategy.
The request phase includes a `:connection_id` path parameter so the user
can pick which connection to sign in with. The callback phase uses a
fixed path — connection identity is restored from the user's session.
"""
@spec routes(DynamicOidc.t()) :: [Strategy.route()]
def routes(strategy) do
subject_name = Info.authentication_subject_name!(strategy.resource)
base = [subject_name, strategy.name] |> Enum.map_join("/", &to_string/1)
[
{"/#{base}/:connection_id/request", :request},
{"/#{base}/callback", :callback}
]
end
@doc """
Handle HTTP requests.
"""
@spec plug(DynamicOidc.t(), phase, Conn.t()) :: Conn.t()
def plug(strategy, :request, conn), do: DynamicOidc.Plug.request(conn, strategy)
def plug(strategy, :callback, conn), do: DynamicOidc.Plug.callback(conn, strategy)
# The OAuth2.Actions functions are typespec'd against `OAuth2.t()`, but
# work fine on the populated DynamicOidc struct since the runtime
# behaviour only touches shared fields.
@dialyzer {:nowarn_function, [action: 4]}
@doc """
Perform actions.
"""
@spec action(DynamicOidc.t(), action, map, keyword) ::
{:ok, Resource.record()} | {:error, any}
def action(strategy, :register, params, options),
do: AshAuthentication.Strategy.OAuth2.Actions.register(strategy, params, options)
def action(strategy, :sign_in, params, options),
do: AshAuthentication.Strategy.OAuth2.Actions.sign_in(strategy, params, options)
@doc false
@spec tokens_required?(DynamicOidc.t()) :: boolean
def tokens_required?(_), do: false
end