improvement: Use Ash functions instead of generated domain functions.

This commit is contained in:
James Harton 2024-04-09 15:43:10 +12:00
parent a5f3f244ae
commit 59918e49a4
Signed by: james
GPG key ID: 90E82DAA13F624F4
9 changed files with 83 additions and 40 deletions

View file

@ -197,13 +197,16 @@ defmodule AshAuthentication do
def subject_to_user(%URI{path: subject_name, query: primary_key} = _subject, resource, options) do
with {:ok, resource_subject_name} <- Info.authentication_subject_name(resource),
^subject_name <- to_string(resource_subject_name),
{:ok, action_name} <- Info.authentication_get_by_subject_action_name(resource),
{:ok, domain} <- Info.domain(resource) do
{:ok, action_name} <- Info.authentication_get_by_subject_action_name(resource) do
primary_key =
primary_key
|> URI.decode_query()
|> Enum.to_list()
options =
options
|> Keyword.put_new_lazy(:domain, fn -> Info.domain!(resource) end)
resource
|> Query.new()
|> Query.set_context(%{
@ -213,7 +216,7 @@ defmodule AshAuthentication do
})
|> Query.for_read(action_name, %{})
|> Query.filter(^primary_key)
|> domain.read(options)
|> Ash.read(options)
|> case do
{:ok, [user]} -> {:ok, user}
_ -> {:error, NotFound.exception([])}

View file

@ -21,11 +21,16 @@ defmodule AshAuthentication.AddOn.Confirmation.Actions do
"""
@spec confirm(Confirmation.t(), map, keyword) :: {:ok, Resource.record()} | {:error, any}
def confirm(strategy, params, opts \\ []) do
with {:ok, domain} <- Info.domain(strategy.resource),
{:ok, token} <- Map.fetch(params, "confirm"),
with {:ok, token} <- Map.fetch(params, "confirm"),
{:ok, %{"sub" => subject}, _} <- Jwt.verify(token, strategy.resource),
{:ok, user} <- AshAuthentication.subject_to_user(subject, strategy.resource, opts),
{:ok, token_resource} <- Info.authentication_tokens_token_resource(strategy.resource) do
opts =
opts
|> Keyword.put_new_lazy(:domain, fn ->
Info.domain!(strategy.resource)
end)
user
|> Changeset.new()
|> Changeset.set_context(%{
@ -40,7 +45,7 @@ defmodule AshAuthentication.AddOn.Confirmation.Actions do
{:error, reason} -> {:error, reason}
end
end)
|> domain.update(opts)
|> Ash.update(opts)
else
:error -> {:error, InvalidToken.exception(type: :confirmation)}
{:error, reason} -> {:error, reason}
@ -60,6 +65,7 @@ defmodule AshAuthentication.AddOn.Confirmation.Actions do
with {:ok, token_resource} <- Info.authentication_tokens_token_resource(strategy.resource),
{:ok, domain} <- TokenResource.Info.token_domain(token_resource),
opts <- opts |> Keyword.put(:upsert?, true) |> Keyword.put_new(:domain, domain),
{:ok, store_changes_action} <-
TokenResource.Info.token_confirmation_store_changes_action_name(token_resource),
{:ok, _token_record} <-
@ -75,7 +81,7 @@ defmodule AshAuthentication.AddOn.Confirmation.Actions do
extra_data: changes,
purpose: to_string(Strategy.name(strategy))
})
|> domain.create(Keyword.merge(opts, upsert?: true)) do
|> Ash.create(opts) do
:ok
else
{:error, reason} ->
@ -95,7 +101,10 @@ defmodule AshAuthentication.AddOn.Confirmation.Actions do
@spec get_changes(Confirmation.t(), String.t(), keyword) :: {:ok, map} | :error
def get_changes(strategy, jti, opts \\ []) do
with {:ok, token_resource} <- Info.authentication_tokens_token_resource(strategy.resource),
{:ok, domain} <- TokenResource.Info.token_domain(token_resource),
opts <-
Keyword.put_new_lazy(opts, :domain, fn ->
TokenResource.Info.token_domain!(token_resource)
end),
{:ok, get_changes_action} <-
TokenResource.Info.token_confirmation_get_changes_action_name(token_resource),
{:ok, [token_record]} <-
@ -108,7 +117,7 @@ defmodule AshAuthentication.AddOn.Confirmation.Actions do
})
|> Query.set_context(%{strategy: strategy})
|> Query.for_read(get_changes_action, %{"jti" => jti})
|> domain.read(opts) do
|> Ash.read(opts) do
changes =
strategy.monitor_fields
|> Stream.map(&to_string/1)

View file

@ -14,13 +14,17 @@ defmodule AshAuthentication.Strategy.MagicLink.Actions do
"""
@spec request(MagicLink.t(), map, keyword) :: :ok | {:error, any}
def request(strategy, params, options) do
domain = Info.domain!(strategy.resource)
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.request_action_name, params)
|> domain.read(options)
|> Ash.read(options)
|> case do
{:ok, _} -> :ok
{:error, reason} -> {:error, reason}
@ -33,13 +37,15 @@ defmodule AshAuthentication.Strategy.MagicLink.Actions do
@spec sign_in(MagicLink.t(), map, keyword) ::
{:ok, Resource.record()} | {:error, Errors.AuthenticationFailed.t()}
def sign_in(strategy, params, options) do
domain = Info.domain!(strategy.resource)
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)
|> domain.read(options)
|> Ash.read(options)
|> case do
{:ok, [user]} ->
{:ok, user}

View file

@ -22,7 +22,9 @@ defmodule AshAuthentication.Strategy.OAuth2.Actions do
)}
def sign_in(%OAuth2{} = strategy, params, options) do
domain = Info.domain!(strategy.resource)
options =
options
|> Keyword.put_new_lazy(:domain, fn -> Info.domain!(strategy.resource) end)
strategy.resource
|> Query.new()
@ -32,7 +34,7 @@ defmodule AshAuthentication.Strategy.OAuth2.Actions do
}
})
|> Query.for_read(strategy.sign_in_action_name, params)
|> domain.read(options)
|> Ash.read(options)
|> case do
{:ok, [user]} ->
{:ok, user}
@ -90,9 +92,12 @@ defmodule AshAuthentication.Strategy.OAuth2.Actions do
"""
@spec register(OAuth2.t(), map, keyword) :: {:ok, Resource.record()} | {:error, any}
def register(%OAuth2{} = strategy, params, options) when strategy.registration_enabled? do
domain = Info.domain!(strategy.resource)
action = Resource.Info.action(strategy.resource, strategy.register_action_name, :create)
options =
options
|> Keyword.put_new_lazy(:domain, fn -> Info.domain!(strategy.resource) end)
strategy.resource
|> Changeset.new()
|> Changeset.set_context(%{
@ -104,7 +109,7 @@ defmodule AshAuthentication.Strategy.OAuth2.Actions do
upsert?: true,
upsert_identity: action.upsert_identity
)
|> domain.create(options)
|> Ash.create(options)
end
def register(%OAuth2{} = strategy, _params, _options),

View file

@ -42,7 +42,7 @@ defmodule AshAuthentication.Strategy.OAuth2.IdentityChange do
"#{user_id_attribute_name}": user.id
}) do
user
|> changeset.domain.load(strategy.identity_relationship_name)
|> Ash.load(strategy.identity_relationship_name, domain: Info.domain!(strategy.resource))
else
:error -> :error
{:error, reason} -> {:error, reason}

View file

@ -70,7 +70,7 @@ defmodule AshAuthentication.Strategy.OAuth2.SignInPreparation do
|> case do
{:ok, _identity} ->
user
|> query.domain.load(strategy.identity_relationship_name)
|> Ash.load(strategy.identity_relationship_name, domain: Info.domain!(strategy.resource))
{:error, reason} ->
{:error, reason}

View file

@ -16,8 +16,6 @@ defmodule AshAuthentication.Strategy.Password.Actions do
{:ok, Resource.record()} | {:error, Errors.AuthenticationFailed.t()}
def sign_in(strategy, params, options)
when is_struct(strategy, Password) and strategy.sign_in_enabled? do
domain = Info.domain!(strategy.resource)
{context, options} = Keyword.pop(options, :context, [])
context =
@ -29,11 +27,15 @@ defmodule AshAuthentication.Strategy.Password.Actions do
}
})
options =
options
|> Keyword.put_new_lazy(:domain, fn -> Info.domain!(strategy.resource) end)
strategy.resource
|> Query.new()
|> Query.set_context(context)
|> Query.for_read(strategy.sign_in_action_name, params)
|> domain.read(options)
|> Ash.read(options)
|> case do
{:ok, [user]} ->
{:ok, user}
@ -101,13 +103,15 @@ defmodule AshAuthentication.Strategy.Password.Actions do
"""
@spec sign_in_with_token(Password.t(), map, keyword) :: {:ok, Resource.record()} | {:error, any}
def sign_in_with_token(strategy, params, options) when is_struct(strategy, Password) do
domain = Info.domain!(strategy.resource)
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_with_token_action_name, params)
|> domain.read(options)
|> Ash.read(options)
|> case do
{:ok, [user]} ->
{:ok, user}
@ -147,7 +151,9 @@ defmodule AshAuthentication.Strategy.Password.Actions do
@spec register(Password.t(), map, keyword) :: {:ok, Resource.record()} | {:error, any}
def register(strategy, params, options)
when is_struct(strategy, Password) and strategy.registration_enabled? == true do
domain = Info.domain!(strategy.resource)
options =
options
|> Keyword.put_new_lazy(:domain, fn -> Info.domain!(strategy.resource) end)
strategy.resource
|> Changeset.new()
@ -157,7 +163,7 @@ defmodule AshAuthentication.Strategy.Password.Actions do
}
})
|> Changeset.for_create(strategy.register_action_name, params)
|> domain.create(options)
|> Ash.create(options)
end
def register(strategy, _params, _options) when is_struct(strategy, Password) do
@ -182,7 +188,9 @@ defmodule AshAuthentication.Strategy.Password.Actions do
params,
options
) do
domain = Info.domain!(strategy.resource)
options =
options
|> Keyword.put_new_lazy(:domain, fn -> Info.domain!(strategy.resource) end)
strategy.resource
|> Query.new()
@ -192,7 +200,7 @@ defmodule AshAuthentication.Strategy.Password.Actions do
}
})
|> Query.for_read(resettable.request_password_reset_action_name, params)
|> domain.read(options)
|> Ash.read(options)
|> case do
{:ok, _} -> :ok
{:error, reason} -> {:error, reason}
@ -216,7 +224,9 @@ defmodule AshAuthentication.Strategy.Password.Actions do
with {:ok, token} <- Map.fetch(params, "reset_token"),
{:ok, %{"sub" => subject}, resource} <- Jwt.verify(token, strategy.resource),
{:ok, user} <- AshAuthentication.subject_to_user(subject, resource, options) do
domain = Info.domain!(resource)
options =
options
|> Keyword.put_new_lazy(:domain, fn -> Info.domain!(strategy.resource) end)
user
|> Changeset.new()
@ -226,7 +236,7 @@ defmodule AshAuthentication.Strategy.Password.Actions do
}
})
|> Changeset.for_update(resettable.password_reset_action_name, params)
|> domain.update(options)
|> Ash.update(options)
else
{:error, %Changeset{} = changeset} -> {:error, changeset}
_ -> {:error, Errors.InvalidToken.exception(type: :reset)}

View file

@ -22,7 +22,7 @@ defmodule AshAuthentication.TokenResource.Actions do
}
})
|> Query.for_read(read_expired_action_name, opts)
|> domain.read()
|> Ash.read(domain: domain)
end
end
@ -52,6 +52,9 @@ defmodule AshAuthentication.TokenResource.Actions do
Notifier.notify(notifications)
:ok
{:ok, {:error, reason}} ->
{:error, reason}
{:error, reason} ->
{:error, reason}
end
@ -80,7 +83,7 @@ defmodule AshAuthentication.TokenResource.Actions do
}
})
|> Query.for_read(is_revoked_action_name, %{"token" => token}, opts)
|> domain.read()
|> Ash.read(domain: domain)
|> case do
{:ok, []} -> false
{:ok, _} -> true
@ -108,7 +111,7 @@ defmodule AshAuthentication.TokenResource.Actions do
}
})
|> Query.for_read(is_revoked_action_name, %{"jti" => jti}, opts)
|> domain.read()
|> Ash.read(domain: domain)
|> case do
{:ok, []} -> false
{:ok, _} -> true
@ -145,7 +148,7 @@ defmodule AshAuthentication.TokenResource.Actions do
%{"token" => token},
Keyword.merge(opts, upsert?: true)
)
|> domain.create()
|> Ash.create(domain: domain)
|> case do
{:ok, _} -> :ok
{:error, reason} -> {:error, reason}
@ -175,7 +178,7 @@ defmodule AshAuthentication.TokenResource.Actions do
params,
Keyword.merge(opts, upsert?: true)
)
|> domain.create()
|> Ash.create(domain: domain)
|> case do
{:ok, _} -> :ok
{:error, reason} -> {:error, reason}
@ -195,19 +198,26 @@ defmodule AshAuthentication.TokenResource.Actions do
|> Query.new()
|> Query.set_context(%{private: %{ash_authentication?: true}})
|> Query.for_read(get_token_action_name, params, opts)
|> domain.read()
|> Ash.read(domain: domain)
end
end
defp expunge_inside_transaction(resource, expunge_expired_action_name, opts) do
with :ok <- assert_resource_has_extension(resource, TokenResource),
{:ok, domain} <- Info.token_domain(resource),
{:ok, read_expired_action_name} <- Info.token_read_expired_action_name(resource) do
opts =
opts
|> Keyword.put_new_lazy(:domain, fn -> Info.token_domain!(resource) end)
resource
|> Query.new()
|> Query.set_context(%{private: %{ash_authentication?: true}})
|> Query.for_read(read_expired_action_name, opts)
|> domain.bulk_destroy(expunge_expired_action_name, %{}, opts)
|> Query.for_read(read_expired_action_name, %{}, opts)
|> Ash.bulk_destroy(
expunge_expired_action_name,
%{},
Keyword.put_new(opts, :strategy, [:atomic, :atomic_batches, :stream])
)
|> case do
%{status: :success, notifications: notifications} -> {:ok, notifications}
%{errors: errors} -> {:error, Ash.Error.to_class(errors)}

View file

@ -30,7 +30,7 @@ defmodule AshAuthentication.UserIdentity.Actions do
upsert?: true,
upsert_identity: action.upsert_identity
)
|> domain.create()
|> Ash.create(domain: domain)
end
end
end