Skip to content

Commit

Permalink
handle all types in exhange
Browse files Browse the repository at this point in the history
  • Loading branch information
Hanspagh committed Jun 15, 2016
1 parent 7564c1d commit c4cee60
Show file tree
Hide file tree
Showing 2 changed files with 43 additions and 29 deletions.
49 changes: 25 additions & 24 deletions lib/guardian.ex
Original file line number Diff line number Diff line change
Expand Up @@ -197,38 +197,39 @@ defmodule Guardian do
The token with typ 'refresh' will be revoked after the exhange
"""
@spec exchange!(String.t) :: {:ok, String.t, Map} |
@spec exchange(String.t, String.t, String.t) :: {:ok, String.t, Map} |
{:error, atom} |
{:error, String.t}

def exchange!(long_living_jwt) do
case decode_and_verify(long_living_jwt) do
{:ok, found_claims} ->
do_exchange!(long_living_jwt, found_claims)
def exchange(old_jwt, from_typ, to_typ) do
case decode_and_verify(old_jwt) do
{:ok, found_claims} -> do_exchange(from_typ, to_typ, found_claims)
{:error, reason} -> {:error, reason}
end
end

defp do_exchange!(long_living_jwt, claims) do
type = Map.get(claims, "typ")
if type === "refresh" do
new_claims = claims
|> Map.drop(["jti", "iat", "exp", "nbf"])
|> Guardian.Claims.jti
|> Guardian.Claims.nbf
|> Guardian.Claims.iat
|> Guardian.Claims.ttl
{:ok, resource} = Guardian.serializer.from_token(claims["sub"])

case encode_and_sign(resource, nil, new_claims) do
{:ok, jwt, full_claims} ->
revoke!(long_living_jwt, peek_claims(long_living_jwt), %{})
{:ok, jwt, full_claims}
{:error, reason} -> {:error, reason}
end
defp check_type(claims, typ) when is_binary(typ) do
Map.get(claims, "typ") === typ
end

defp check_type(claims, typ_list) when is_list(typ_list) do
typ = Map.get(claims, "typ")
typ_list |> Enum.any?(&(&1 === typ))
end

defp check_type(_claims, _typ) do
false
end

else
{:error, :incorrect_token_type}
defp do_exchange(from_typ, to_typ, claims) do
case check_type(claims, from_typ) do
false -> {:error, :incorrect_token_type}
true ->
{:ok, resource} = Guardian.serializer.from_token(claims["sub"])
case encode_and_sign(resource, to_typ, %{}) do
{:ok, jwt, full_claims} -> {:ok, jwt, full_claims}
{:error, reason} -> {:error, reason}
end
end
end

Expand Down
23 changes: 18 additions & 5 deletions test/guardian_test.exs
Original file line number Diff line number Diff line change
Expand Up @@ -325,25 +325,38 @@ defmodule GuardianTest do
refute Map.get(new_claims, "exp") == Map.get(claims, "exp")
end

test "exchange" do
{:ok, jwt, claims} = Guardian.encode_and_sign("thinger", "refresh")

{:ok, new_jwt, new_claims} = Guardian.exchange(jwt, "refresh", "access")

test "exchange!" do
{:ok, jwt, claims} = Guardian.encode_and_sign("thinger", "refresh")
refute jwt == new_jwt
refute Map.get(new_claims, "jti") == nil
refute Map.get(new_claims, "jti") == Map.get(claims, "jti")

refute Map.get(new_claims, "exp") == nil
refute Map.get(new_claims, "exp") == Map.get(claims, "exp")
assert Map.get(new_claims, "typ") == "access"
end

test "exchange with list of from typs" do
{:ok, jwt, claims} = Guardian.encode_and_sign("thinger", "rememberMe")

{:ok, new_jwt, new_claims} = Guardian.exchange!(jwt)
{:ok, new_jwt, new_claims} = Guardian.exchange(jwt, ["refresh", "rememberMe"], "access")

refute jwt == new_jwt
refute Map.get(new_claims, "jti") == nil
refute Map.get(new_claims, "jti") == Map.get(claims, "jti")

refute Map.get(new_claims, "exp") == nil
refute Map.get(new_claims, "exp") == Map.get(claims, "exp")
assert Map.get(new_claims, "typ") == "access"
end

test "exchange! with a incorrect typ" do
test "exchange with a wrong from typ" do
{:ok, jwt, _claims} = Guardian.encode_and_sign("thinger")

assert Guardian.exchange!(jwt) == {:error, :incorrect_token_type}
assert Guardian.exchange(jwt, "refresh", "access") == {:error, :incorrect_token_type}
end


Expand Down

0 comments on commit c4cee60

Please sign in to comment.