Skip to content

Commit

Permalink
improvement: compile-time check to make sure that the configured `tok…
Browse files Browse the repository at this point in the history
…en_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
  • Loading branch information
simpers committed Jul 24, 2024
1 parent a79a474 commit 866d806
Show file tree
Hide file tree
Showing 3 changed files with 70 additions and 4 deletions.
6 changes: 5 additions & 1 deletion lib/ash_authentication/jwt.ex
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,8 @@ defmodule AshAuthentication.Jwt do
specified in integer positive hours.
"""

require Logger

alias Ash.Resource
alias AshAuthentication.{Info, Jwt.Config, TokenResource}

Expand Down Expand Up @@ -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

Expand Down
11 changes: 8 additions & 3 deletions lib/ash_authentication/verifier.ex
Original file line number Diff line number Diff line change
Expand Up @@ -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) ->
Expand All @@ -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)
Expand Down
57 changes: 57 additions & 0 deletions test/ash_authentication/user_with_bad_token_test.exs
Original file line number Diff line number Diff line change
@@ -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

0 comments on commit 866d806

Please sign in to comment.