defmodule Oidcc.Userinfo do
use TelemetryRegistry
telemetry_event(%{
event: [:oidcc, :userinfo, :start],
description: "Emitted at the start of loading userinfo",
measurements: "%{system_time: non_neg_integer(), monotonic_time: integer()}",
metadata: "%{issuer: :uri_string.uri_string(), client_id: String.t()}"
})
telemetry_event(%{
event: [:oidcc, :userinfo, :stop],
description: "Emitted at the end of loading userinfo",
measurements: "%{duration: integer(), monotonic_time: integer()}",
metadata: "%{issuer: :uri_string.uri_string(), client_id: String.t()}"
})
telemetry_event(%{
event: [:oidcc, :userinfo, :exception],
description: "Emitted at the end of loading userinfo",
measurements: "%{duration: integer(), monotonic_time: integer()}",
metadata: "%{issuer: :uri_string.uri_string(), client_id: String.t()}"
})
@moduledoc """
OpenID Connect Userinfo
See https://openid.net/specs/openid-connect-core-1_0.html#UserInfo
## Telemetry
#{telemetry_docs()}
"""
@moduledoc since: "3.0.0"
alias Oidcc.ClientContext
alias Oidcc.Token
@doc """
Load userinfo for the given token
For a high level interface using `Oidcc.ProviderConfiguration.Worker`
see `Oidcc.retrieve_userinfo/5`.
## Examples
iex> {:ok, pid} =
...> Oidcc.ProviderConfiguration.Worker.start_link(%{
...> issuer: "https://api.login.yahoo.com"
...> })
...>
...> {:ok, client_context} =
...> Oidcc.ClientContext.from_configuration_worker(
...> pid,
...> "client_id",
...> "client_secret"
...> )
...>
...> # Get access_token from Oidcc.Token.retrieve/3
...> access_token = "access_token"
...>
...> Oidcc.Userinfo.retrieve(
...> access_token,
...> client_context,
...> %{expected_subject: "sub"}
...> )
...> # => {:ok, %{"sub" => "sub"}}
"""
@doc since: "3.0.0"
@spec retrieve(
access_token :: String.t(),
client_context :: ClientContext.t(),
opts :: :oidcc_userinfo.retrieve_opts()
) :: {:ok, :oidcc_jwt_util.claims()} | {:error, :oidcc_userinfo.error()}
@spec retrieve(
token :: Token.t(),
client_context :: ClientContext.t(),
opts :: :oidcc_userinfo.retrieve_opts()
) :: {:ok, :oidcc_jwt_util.claims()} | {:error, :oidcc_userinfo.error()}
def retrieve(token, client_context, opts) do
token =
case token do
token when is_binary(token) -> token
%Token{} = token -> Token.struct_to_record(token)
end
client_context = ClientContext.struct_to_record(client_context)
:oidcc_userinfo.retrieve(token, client_context, opts)
end
end