Current section

Files

Jump to
ueberauth_auth0 lib ueberauth strategy auth0.ex
Raw

lib/ueberauth/strategy/auth0.ex

defmodule Ueberauth.Strategy.Auth0 do
@moduledoc """
Provides an Ueberauth strategy for authenticating with Auth0.
You can edit the behaviour of the Strategy by including some options when you register your provider.
To set the `uid_field`
config :ueberauth, Ueberauth,
providers: [
auth0: { Ueberauth.Strategy.Auth0, [uid_field: :email] }
]
Default is `:user_id`
To set the default ['scopes'](https://auth0.com/docs/scopes) (permissions):
config :ueberauth, Ueberauth,
providers: [
auth0: { Ueberauth.Strategy.Auth0, [default_scope: "openid email"] }
]
Deafult is "openid email"
"""
use Ueberauth.Strategy, uid_field: :user_id,
default_scope: "openid email",
oauth2_module: Ueberauth.Strategy.Auth0.OAuth
alias Ueberauth.Auth.Info
alias Ueberauth.Auth.Credentials
@doc """
Handles the callback from Auth0. When there is a failure from Auth0 the failure is included in the
`ueberauth_failure` struct. Otherwise the information returned from Auth0 is returned in the `Ueberauth.Auth` struct.
"""
def handle_callback!(%Plug.Conn{ params: %{ "code" => code } } = conn) do
module = option(conn, :oauth2_module)
redirect_uri = callback_url(conn)
client = apply(module, :get_token!, [[code: code, redirect_uri: redirect_uri]])
token = client.token
if token.access_token == nil do
set_errors!(conn, [error(token.other_params["error"], token.other_params["error_description"])])
else
fetch_user(conn, client)
end
end
@doc false
def handle_callback!(conn) do
set_errors!(conn, [error("missing_code", "No code received")])
end
@doc """
Cleans up the private area of the connection used for passing the raw Auth0 response around during the callback.
"""
def handle_cleanup!(conn) do
conn
|> put_private(:auth0_user, nil)
|> put_private(:auth0_token, nil)
end
defp fetch_user(conn, client = %{token: token}) do
conn = put_private(conn, :auth0_token, token)
case OAuth2.Client.get(client, "/userinfo") do
{ :ok, %OAuth2.Response{status_code: 401, body: _body}} ->
set_errors!(conn, [error("token", "unauthorized")])
{ :ok, %OAuth2.Response{status_code: status_code, body: user} } when status_code in 200..399 ->
put_private(conn, :auth0_user, user)
{ :error, %OAuth2.Error{reason: reason} } ->
set_errors!(conn, [error("OAuth2", reason)])
end
end
@doc """
Fetches the uid field from the Auth0 response.
"""
def uid(conn) do
conn.private.auth0_user[option(conn, :uid_field) |> to_string]
end
@doc """
Includes the credentials from the Auth0 response.
"""
def credentials(conn) do
token = conn.private.auth0_token
scopes = (token.other_params["scope"] || "")
|> String.split(",")
%Credentials{
token: token.access_token,
refresh_token: token.refresh_token,
token_type: token.token_type,
expires_at: token.expires_at,
expires: !!token.expires_at,
scopes: scopes,
other: token.other_params
}
end
@doc """
Fetches the fields to populate the info section of the `Ueberauth.Auth` struct.
"""
def info(conn) do
user = conn.private.auth0_user
%Info{
name: user["name"],
nickname: user["nickname"],
email: user["email"],
location: user["locale"],
first_name: user["given_name"],
last_name: user["family_name"],
image: user["picture"]
}
end
defp option(conn, key) do
Dict.get(options(conn), key, Dict.get(default_options, key))
end
end