Current section

Files

Jump to
hub_identity_elixir lib hub_identity token.ex
Raw

lib/hub_identity/token.ex

defmodule HubIdentityElixir.HubIdentity.Token do
alias HubIdentityElixir.HubIdentity.Server
def parse(token) do
with [header, claims, signature] <- String.split(token, "."),
{:ok, user_params} <- build_user_params(claims),
true <- verify_signature({header, claims}, signature) do
{:ok, user_params}
else
{:error, message} -> {:error, message}
false -> {:error, :signature_fail}
end
end
defp base_jason_decode(string) do
with {:ok, base_decoded} <- Base.url_decode64(string, padding: false),
{:ok, jason_decoded} <- Jason.decode(base_decoded) do
{:ok, jason_decoded}
else
_ -> {:error, :token_decode_fail}
end
end
defp build_user_params(claims) do
with {:ok,
%{
"owner_type" => owner_type,
"owner_uid" => owner_uid,
"sub" => subject
}} <- base_jason_decode(claims),
[user_type, uid] <- String.split(subject, ":") do
{:ok, %{owner_type: owner_type, owner_uid: owner_uid, uid: uid, user_type: user_type}}
else
{:error, message} -> {:error, message}
_ -> {:error, :claims_parse_fail}
end
end
defp verify_signature({header, claims}, signature) do
with {:ok, %{"kid" => key_id}} <- base_jason_decode(header),
{:ok, decoded_signature} <- Base.url_decode64(signature, padding: false),
%{"e" => encoded_e, "n" => encoded_n} <- Server.get_certs(key_id),
{:ok, e} <- Base.url_decode64(encoded_e, padding: false),
{:ok, n} <- Base.url_decode64(encoded_n, padding: false) do
:crypto.verify(:rsa, :sha256, "#{header}.#{claims}", decoded_signature, [e, n])
else
_ -> {:error, :signature_parse_fail}
end
end
end