defmodule ToweropsWeb.Plugs.ApiAuth do @moduledoc """ Plug for authenticating API requests using Bearer tokens. Expects the Authorization header to contain a Bearer token: Authorization: Bearer towerops_xxxxx Sets the following assigns on successful authentication: - :current_organization_id - The organization ID the token is scoped to - :api_authenticated - true Returns 401 Unauthorized if: - No Authorization header is present - Token is invalid or expired - Token format is incorrect """ import Phoenix.Controller, only: [json: 2] import Plug.Conn alias Towerops.ApiTokens def init(opts), do: opts def call(conn, _opts) do case get_req_header(conn, "authorization") do ["Bearer " <> token] -> authenticate_with_token(conn, token) _ -> conn |> put_status(:unauthorized) |> json(%{error: "Missing or invalid Authorization header"}) |> halt() end end defp authenticate_with_token(conn, token) do case ApiTokens.verify_token(token) do {:ok, organization_id} -> conn |> assign(:current_organization_id, organization_id) |> assign(:api_authenticated, true) {:error, :invalid_token} -> conn |> put_status(:unauthorized) |> json(%{error: "Invalid or expired API token"}) |> halt() end end end