Packages
ash_authentication
4.13.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.
Retired package: This break Google auth flows due to an assent upgrade, will be fixed in next release
Security advisory:
This version has known vulnerabilities.
View advisories
Current section
Files
Jump to
Current section
Files
lib/ash_authentication/strategies/magic_link/actions.ex
# SPDX-FileCopyrightText: 2022 Alembic Pty Ltd
#
# SPDX-License-Identifier: MIT
defmodule AshAuthentication.Strategy.MagicLink.Actions do
@moduledoc """
Actions for the magic link strategy.
Provides the code interface for working with user resources for providing
magic links.
"""
alias Ash.ActionInput
alias Ash.{Changeset, Query, Resource}
alias AshAuthentication.{Errors, Info, Strategy.MagicLink}
@doc """
Request a magic link for a user.
"""
@spec request(MagicLink.t(), map, keyword) :: :ok | {:error, any}
def request(strategy, params, options) do
action = Ash.Resource.Info.action(strategy.resource, strategy.request_action_name)
options =
options
|> Keyword.put_new_lazy(:domain, fn ->
Info.domain!(strategy.resource)
end)
case action.type do
:read ->
strategy.resource
|> Query.new()
|> Query.set_context(%{private: %{ash_authentication?: true}})
|> Query.for_read(strategy.request_action_name, params, options)
|> Ash.read()
|> case do
{:ok, _} -> :ok
{:error, reason} -> {:error, reason}
end
:action ->
strategy.resource
|> ActionInput.new()
|> ActionInput.set_context(%{private: %{ash_authentication?: true}})
|> ActionInput.for_action(strategy.request_action_name, params, options)
|> Ash.run_action()
|> case do
:ok -> :ok
{:error, reason} -> {:error, reason}
end
end
end
@doc """
Attempt to sign a user in via magic link.
"""
@spec sign_in(MagicLink.t(), map, keyword) ::
{:ok, Resource.record()} | {:error, Errors.AuthenticationFailed.t()}
def sign_in(strategy, params, options) do
if strategy.registration_enabled? do
strategy.resource
|> Changeset.new()
|> Changeset.set_context(%{private: %{ash_authentication?: true}})
|> Changeset.for_create(strategy.sign_in_action_name, params, options)
|> Ash.create()
|> case do
{:ok, record} ->
{:ok, record}
{:error, error} ->
{:error,
Errors.AuthenticationFailed.exception(
strategy: strategy,
caused_by: error
)}
end
else
options =
options
|> Keyword.put_new_lazy(:domain, fn -> Info.domain!(strategy.resource) end)
strategy.resource
|> Query.new()
|> Query.set_context(%{private: %{ash_authentication?: true}})
|> Query.for_read(strategy.sign_in_action_name, params, options)
|> Ash.read()
|> case do
{:ok, [user]} ->
{:ok, user}
{:ok, []} ->
{:error,
Errors.AuthenticationFailed.exception(
strategy: strategy,
caused_by: %{
module: __MODULE__,
strategy: strategy,
action: :sign_in,
message: "Query returned no users"
}
)}
{:ok, _users} ->
{:error,
Errors.AuthenticationFailed.exception(
strategy: strategy,
caused_by: %{
module: __MODULE__,
strategy: strategy,
action: :sign_in,
message: "Query returned too many users"
}
)}
{:error, error} when is_exception(error) ->
{:error,
Errors.AuthenticationFailed.exception(
strategy: strategy,
caused_by: error
)}
{:error, error} ->
{:error,
Errors.AuthenticationFailed.exception(
strategy: strategy,
caused_by: %{
module: __MODULE__,
strategy: strategy,
action: :sign_in,
message: "Query returned error: #{inspect(error)}"
}
)}
end
end
end
end