improvement: compile-time check to make sure that the configured token_resource is an Ash.Resource (#749)

* improvement(Tokens): improved compile-time validation of the token_resource option of the tokens DSL by checking that the passed value is an Ash.Resource.

* improvement(Tokens): removed unnecessary stuff from the test file.

* improvement(Tokens): fixed credo warning and changed some things after PR feedback
This commit is contained in:
Simon Bergström 2024-07-24 22:21:24 +02:00 committed by GitHub
parent a79a474b11
commit 866d806b47
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
3 changed files with 70 additions and 4 deletions

View file

@ -54,6 +54,8 @@ defmodule AshAuthentication.Jwt do
specified in integer positive hours.
"""
require Logger
alias Ash.Resource
alias AshAuthentication.{Info, Jwt.Config, TokenResource}
@ -113,7 +115,9 @@ defmodule AshAuthentication.Jwt do
:ok <- maybe_store_token(token, resource, user, purpose, action_opts) do
{:ok, token, claims}
else
{:error, _reason} -> :error
{:error, reason} ->
Logger.error("Failed to generate token for user: #{inspect reason, pretty: true}")
:error
end
end

View file

@ -109,11 +109,16 @@ defmodule AshAuthentication.Verifier do
end
end
@spec token_resource?(any()) :: {boolean(), any()}
defp token_resource?(module) do
{Spark.Dsl.is?(module, Ash.Resource), module}
end
defp validate_token_resource(dsl_state) do
if_tokens_enabled(dsl_state, fn dsl_state ->
with {:ok, resource} when is_truthy(resource) <-
Info.authentication_tokens_token_resource(dsl_state),
true <- is_atom(resource) do
{true, _resource} <- token_resource?(resource) do
:ok
else
{:ok, falsy} when is_falsy(falsy) ->
@ -122,11 +127,11 @@ defmodule AshAuthentication.Verifier do
{:error, reason} ->
{:error, reason}
false ->
{false, bad_token_resource} ->
{:error,
DslError.exception(
path: [:authentication, :tokens, :token_resource],
message: "is not a valid module name"
message: "`#{inspect(bad_token_resource)}` is not a valid token resource module name"
)}
end
end)

View file

@ -0,0 +1,57 @@
defmodule AshAuthentication.UserWithBadTokenTest do
@moduledoc false
use DataCase, async: true
test "cannot compile with bad token_resource configured" do
assert_raise Spark.Error.DslError, ~r/`BadToken` is not a valid token resource module name/, fn ->
defmodule UserWithBadToken do
@moduledoc false
use Ash.Resource,
data_layer: AshPostgres.DataLayer,
extensions: [AshAuthentication],
validate_domain_inclusion?: false,
domain: Example
attributes do
uuid_primary_key :id, writable?: true
attribute :email, :ci_string, allow_nil?: false, public?: true
attribute :hashed_password, :string, allow_nil?: true, sensitive?: true, public?: false
create_timestamp :created_at
update_timestamp :updated_at
end
authentication do
tokens do
enabled? true
token_resource BadToken
signing_secret fn _, _ -> :dummy end
end
strategies do
password do
identity_field :email
resettable do
sender fn _user, _token, _opts -> :noop end
end
end
end
end
actions do
defaults [:create, :read, :update, :destroy]
end
identities do
identity :email, [:email], eager_check_with: Example
end
postgres do
table "user_with_bad_token_required"
repo Example.Repo
end
end
end
end
end