analytics/lib/plausible_web/plugs/authorize_sites_api.ex
2021-05-05 10:30:05 +03:00

58 lines
1.5 KiB
Elixir

defmodule PlausibleWeb.AuthorizeSitesApiPlug do
import Plug.Conn
use Plausible.Repo
alias Plausible.Auth.ApiKey
alias PlausibleWeb.Api.Helpers, as: H
def init(options) do
options
end
def call(conn, _opts) do
with {:ok, raw_api_key} <- get_bearer_token(conn),
{:ok, api_key} <- verify_access(raw_api_key) do
user = Repo.get_by(Plausible.Auth.User, id: api_key.user_id)
assign(conn, :current_user, user)
else
{:error, :missing_api_key} ->
H.unauthorized(
conn,
"Missing API key. Please use a valid Plausible API key as a Bearer Token."
)
{:error, :invalid_api_key} ->
H.unauthorized(
conn,
"Invalid API key. Please make sure you're using a valid API key with access to the resource you've requested."
)
end
end
defp verify_access(api_key) do
hashed_key = ApiKey.do_hash(api_key)
found_key =
Repo.one(
from a in ApiKey,
where: a.key_hash == ^hashed_key,
where: fragment("? @> ?", a.scopes, ["sites:provision:*"])
)
cond do
found_key -> {:ok, found_key}
true -> {:error, :invalid_api_key}
end
end
defp get_bearer_token(conn) do
authorization_header =
Plug.Conn.get_req_header(conn, "authorization")
|> List.first()
case authorization_header do
"Bearer " <> token -> {:ok, String.trim(token)}
_ -> {:error, :missing_api_key}
end
end
end