KeenAuth.Processor behaviour (KeenAuth v1.0.1)

Copy Markdown View Source

Defines the processor behavior for handling authentication business logic.

Processors are the business logic hub in KeenAuth's pipeline architecture. They receive normalized user data from mappers and can implement custom validation, user creation, role assignment, auditing, and other business-specific logic.

Pipeline Stage

The processor sits between the mapper and storage in the authentication flow:

Strategy  Mapper  **Processor**  Storage

Flexibility

Processors can be as simple or sophisticated as needed:

  • Simple: Pass data through unchanged
  • Advanced: Database lookups, validation, user creation, role assignment, auditing

Example Implementation

defmodule MyApp.Auth.Processor do
  @behaviour KeenAuth.Processor

  def process(conn, provider, mapped_user, oauth_response) do
    with {:ok, user} <- find_or_create_user(mapped_user),
         :ok <- validate_permissions(user),
         {:ok, user} <- assign_roles(user, oauth_response) do
      {:ok, conn, user, oauth_response}
    else
      {:error, reason} ->
        conn
        |> put_flash(:error, "Authentication failed")
        |> redirect(to: "/login")
    end
  end

  def sign_out(conn, provider, params) do
    conn
    |> KeenAuth.Storage.delete()
    |> redirect(to: "/")
  end
end

Configuration

Specify your processor in the strategy configuration:

config :keen_auth,
  strategies: [
    azure_ad: [
      processor: MyApp.Auth.Processor,
      # ... other config
    ]
  ]

Summary

Callbacks

Processes the authenticated user and OAuth response.

Handles user sign out.

Functions

Gets the processor module for the given provider.

Extracts the processor module from the configuration.

Delegates to the configured processor for the given provider.

Delegates to the configured processor for sign out.

Callbacks

process(conn, provider, mapped_user, response)

@callback process(
  conn :: Plug.Conn.t(),
  provider :: atom(),
  mapped_user :: KeenAuth.User.t() | map(),
  response :: KeenAuth.AuthenticationController.oauth_callback_response() | nil
) ::
  {:ok, Plug.Conn.t(), KeenAuth.User.t() | map(),
   KeenAuth.AuthenticationController.oauth_callback_response() | nil}
  | Plug.Conn.t()

Processes the authenticated user and OAuth response.

This callback is called after the user data has been normalized by the mapper. It's where you implement your application's business logic for handling authenticated users.

Parameters

  • conn - The Plug connection
  • provider - The OAuth provider atom (e.g., :azure_ad, :github)
  • mapped_user - User data normalized by the mapper
  • response - The complete OAuth response including tokens

Return Values

  • {:ok, conn, user, response} - Success, proceed to storage
  • conn - Halt processing (e.g., redirect to error page)

Example

def process(conn, :azure_ad, mapped_user, oauth_response) do
  case create_or_update_user(mapped_user) do
    {:ok, user} -> {:ok, conn, user, oauth_response}
    {:error, _} -> redirect(conn, to: "/login?error=invalid_user")
  end
end

sign_out(conn, provider, params)

@callback sign_out(conn :: Plug.Conn.t(), provider :: binary(), params :: map()) ::
  Plug.Conn.t()

Handles user sign out.

This callback is called when a user signs out. It should clean up any user-specific data and redirect appropriately.

Parameters

  • conn - The Plug connection
  • provider - The OAuth provider atom or binary
  • params - Request parameters (may include redirect destination)

Return Value

  • conn - The modified connection (typically with a redirect)

Example

def sign_out(conn, _provider, params) do
  conn
  |> clear_user_session()
  |> redirect(to: params["redirect_to"] || "/")
end

Functions

current_processor(conn, provider)

Gets the processor module for the given provider.

Fetches the configuration from the connection and returns the processor module configured for the provider.

get_processor(config, provider)

Extracts the processor module from the configuration.

Returns the configured processor for the provider, or the default processor if none is configured.

process(conn, provider, mapped_user, oauth_response)

Delegates to the configured processor for the given provider.

This function looks up the processor configured for the specific provider and calls its process/4 function.

sign_out(conn, provider, params)

Delegates to the configured processor for sign out.

This function looks up the processor configured for the specific provider and calls its sign_out/3 function.