Packages
ash_authentication
4.14.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.
Current section
Files
Jump to
Current section
Files
lib/ash_authentication/strategies/oauth2/verifier.ex
# SPDX-FileCopyrightText: 2022 Alembic Pty Ltd
#
# SPDX-License-Identifier: MIT
defmodule AshAuthentication.Strategy.OAuth2.Verifier do
@moduledoc """
DSL verifier for oauth2 strategies.
"""
alias AshAuthentication.Strategy.OAuth2
alias Spark.Error.DslError
import AshAuthentication.Validations
@doc false
@spec verify(OAuth2.t(), map) :: :ok | {:error, Exception.t()}
def verify(strategy, dsl_state) do
with :ok <- validate_secret(strategy, :authorize_url),
:ok <- validate_secret(strategy, :client_id),
:ok <- validate_secret(strategy, :client_secret),
:ok <- validate_secret(strategy, :redirect_uri),
:ok <- validate_secret(strategy, :base_url),
:ok <- validate_secret(strategy, :token_url),
:ok <- validate_secret(strategy, :user_url),
:ok <- prevent_hijacking(dsl_state, strategy),
:ok <- validate_confirmation_for_untrusted_match(dsl_state, strategy),
:ok <- validate_private_key(strategy) do
oauth2_strategy_warnings(strategy, dsl_state)
end
end
defp validate_confirmation_for_untrusted_match(_dsl_state, %{on_untrusted_email_match: :reject}),
do: :ok
defp validate_confirmation_for_untrusted_match(dsl_state, strategy) do
if Enum.any?(
AshAuthentication.Info.authentication_add_ons(dsl_state),
&(&1.__struct__ == AshAuthentication.AddOn.Confirmation)
) do
:ok
else
{:error,
DslError.exception(
path: [:authentication, :strategies, strategy.name],
message: """
`on_untrusted_email_match` is set to `:confirm`, but no `confirmation` add-on is configured.
Linking a provider via confirmation requires a confirmation add-on to issue the confirmation
and apply the link once the recipient proves ownership. Add a `confirmation` add-on, or set
`on_untrusted_email_match :reject`.
"""
)}
end
end
defp validate_private_key(%{auth_method: :private_key_jwt} = strategy),
do: validate_secret(strategy, :private_key)
defp validate_private_key(_strategy), do: :ok
defp prevent_hijacking(_dsl_state, %{prevent_hijacking?: false}), do: :ok
defp prevent_hijacking(_dsl_state, %{registration_enabled?: false}), do: :ok
defp prevent_hijacking(dsl_state, strategy) do
case Enum.find(
AshAuthentication.Info.authentication_strategies(dsl_state),
fn other_strategy ->
other_strategy.__struct__ == AshAuthentication.Strategy.Password &&
other_strategy.registration_enabled?
end
) do
nil ->
:ok
password_strategy ->
if has_confirmation_add_on?(dsl_state, password_strategy) do
:ok
else
{:error,
DslError.exception(
path: [:authentication, :strategies, strategy.name],
message: """
If you have an oauth2 strategy and a password strategy, you must also have a
confirmation add-on that monitors the password's identity field.
This is to prevent from account hijacking. If the field used in your password strategy is not
an email field, you can set `prevent_hijacking?: false` in your oauth strategy.
For more information, see the confirmation tutorial on hexdocs.
"""
)}
end
end
end
defp has_confirmation_add_on?(dsl_state, password_strategy) do
Enum.any?(AshAuthentication.Info.authentication_add_ons(dsl_state), fn add_on ->
add_on.__struct__ == AshAuthentication.AddOn.Confirmation &&
password_strategy.identity_field in add_on.monitor_fields
end)
end
end