Packages
An Ueberauth strategy for generic OpenID Connect (OIDC) authentication, and a library for implementing other OIDC strategies. Based on the Oidcc library.
Current section
Files
Jump to
Current section
Files
lib/ueberauth_oidcc/auth.ex
defmodule UeberauthOidcc.Auth do
@moduledoc """
Helper functions for converting an `Oidcc.Token.t()` and userinfo into `Ueberauth.Auth` structs.
"""
@doc """
Convert an `Oidcc.Token.t()` into an `Ueberauth.Auth.Credentials.t()`
The ID token value is in the `extra` map as `id_token`.
"""
@spec credentials(Oidcc.Token.t()) :: Ueberauth.Auth.Credentials.t()
def credentials(%Oidcc.Token{} = token) do
refresh_token =
case token.refresh do
%{token: token} -> token
_ -> nil
end
expires_at =
case token.access.expires do
e when is_integer(e) ->
System.system_time(:second) + e
_ ->
nil
end
%Ueberauth.Auth.Credentials{
token: token.access.token,
refresh_token: refresh_token,
token_type: "Bearer",
expires: !!token.access.expires,
expires_at: expires_at,
scopes: token.scope,
other: %{
id_token: token.id.token
}
}
end
@doc """
Converts an `Oidcc.Token.t()` and optional userinfo claims to an `Ueberauth.Auth.Info.t()`
Uses the [OpenID Connect standard claims](https://openid.net/specs/openid-connect-basic-1_0.html#StandardClaims).
"""
@spec info(Oidcc.Token.t()) :: Ueberauth.Auth.Info.t()
@spec info(Oidcc.Token.t(), %{binary() => binary()}) :: Ueberauth.Auth.Info.t()
def info(%Oidcc.Token{} = token, userinfo \\ %{}) do
claims =
Map.merge(
token.id.claims,
userinfo || %{}
)
urls =
%{}
|> add_optional_url(:profile, claims["profile"])
|> add_optional_url(:website, claims["website"])
# https://openid.net/specs/openid-connect-core-1_0.html#Claims
%Ueberauth.Auth.Info{
name: claims["name"],
first_name: claims["given_name"],
last_name: claims["family_name"],
nickname: claims["nickname"],
email: claims["email"],
# address claim is a JSON blob
location: nil,
description: nil,
image: claims["picture"],
phone: claims["phone_number"],
birthday: claims["birthdate"],
urls: urls
}
end
defp add_optional_url(urls, field, value)
defp add_optional_url(urls, _field, nil), do: urls
defp add_optional_url(urls, field, value), do: Map.put(urls, field, value)
end