Current section
Files
Jump to
Current section
Files
lib/guardian/db/token.ex
defmodule Guardian.DB.Token do
@moduledoc """
A very simple model for storing tokens generated by `Guardian`.
"""
use Ecto.Schema
import Ecto.Changeset
import Ecto.Query, only: [where: 3]
alias Guardian.DB.Token
@primary_key {:jti, :string, autogenerate: false}
@allowed_fields ~w(jti typ aud iss sub exp jwt claims)a
schema "virtual: token" do
field(:typ, :string)
field(:aud, :string)
field(:iss, :string)
field(:sub, :string)
field(:exp, :integer)
field(:jwt, :string)
field(:claims, :map)
timestamps()
end
@doc """
Find one token by matching jti and aud.
"""
def find_by_claims(claims) do
jti = Map.get(claims, "jti")
aud = Map.get(claims, "aud")
query =
query_schema()
|> where([token], token.jti == ^jti and token.aud == ^aud)
|> Map.put(:prefix, prefix())
Guardian.DB.repo().one(query)
end
@doc """
Create a new token based on the JWT and decoded claims.
"""
def create(claims, jwt) do
prepared_claims =
claims
|> Map.put("jwt", jwt)
|> Map.put("claims", claims)
%Token{}
|> Ecto.put_meta(source: schema_name())
|> Ecto.put_meta(prefix: prefix())
|> cast(prepared_claims, @allowed_fields)
|> Guardian.DB.repo().insert()
end
@doc """
Purge any tokens that are expired. This should be done periodically to keep
your DB table clean of clutter.
"""
def purge_expired_tokens do
timestamp = Guardian.timestamp()
query_schema()
|> where([token], token.exp < ^timestamp)
|> Guardian.DB.repo().delete_all(prefix: prefix())
end
@doc false
def destroy_by_sub(sub) do
query =
query_schema()
|> where([token], token.sub == ^sub)
|> Map.put(:prefix, prefix())
Guardian.DB.repo().delete_all(query)
end
@doc false
def query_schema do
{schema_name(), Token}
end
@doc false
def schema_name do
:guardian
|> Application.fetch_env!(Guardian.DB)
|> Keyword.get(:schema_name, "guardian_tokens")
end
@doc false
def prefix do
:guardian
|> Application.fetch_env!(Guardian.DB)
|> Keyword.get(:prefix, nil)
end
@doc false
def destroy_token(nil, claims, jwt), do: {:ok, {claims, jwt}}
def destroy_token(model, claims, jwt) do
case Guardian.DB.repo().delete(model) do
{:error, _} -> {:error, :could_not_revoke_token}
nil -> {:error, :could_not_revoke_token}
_ -> {:ok, {claims, jwt}}
end
end
end