mirror of
https://github.com/team-alembic/ash_authentication.git
synced 2024-09-19 21:03:23 +12:00
fix: correctly generate sign-in tokens when requested.
This commit is contained in:
parent
d8588b9b89
commit
81236e1ed5
4 changed files with 64 additions and 28 deletions
|
@ -38,28 +38,23 @@ defmodule AshAuthentication.Strategy.Password.SignInPreparation do
|
|||
if strategy.hash_provider.valid?(
|
||||
password,
|
||||
Map.get(record, strategy.hashed_password_field)
|
||||
),
|
||||
do:
|
||||
{:ok,
|
||||
[
|
||||
maybe_generate_token(
|
||||
query.context[:token_type] || :user,
|
||||
record,
|
||||
strategy
|
||||
)
|
||||
]},
|
||||
else:
|
||||
{:error,
|
||||
AuthenticationFailed.exception(
|
||||
strategy: strategy,
|
||||
query: query,
|
||||
caused_by: %{
|
||||
module: __MODULE__,
|
||||
action: query.action,
|
||||
resource: query.resource,
|
||||
message: "Password is not valid"
|
||||
}
|
||||
)}
|
||||
) do
|
||||
token_type = query.context[:token_type] || :user
|
||||
|
||||
{:ok, [maybe_generate_token(token_type, record, strategy)]}
|
||||
else
|
||||
{:error,
|
||||
AuthenticationFailed.exception(
|
||||
strategy: strategy,
|
||||
query: query,
|
||||
caused_by: %{
|
||||
module: __MODULE__,
|
||||
action: query.action,
|
||||
resource: query.resource,
|
||||
message: "Password is not valid"
|
||||
}
|
||||
)}
|
||||
end
|
||||
|
||||
query, [] ->
|
||||
strategy.hash_provider.simulate()
|
||||
|
@ -118,11 +113,11 @@ defmodule AshAuthentication.Strategy.Password.SignInPreparation do
|
|||
end
|
||||
end
|
||||
|
||||
defp generate_token(purpose, record, strategy)
|
||||
when is_integer(strategy.sign_in_token_lifetime) and purpose == :sign_in do
|
||||
defp generate_token(:sign_in, record, strategy) when strategy.sign_in_tokens_enabled? do
|
||||
{:ok, token, _claims} =
|
||||
Jwt.token_for_user(record, %{"purpose" => to_string(purpose)},
|
||||
token_lifetime: strategy.sign_in_token_lifetime
|
||||
Jwt.token_for_user(record, %{"purpose" => "sign_in"},
|
||||
token_lifetime: strategy.sign_in_token_lifetime,
|
||||
purpose: :sign_in
|
||||
)
|
||||
|
||||
Ash.Resource.put_metadata(record, :token, token)
|
||||
|
|
|
@ -24,7 +24,7 @@ defmodule AshAuthentication.Strategy.Password.StrategyTest do
|
|||
assert MapSet.equal?(phases, MapSet.new(~w[register sign_in reset_request reset]a))
|
||||
end
|
||||
|
||||
test "it returns the correct phases when the strategy doesn't suport resetting" do
|
||||
test "it returns the correct phases when the strategy doesn't support resetting" do
|
||||
strategy = %Password{}
|
||||
|
||||
phases =
|
||||
|
@ -48,7 +48,7 @@ defmodule AshAuthentication.Strategy.Password.StrategyTest do
|
|||
assert MapSet.equal?(actions, MapSet.new(~w[register sign_in reset_request reset]a))
|
||||
end
|
||||
|
||||
test "it returns the correct actions when the strategy doesn't suport resetting" do
|
||||
test "it returns the correct actions when the strategy doesn't support resetting" do
|
||||
strategy = %Password{}
|
||||
|
||||
actions =
|
||||
|
|
|
@ -13,6 +13,8 @@ defmodule AshAuthentication.Strategy.PasswordTest do
|
|||
Strategy.Password.Resettable
|
||||
}
|
||||
|
||||
alias Example.User
|
||||
|
||||
doctest Password
|
||||
|
||||
describe "reset_token_for/1" do
|
||||
|
@ -26,4 +28,39 @@ defmodule AshAuthentication.Strategy.PasswordTest do
|
|||
assert claims["act"] == to_string(resettable.password_reset_action_name)
|
||||
end
|
||||
end
|
||||
|
||||
describe "regressions" do
|
||||
test "only one user token is generated for a new user registration" do
|
||||
user = build_user()
|
||||
subject = AshAuthentication.user_to_subject(user)
|
||||
|
||||
tokens = Example.Token |> Ash.read!() |> Enum.group_by(& &1.purpose)
|
||||
assert [%{subject: ^subject}] = tokens["user"]
|
||||
|
||||
token_types = tokens |> Map.keys() |> MapSet.new()
|
||||
assert token_types == MapSet.new(["user", "confirm"])
|
||||
end
|
||||
|
||||
test "only one token is generated for a user sign-in" do
|
||||
user = build_user()
|
||||
subject = AshAuthentication.user_to_subject(user)
|
||||
|
||||
Example.Token |> Ash.bulk_destroy!(:destroy, %{})
|
||||
|
||||
strategy = AshAuthentication.Info.strategy!(User, :password)
|
||||
|
||||
{:ok, _signed_in_user} =
|
||||
Strategy.action(
|
||||
strategy,
|
||||
:sign_in,
|
||||
%{
|
||||
username: user.username,
|
||||
password: user.__metadata__.password
|
||||
},
|
||||
context: [token_type: :sign_in]
|
||||
)
|
||||
|
||||
assert [%{subject: ^subject, purpose: "sign_in"}] = Example.Token |> Ash.read!()
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -9,4 +9,8 @@ defmodule Example.Token do
|
|||
table("tokens")
|
||||
repo(Example.Repo)
|
||||
end
|
||||
|
||||
actions do
|
||||
defaults [:read, :destroy]
|
||||
end
|
||||
end
|
||||
|
|
Loading…
Reference in a new issue