UeberauthToken.Strategy behaviour (ueberauth_token v0.2.0-dev)

A workflow for validation of oauth2 tokens on the resource server.

The strategy handle_callback/1 function is invoked for validation token calidation in either of the following cases:

  1. As a plug in a plug pipeline which assigns an ueberauth struct to %Conn{}

    pipeline :api do plug :accepts, ["json"] plug UeberauthToken.Plug, provider: UeberauthToken.TestProvider end

As a plug, the callback phase of ueberauth is adapted to validate the oauth2 access token. The ueberauth struct is returned in the assigns fields of the struct in one of the two following ways:

# Failed validation
Plug.Conn{assigns: %{ueberauth_failure: %Ueberauth.Failure{}}}

# Successful validation
Plug.Conn{assigns: %{ueberauth_auth: %Ueberauth.Auth{}}}
  1. As a token_auth/3 function call which returns an ueberauth struct.

    token_auth(token, provider, [])

The token_auth/3 validation function returns one of the following forms:

# Failed validation
%Ueberauth.Failure{}

# Successful validation
%Ueberauth.Auth{}

See full description of the config options in UeberauthToken.Config @moduledoc.

defining-an-provider-module

Defining an provider module

An provider module must be specified in order for UeberauthToken to know what authorization server provider to validate against. The provider must implement the callbacks specified in the module UeberauthToken.Strategy.

The following functions should be implemented by the provider module:

@callback get_payload(token :: String.t(), opts :: list()) :: {:ok, map()} | {:error, map()}
@callback valid_token?(token :: String.t(), opts :: list) :: boolean()
@callback get_uid(conn :: Conn.t()) :: any()
@callback get_credentials(conn :: Conn.t()) :: Credentials.t()
@callback get_info(conn :: Conn.t()) :: Info.t()
@callback get_extra(conn :: Conn.t()) :: Extra.t()
@callback get_ttl(conn :: Conn.t()) :: integer()

For a basic example of token validation in a plug pipeline, see UeberauthToken.Plug

For a basic example of token validation as a function, see UeberauthToken.token_auth/3

Link to this section Summary

Callbacks

To populate the ueberauth credentials struct from the payload in :ueberauth_token private conn field.

To populate the ueberauth extra struct from the payload in :ueberauth_token private conn field.

To populate the ueberauth info struct from the payload in :ueberauth_token private conn field.

To get the payload.

To get the ttl from the ueberauth struct. The ttl must be returned n milliseconds.

To populate the ueberauth uid struct from the payload in :ueberauth_token private conn field.

Verifies a token.

Functions

Handles the callback as follows

Clean up private fields after construction of the Ueberauth struct

Link to this section Callbacks

Link to this callback

get_credentials(conn)

@callback get_credentials(
  conn :: %Plug.Conn{
    adapter: term(),
    assigns: term(),
    body_params: term(),
    cookies: term(),
    halted: term(),
    host: term(),
    method: term(),
    owner: term(),
    params: term(),
    path_info: term(),
    path_params: term(),
    port: term(),
    private: %{ueberauth_token: %{payload: map()}},
    query_params: term(),
    query_string: term(),
    remote_ip: term(),
    req_cookies: term(),
    req_headers: term(),
    request_path: term(),
    resp_body: term(),
    resp_cookies: term(),
    resp_headers: term(),
    scheme: term(),
    script_name: term(),
    secret_key_base: term(),
    state: term(),
    status: term()
  }
) :: Credentials.t()

To populate the ueberauth credentials struct from the payload in :ueberauth_token private conn field.

Callback function to be implemented by the provider

Link to this callback

get_extra(conn)

@callback get_extra(
  conn :: %Plug.Conn{
    adapter: term(),
    assigns: term(),
    body_params: term(),
    cookies: term(),
    halted: term(),
    host: term(),
    method: term(),
    owner: term(),
    params: term(),
    path_info: term(),
    path_params: term(),
    port: term(),
    private: %{ueberauth_token: %{payload: map()}},
    query_params: term(),
    query_string: term(),
    remote_ip: term(),
    req_cookies: term(),
    req_headers: term(),
    request_path: term(),
    resp_body: term(),
    resp_cookies: term(),
    resp_headers: term(),
    scheme: term(),
    script_name: term(),
    secret_key_base: term(),
    state: term(),
    status: term()
  }
) :: Extra.t()

To populate the ueberauth extra struct from the payload in :ueberauth_token private conn field.

Callback function to be implemented by the provider

@callback get_info(
  conn :: %Plug.Conn{
    adapter: term(),
    assigns: term(),
    body_params: term(),
    cookies: term(),
    halted: term(),
    host: term(),
    method: term(),
    owner: term(),
    params: term(),
    path_info: term(),
    path_params: term(),
    port: term(),
    private: %{ueberauth_token: %{payload: map()}},
    query_params: term(),
    query_string: term(),
    remote_ip: term(),
    req_cookies: term(),
    req_headers: term(),
    request_path: term(),
    resp_body: term(),
    resp_cookies: term(),
    resp_headers: term(),
    scheme: term(),
    script_name: term(),
    secret_key_base: term(),
    state: term(),
    status: term()
  }
) :: Info.t()

To populate the ueberauth info struct from the payload in :ueberauth_token private conn field.

Callback function to be implemented by the provider

Link to this callback

get_payload(token, opts)

@callback get_payload(token :: String.t(), opts :: list()) ::
  {:ok, map()} | {:error, %{key: String.t(), message: String.t()}}

To get the payload.

Callback function to be implemented by the provider

The payload in turn is put into a private field :ueberauth_token.

The payload is the map from which other callback functions will need to build the :ueberauth structs.

Link to this callback

get_ttl(payload)

@callback get_ttl(payload :: map()) :: integer()

To get the ttl from the ueberauth struct. The ttl must be returned n milliseconds.

Callback function to be implemented by the provider

@callback get_uid(
  conn :: %Plug.Conn{
    adapter: term(),
    assigns: term(),
    body_params: term(),
    cookies: term(),
    halted: term(),
    host: term(),
    method: term(),
    owner: term(),
    params: term(),
    path_info: term(),
    path_params: term(),
    port: term(),
    private: %{ueberauth_token: %{payload: map()}},
    query_params: term(),
    query_string: term(),
    remote_ip: term(),
    req_cookies: term(),
    req_headers: term(),
    request_path: term(),
    resp_body: term(),
    resp_cookies: term(),
    resp_headers: term(),
    scheme: term(),
    script_name: term(),
    secret_key_base: term(),
    state: term(),
    status: term()
  }
) :: any()

To populate the ueberauth uid struct from the payload in :ueberauth_token private conn field.

Callback function to be implemented by the provider

Link to this callback

valid_token?(token, opts)

@callback valid_token?(token :: String.t(), opts :: list()) :: boolean()

Verifies a token.

Callback function to be implemented by the provider.

Link to this section Functions

Link to this function

extract_token(access_token)

Link to this function

handle_callback!(conn)

@spec handle_callback!(Plug.Conn.t()) :: Plug.Conn.t()

Handles the callback as follows:

  1. Extracts token from "Bearer token" if it is in that format

  2. Tries to get the token data from the cache if

  • The cache is turned on
  • The token is present in the cache already
  • If this stage successfully retrieves the token, then subsequent steps will be skipped.
  1. By way of a callback function, it seeks data for populating the ueberauth struct using the token. The callback function must be provided through an provider in the config or can be provided manually in the conn.assigns field.

  2. The provider will cache the data if the use_cache configuration option is set to true.

Link to this function

handle_cleanup!(conn)

Clean up private fields after construction of the Ueberauth struct

Link to this function

rework_error_struct(conn, provider)