diff --git a/lib/ash_authentication/token_resource/transformer.ex b/lib/ash_authentication/token_resource/transformer.ex index d5fcbe1..2f36398 100644 --- a/lib/ash_authentication/token_resource/transformer.ex +++ b/lib/ash_authentication/token_resource/transformer.ex @@ -334,12 +334,34 @@ defmodule AshAuthentication.TokenResource.Transformer do end defp validate_is_revoked_action(dsl_state, action_name) do - with {:ok, action} <- validate_action_exists(dsl_state, action_name), - :ok <- - validate_action_argument_option(action, :token, :type, [Ash.Type.String, :string]), - :ok <- validate_action_argument_option(action, :jti, :type, [Ash.Type.String, :string]), - :ok <- validate_action_has_preparation(action, TokenResource.IsRevokedPreparation) do - validate_field_in_values(action, :type, [:read]) + case validate_action_exists(dsl_state, action_name) do + {:ok, %{type: :read} = action} -> + with :ok <- + validate_action_argument_option(action, :token, :type, [Ash.Type.String, :string]), + :ok <- + validate_action_argument_option(action, :jti, :type, [Ash.Type.String, :string]), + :ok <- validate_action_has_preparation(action, TokenResource.IsRevokedPreparation) do + :ok + end + + {:ok, %{type: :action} = action} -> + with :ok <- + validate_action_argument_option(action, :token, :type, [Ash.Type.String, :string]), + :ok <- + validate_action_argument_option(action, :jti, :type, [Ash.Type.String, :string]) do + :ok + end + + {:ok, _} -> + {:error, + Spark.Error.DslError.exception( + module: Spark.Dsl.Transformer.get_persisted(dsl_state, :module), + path: [:actions, :is_revoked], + message: "The action `:is_revoked` must be a read action or a generic action" + )} + + _ -> + :ok end end diff --git a/lib/ash_authentication/transformer.ex b/lib/ash_authentication/transformer.ex index 66accef..5a7afed 100644 --- a/lib/ash_authentication/transformer.ex +++ b/lib/ash_authentication/transformer.ex @@ -32,7 +32,6 @@ defmodule AshAuthentication.Transformer do :ok | {:ok, map} | {:error, term} | {:warn, map, String.t() | [String.t()]} | :halt def transform(dsl_state) do with {:ok, dsl_state} <- maybe_set_domain(dsl_state, :authentication), - :ok <- validate_at_least_one_strategy(dsl_state), :ok <- validate_unique_strategy_names(dsl_state), :ok <- validate_unique_add_on_names(dsl_state), {:ok, dsl_state} <- maybe_transform_token_lifetime(dsl_state), @@ -119,22 +118,6 @@ defmodule AshAuthentication.Transformer do defp ensure_current_user_atom_exists(subject_name), do: String.to_atom("current_#{subject_name}") - defp validate_at_least_one_strategy(dsl_state) do - ok? = - dsl_state - |> Transformer.get_entities([:authentication, :strategies]) - |> Enum.any?() - - if ok?, - do: :ok, - else: - {:error, - DslError.exception( - path: [:authentication, :strategies], - message: "Expected at least one authentication strategy" - )} - end - defp validate_read_action(dsl_state, action_name) do with {:ok, action} <- validate_action_exists(dsl_state, action_name), :ok <- validate_field_in_values(action, :type, [:read]) do diff --git a/lib/mix/tasks/ash_authentication.install.ex b/lib/mix/tasks/ash_authentication.install.ex index 39511da..7d80f10 100644 --- a/lib/mix/tasks/ash_authentication.install.ex +++ b/lib/mix/tasks/ash_authentication.install.ex @@ -103,11 +103,10 @@ defmodule Mix.Tasks.AshAuthentication.Install do ) do case Igniter.Code.Module.find_module(igniter, user_resource) do {:ok, {igniter, _, _}} -> - {:ok, Igniter.add_warning( igniter, "User resource already exists: #{user_resource}, skipping creation." - )} + ) {:error, igniter} -> extensions = "AshAuthentication,Ash.Policy.Authorizer" @@ -213,11 +212,10 @@ defmodule Mix.Tasks.AshAuthentication.Install do defp generate_token_resource(igniter, token_resource, argv, resource_args) do case Igniter.Code.Module.find_module(igniter, token_resource) do {:ok, {igniter, _, _}} -> - {:ok, Igniter.add_warning( igniter, "Token resource already exists: #{token_resource}, skipping creation." - )} + ) {:error, igniter} -> extensions = "AshAuthentication.TokenResource,Ash.Policy.Authorizer" @@ -238,6 +236,8 @@ defmodule Mix.Tasks.AshAuthentication.Install do "read", "--extend", extensions, + "--uuid-primary-key", + "id", "--attribute", "jti:string:primary_key:public:required:sensitive", "--attribute", @@ -296,9 +296,8 @@ defmodule Mix.Tasks.AshAuthentication.Install do description "Returns true if a revocation token is found for the provided token" argument :token, :string, sensitive?: true, allow_nil?: false argument :jti, :string, sensitive?: true, allow_nil?: false - get? true - prepare AshAuthentication.TokenResource.IsRevokedPreparation + run AshAuthentication.TokenResource.IsRevoked end """) |> Ash.Resource.Igniter.add_action(token_resource, """ diff --git a/test/mix/tasks/ash_authentication.install_test.exs b/test/mix/tasks/ash_authentication.install_test.exs index dfa1a5b..5808f77 100644 --- a/test/mix/tasks/ash_authentication.install_test.exs +++ b/test/mix/tasks/ash_authentication.install_test.exs @@ -139,6 +139,8 @@ defmodule Mix.Tasks.AshAuthentication.InstallTest do end attributes do + uuid_primary_key(:id) + attribute :jti, :string do primary_key?(true) public?(true) @@ -188,9 +190,8 @@ defmodule Mix.Tasks.AshAuthentication.InstallTest do description("Returns true if a revocation token is found for the provided token") argument(:token, :string, sensitive?: true, allow_nil?: false) argument(:jti, :string, sensitive?: true, allow_nil?: false) - get?(true) - prepare(AshAuthentication.TokenResource.IsRevokedPreparation) + run(AshAuthentication.TokenResource.IsRevoked) end create :revoke_token do