Current section

Files

Jump to
indieweb lib indieweb auth default token.ex
Raw

lib/indieweb/auth/default/token.ex

defmodule IndieWeb.Auth.DefaultTokenAdapter do
@moduledoc """
Provides a implementation of the token-centric parts of IndieAuth.
"""
@behaviour IndieWeb.Auth.Token.Adapter
alias IndieWeb.Cache
@impl true
def info(token, options \\ []) do
case Cache.get(do_make_token_key(token), options) do
data when is_binary(data) -> URI.decode_query(data)
_ -> {:error, :token_not_found}
end
end
@impl true
def delete(token, options \\ []) do
Cache.delete(do_make_token_key(token), options)
end
@impl true
def generate(client_id, scope, options \\ []) do
token = do_make_token(client_id, scope)
case Cache.set(
do_make_token_key(token),
URI.encode_query(%{"scope" => scope, "client_id" => client_id}),
[],
options
) do
:ok -> {:ok, token}
error -> {:error, :failed_to_save_token, reason: error}
end
end
defp do_make_token(client_id, scope) do
token_data =
[
:crypto.strong_rand_bytes(32),
client_id,
scope
]
|> Enum.map(&Base.encode16(&1, padding: false, case: :lower))
|> Enum.join()
:crypto.hash(:sha256, token_data) |> Base.encode64(padding: false)
end
defp do_make_token_key(token) do
:crypto.hash(:sha256, "token:#{token}")
|> Base.encode16(padding: false, case: :lower)
end
end