Current section

Files

Jump to
btrz_ex_auth_api lib plug verify_premium.ex
Raw

lib/plug/verify_premium.ex

if Code.ensure_loaded?(Plug) do
defmodule BtrzAuth.Plug.VerifyPremium do
@moduledoc """
Looks for and validates that the passed `keys` features are present in the account data under `conn.private.account["premium"]`
saved by `BtrzAuth.Plug.VerifyApiKey` (the order of the plugs is very important!)
If the premium keys are not found under `conn.private.account`, the pipeline will be halted and the `conn.resp_body` with:
```elixir
%{
"error" => "unauthorized",
"reason" => "premium_not_verified"
}
```
Options:
* `keys` - list of atom premium features to verify. Defaults to: `[]`
### Example
```elixir
plug BtrzAuth.Plug.VerifyPremium, keys: [:special_content]
```
"""
import Plug.Conn
require Logger
@spec init(Keyword.t()) :: Keyword.t()
def init(opts) do
keys = Keyword.get(opts, :keys, [])
Keyword.put(opts, :keys, keys)
end
@spec call(Plug.Conn.t(), Keyword.t()) :: Plug.Conn.t()
def call(%Plug.Conn{private: %{btrz_token_type: :internal}} = conn, _opts), do: conn
def call(conn, opts) do
Logger.debug("accessing VerifyPremium plug with opts: #{inspect(opts)}..")
with account <- Map.get(conn.private, :account),
premium_keys <- get_premium_keys(account),
true <- are_valid_premium_keys?(premium_keys, opts) do
conn
else
_ ->
conn
|> BtrzAuth.ErrorHandler.auth_error({:unauthorized, :premium_not_verified})
|> halt()
end
end
defp get_premium_keys(%{"premium" => premium}) do
premium |> Enum.map(fn x -> String.to_atom(x) end)
end
defp get_premium_keys(_), do: []
@doc false
@spec are_valid_premium_keys?(List.t(), Keyword.t()) :: Boolean.t()
defp are_valid_premium_keys?(premium, opts) do
keys = opts[:keys]
diff = premium -- keys
length(premium) === length(diff) + length(keys)
end
end
end