# `KeenAuth.Processor`
[🔗](https://github.com/KeenMate/keen_auth/blob/main/lib/processor.ex#L1)

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
        ]
      ]

# `process`

```elixir
@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`

```elixir
@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

# `current_processor`

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`

Extracts the processor module from the configuration.

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

# `process`

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`

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.

---

*Consult [api-reference.md](api-reference.md) for complete listing*
