# `ExDisco.Auth`
[🔗](https://github.com/bo1ta/ex_disco/blob/main/lib/ex_disco/auth.ex#L1)

OAuth 1.0a flow functions for the Discogs API.

This module handles the OAuth handshake — requesting temporary tokens,
generating authorization URLs, and exchanging verifiers for permanent
credentials. For building auth values to pass to API functions, see
`ExDisco.Auth.Authorization`.

## OAuth 1.0a Flow

### Step 1: Get Consumer Credentials

Register your application at https://www.discogs.com/settings/developers to obtain
consumer_key and consumer_secret. Store these in your config:

    config :ex_disco, ExDisco,
      consumer_key: "your_consumer_key",
      consumer_secret: "your_consumer_secret"

### Step 2: Request a Temporary Token

When a user logs in, request a temporary token that directs them to Discogs:

    {:ok, request_token} = ExDisco.Auth.request_token("https://yourapp.com/callback")

Store the request_token temporarily (it's short-lived).

### Step 3: Redirect User to Authorization

Direct the user to Discogs with:

    url = ExDisco.Auth.authorize_url(request_token)
    # Redirect user to this URL

Discogs returns them to your callback URL with an oauth_verifier parameter.

### Step 4: Exchange for Long-Lived Credentials

Use the verifier to get an `Authorization` struct:

    {:ok, auth} = ExDisco.Auth.access_token(request_token, verifier)
    # Store auth.credentials for the user

### Step 5: Make Authenticated Requests

Pass the returned `Authorization` directly to API functions:

    {:ok, auth} = ExDisco.Auth.access_token(request_token, verifier)

    auth
    |> ExDisco.Users.get_identity()

# `access_token`

```elixir
@spec access_token(ExDisco.Auth.RequestToken.t(), String.t()) ::
  {:ok, ExDisco.Auth.Authorization.t()} | {:error, ExDisco.Error.t()}
```

Exchanges a verifier for permanent OAuth credentials using configured credentials.

This is Step 4 of the OAuth flow. After the user approves your app on Discogs
and is redirected back to your callback URL, you'll receive an oauth_verifier.
Use this function to exchange it for long-lived credentials.

Store the returned credentials (token and token_secret) for the user so you can
make authenticated requests on their behalf.

## Examples

    iex> req_token = %ExDisco.Auth.RequestToken{oauth_token: "...", oauth_token_secret: "..."}
    iex> ExDisco.Auth.access_token(req_token, "verifier_from_discogs")
    {:ok, %ExDisco.Auth.Authorization{type: :oauth, ...}}

# `access_token`

```elixir
@spec access_token(String.t(), String.t(), String.t(), String.t(), String.t()) ::
  {:ok, ExDisco.Auth.Authorization.t()} | {:error, ExDisco.Error.t()}
```

Exchanges a verifier for permanent OAuth credentials using explicit credentials.

Same as access_token/2 but accepts credentials directly instead of reading
from config. Use when your consumer credentials are not in config.

## Examples

    iex> ExDisco.Auth.access_token("key", "secret", "req_token", "req_secret", "verifier")
    {:ok, %ExDisco.Auth.Authorization{type: :oauth, ...}}

# `authorize_url`

```elixir
@spec authorize_url(String.t() | ExDisco.Auth.RequestToken.t()) :: String.t()
```

Generates the URL to redirect the user to for authorization.

This is Step 2 of the OAuth flow. Redirect the user to this URL so they can
approve your app. After approval, Discogs redirects them back to your callback
URL with an oauth_verifier parameter.

Can accept either a RequestToken struct or a raw oauth_token string.

## Examples

    iex> token = %ExDisco.Auth.RequestToken{oauth_token: "temp_token"}
    iex> url = ExDisco.Auth.authorize_url(token)
    iex> String.starts_with?(url, "https://www.discogs.com/oauth/authorize")
    true

    iex> url = ExDisco.Auth.authorize_url("temp_token")
    iex> String.contains?(url, "oauth_token=temp_token")
    true

# `request_token`

```elixir
@spec request_token(String.t()) ::
  {:ok, ExDisco.Auth.RequestToken.t()} | {:error, ExDisco.Error.t()}
```

Requests a temporary OAuth token using configured consumer credentials.

The callback_url is where Discogs will redirect the user after they authorize
your app. This is Step 1 of the OAuth flow.

## Examples

    iex> ExDisco.Auth.request_token("https://myapp.com/auth/callback")
    {:ok, %ExDisco.Auth.RequestToken{...}}

# `request_token`

```elixir
@spec request_token(String.t(), String.t(), String.t()) ::
  {:ok, ExDisco.Auth.RequestToken.t()} | {:error, ExDisco.Error.t()}
```

Requests a temporary OAuth token using explicit consumer credentials.

Use this if your consumer credentials are not in config. Same as request_token/1
but accepts credentials directly instead of reading from config.

## Examples

    iex> ExDisco.Auth.request_token("key", "secret", "https://myapp.com/auth/callback")
    {:ok, %ExDisco.Auth.RequestToken{...}}

---

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