| defmodule PlausibleWeb.Plugs.AuthorizePluginsAPI do |
| @moduledoc """ |
| Plug for Basic HTTP Authentication using |
| Plugins API Tokens lookup. |
| """ |
|
|
| alias PlausibleWeb.Plugins.API.Errors |
| alias Plausible.Plugins.API.Tokens |
| import Plug.Conn |
|
|
| def init(opts), do: opts |
|
|
| def call(conn, opts \\ []) do |
| send_error? = |
| Keyword.get(opts, :send_error?, true) |
|
|
| with {:ok, token} <- extract_token(conn), |
| {:ok, conn} <- authorize(conn, token) do |
| conn |
| else |
| {:unauthorized, conn} -> |
| if send_error? do |
| Errors.unauthorized(conn) |
| else |
| conn |
| end |
| end |
| end |
|
|
| defp authorize(conn, token_value) do |
| case Tokens.find(token_value) do |
| {:ok, token} -> |
| {:ok, token} = Tokens.update_last_seen(token) |
| {:ok, Plug.Conn.assign(conn, :authorized_site, token.site)} |
|
|
| {:error, :not_found} -> |
| {:unauthorized, conn} |
| end |
| end |
|
|
| defp extract_token(conn) do |
| with ["Basic " <> encoded_user_and_pass] <- get_req_header(conn, "authorization"), |
| {:ok, decoded_user_and_pass} <- Base.decode64(encoded_user_and_pass) do |
| case :binary.split(decoded_user_and_pass, ":") do |
| [_user, token_value] -> {:ok, token_value} |
| [token_value] -> {:ok, token_value} |
| end |
| else |
| _ -> |
| {:unauthorized, conn} |
| end |
| end |
| end |
|
|