mirror of
https://github.com/team-alembic/ash_authentication.git
synced 2024-09-19 12:52:55 +12:00
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:
parent
a79a474b11
commit
866d806b47
3 changed files with 70 additions and 4 deletions
|
@ -54,6 +54,8 @@ defmodule AshAuthentication.Jwt do
|
||||||
specified in integer positive hours.
|
specified in integer positive hours.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
require Logger
|
||||||
|
|
||||||
alias Ash.Resource
|
alias Ash.Resource
|
||||||
alias AshAuthentication.{Info, Jwt.Config, TokenResource}
|
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 <- maybe_store_token(token, resource, user, purpose, action_opts) do
|
||||||
{:ok, token, claims}
|
{:ok, token, claims}
|
||||||
else
|
else
|
||||||
{:error, _reason} -> :error
|
{:error, reason} ->
|
||||||
|
Logger.error("Failed to generate token for user: #{inspect reason, pretty: true}")
|
||||||
|
:error
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
|
@ -109,11 +109,16 @@ defmodule AshAuthentication.Verifier do
|
||||||
end
|
end
|
||||||
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
|
defp validate_token_resource(dsl_state) do
|
||||||
if_tokens_enabled(dsl_state, fn dsl_state ->
|
if_tokens_enabled(dsl_state, fn dsl_state ->
|
||||||
with {:ok, resource} when is_truthy(resource) <-
|
with {:ok, resource} when is_truthy(resource) <-
|
||||||
Info.authentication_tokens_token_resource(dsl_state),
|
Info.authentication_tokens_token_resource(dsl_state),
|
||||||
true <- is_atom(resource) do
|
{true, _resource} <- token_resource?(resource) do
|
||||||
:ok
|
:ok
|
||||||
else
|
else
|
||||||
{:ok, falsy} when is_falsy(falsy) ->
|
{:ok, falsy} when is_falsy(falsy) ->
|
||||||
|
@ -122,11 +127,11 @@ defmodule AshAuthentication.Verifier do
|
||||||
{:error, reason} ->
|
{:error, reason} ->
|
||||||
{:error, reason}
|
{:error, reason}
|
||||||
|
|
||||||
false ->
|
{false, bad_token_resource} ->
|
||||||
{:error,
|
{:error,
|
||||||
DslError.exception(
|
DslError.exception(
|
||||||
path: [:authentication, :tokens, :token_resource],
|
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
|
||||||
end)
|
end)
|
||||||
|
|
57
test/ash_authentication/user_with_bad_token_test.exs
Normal file
57
test/ash_authentication/user_with_bad_token_test.exs
Normal 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
|
Loading…
Reference in a new issue