defmodule PinchflatWeb.ApiAuthPlug do @moduledoc """ Authenticates API requests using a Bearer token. The token is stored in the settings database and managed via the web UI. A token must be generated before API access is possible — the API is always authenticated, there is no open-access mode. Clients should send the token in the Authorization header: Authorization: Bearer """ import Plug.Conn alias Pinchflat.Settings def init(opts), do: opts def call(conn, _opts) do expected_token = Settings.get!(:api_token) if credential_set?(expected_token) do case get_req_header(conn, "authorization") do ["Bearer " <> token] -> if String.trim(token) == expected_token do conn else send_unauthorized(conn) end _ -> send_unauthorized(conn) end else # No API token has been generated yet — deny all access send_unauthorized(conn, "API token not configured. Generate one in Settings.") end end defp credential_set?(credential) do credential && credential != "" end defp send_unauthorized(conn, message \\ "Unauthorized") do conn |> put_resp_content_type("application/json") |> send_resp(401, ~s({"errors":{"detail":"#{message}"}})) |> halt() end end