Fix guardian db hook when refresh the access token

This commit is contained in:
Chocobozzz 2019-08-12 17:41:41 +02:00
parent 6d221212ef
commit ac1dab0fc0
No known key found for this signature in database
GPG key ID: 583A612D890159BE
5 changed files with 41 additions and 10 deletions

View file

@ -19,7 +19,7 @@ config :mobilizon, MobilizonWeb.Endpoint,
config :logger, config :logger,
backends: [:console], backends: [:console],
compile_time_purge_level: :debug, compile_time_purge_level: :debug,
level: :info level: :debug
# Configure your database # Configure your database
config :mobilizon, Mobilizon.Repo, config :mobilizon, Mobilizon.Repo,

View file

@ -253,13 +253,21 @@ defmodule Mobilizon.Users do
end end
def generate_access_token(user) do def generate_access_token(user) do
with {:ok, access_token, _claims} <- MobilizonWeb.Guardian.encode_and_sign(user, %{}, token_type: "access", ttl: {5, :seconds}) do with {:ok, access_token, _claims} <-
MobilizonWeb.Guardian.encode_and_sign(user, %{},
token_type: "access",
ttl: {5, :seconds}
) do
{:ok, access_token} {:ok, access_token}
end end
end end
def generate_refresh_token(user) do def generate_refresh_token(user) do
with {:ok, refresh_token, _claims} <- MobilizonWeb.Guardian.encode_and_sign(user, %{}, token_type: "refresh", ttl: {30, :days}) do with {:ok, refresh_token, _claims} <-
MobilizonWeb.Guardian.encode_and_sign(user, %{},
token_type: "refresh",
ttl: {30, :days}
) do
{:ok, refresh_token} {:ok, refresh_token}
end end
end end

View file

@ -61,6 +61,14 @@ defmodule MobilizonWeb.Guardian do
end end
end end
def on_refresh({old_token, old_claims}, {new_token, new_claims}, _options) do
with {:ok, _, _} <- Guardian.DB.on_refresh({old_token, old_claims}, {new_token, new_claims}) do
{:ok, {old_token, old_claims}, {new_token, new_claims}}
end
end
def on_exchange(old_stuff, new_stuff, options), do: on_refresh(old_stuff, new_stuff, options)
# def build_claims(claims, _resource, opts) do # def build_claims(claims, _resource, opts) do
# claims = claims # claims = claims
# |> encode_permissions_into_claims!(Keyword.get(opts, :permissions)) # |> encode_permissions_into_claims!(Keyword.get(opts, :permissions))

View file

@ -65,7 +65,8 @@ defmodule MobilizonWeb.Resolvers.User do
""" """
def login_user(_parent, %{email: email, password: password}, _resolution) do def login_user(_parent, %{email: email, password: password}, _resolution) do
with {:ok, %User{} = user} <- Users.get_user_by_email(email, true), with {:ok, %User{} = user} <- Users.get_user_by_email(email, true),
{:ok, %{access_token: access_token, refresh_token: refresh_token}} <- Users.authenticate(%{user: user, password: password}) do {:ok, %{access_token: access_token, refresh_token: refresh_token}} <-
Users.authenticate(%{user: user, password: password}) do
{:ok, %{access_token: access_token, refresh_token: refresh_token, user: user}} {:ok, %{access_token: access_token, refresh_token: refresh_token, user: user}}
else else
{:error, :user_not_found} -> {:error, :user_not_found} ->
@ -86,8 +87,11 @@ defmodule MobilizonWeb.Resolvers.User do
}, },
_context _context
) do ) do
with {:ok, _old, {exchanged_token, _claims}} <- MobilizonWeb.Guardian.exchange(refresh_token, "refresh", "access", ttl: { 1, :days}), with {:ok, user, _claims} <- MobilizonWeb.Guardian.resource_from_token(refresh_token),
{:ok, user, _claims} <- MobilizonWeb.Guardian.resource_from_token(refresh_token), {:ok, _old, {exchanged_token, _claims}} <-
MobilizonWeb.Guardian.exchange(refresh_token, ["access", "refresh"], "access",
ttl: {1, :days}
),
{:ok, refresh_token} <- Users.generate_refresh_token(user) do {:ok, refresh_token} <- Users.generate_refresh_token(user) do
{:ok, %{access_token: exchanged_token, refresh_token: refresh_token}} {:ok, %{access_token: exchanged_token, refresh_token: refresh_token}}
else else
@ -128,8 +132,14 @@ defmodule MobilizonWeb.Resolvers.User do
with {:check_confirmation_token, {:ok, %User{} = user}} <- with {:check_confirmation_token, {:ok, %User{} = user}} <-
{:check_confirmation_token, Activation.check_confirmation_token(token)}, {:check_confirmation_token, Activation.check_confirmation_token(token)},
{:get_actor, actor} <- {:get_actor, Users.get_actor_for_user(user)}, {:get_actor, actor} <- {:get_actor, Users.get_actor_for_user(user)},
{:ok, %{access_token: access_token, refresh_token: refresh_token}} <- Users.generate_tokens(user) do {:ok, %{access_token: access_token, refresh_token: refresh_token}} <-
{:ok, %{access_token: access_token, refresh_token: refresh_token, user: Map.put(user, :default_actor, actor)}} Users.generate_tokens(user) do
{:ok,
%{
access_token: access_token,
refresh_token: refresh_token,
user: Map.put(user, :default_actor, actor)
}}
else else
err -> err ->
Logger.info("Unable to validate user with token #{token}") Logger.info("Unable to validate user with token #{token}")
@ -180,7 +190,8 @@ defmodule MobilizonWeb.Resolvers.User do
def reset_password(_parent, %{password: password, token: token}, _resolution) do def reset_password(_parent, %{password: password, token: token}, _resolution) do
with {:ok, %User{} = user} <- with {:ok, %User{} = user} <-
ResetPassword.check_reset_password_token(password, token), ResetPassword.check_reset_password_token(password, token),
{:ok, %{access_token: access_token, refresh_token: refresh_token}} <- Users.authenticate(%{user: user, password: password}) do {:ok, %{access_token: access_token, refresh_token: refresh_token}} <-
Users.authenticate(%{user: user, password: password}) do
{:ok, %{access_token: access_token, refresh_token: refresh_token, user: user}} {:ok, %{access_token: access_token, refresh_token: refresh_token, user: user}}
end end
end end

View file

@ -32,7 +32,11 @@ defmodule MobilizonWeb.Schema do
@desc "A JWT and the associated user ID" @desc "A JWT and the associated user ID"
object :login do object :login do
field(:access_token, non_null(:string), description: "A JWT Token for this session") field(:access_token, non_null(:string), description: "A JWT Token for this session")
field(:refresh_token, non_null(:string), description: "A JWT Token to refresh the access token")
field(:refresh_token, non_null(:string),
description: "A JWT Token to refresh the access token"
)
field(:user, non_null(:user), description: "The user associated to this session") field(:user, non_null(:user), description: "The user associated to this session")
end end