Current section
Files
Jump to
Current section
Files
lib/tokenizer.ex
defmodule Tokenizer do
defmodule InjectProcessor do
defstruct [:token, fmt: nil, allowed_fmt: nil, dst: nil, allowed_dst: nil]
end
defmodule InjectHMACProcessor do
defstruct [:key, hash: nil, fmt: nil, allowed_fmt: nil, dst: nil, allowed_dst: nil]
end
defmodule BearerAuth do
defstruct [:digest]
end
defmodule MacaroonAuth do
defstruct [:key]
end
defmodule FlysrcAuth do
defstruct [:allowed_orgs, :allowed_apps, :allowed_instances]
end
defmodule Secret do
defstruct inject_processor: nil,
inject_hmac_processor: nil,
bearer_auth: nil,
macaroon_auth: nil,
fly_src_auth: nil,
allowed_hosts: nil,
allowed_host_pattern: nil
def new(processor, auth, opts \\ []) do
%Secret{
allowed_hosts: Keyword.get(opts, :allowed_hosts),
allowed_host_pattern: Keyword.get(opts, :allowed_host_pattern)
}
|> merge_processor(processor)
|> merge_auth(auth)
end
defp merge_processor(%Secret{} = s, %InjectProcessor{} = processor),
do: %Secret{s | inject_processor: processor}
defp merge_processor(%Secret{} = s, %InjectHMACProcessor{} = processor),
do: %Secret{s | inject_hmac_processor: processor}
defp merge_auth(%Secret{} = s, %BearerAuth{} = auth), do: %Secret{s | bearer_auth: auth}
defp merge_auth(%Secret{} = s, %MacaroonAuth{} = auth), do: %Secret{s | macaroon_auth: auth}
defp merge_auth(%Secret{} = s, %FlysrcAuth{} = auth), do: %Secret{s | fly_src_auth: auth}
end
@spec seal(%Tokenizer.Secret{}, iodata()) :: {:ok, String.t()} | {:error, any()}
def seal(%Tokenizer.Secret{} = s, key) do
with {:ok, json} <- Jason.encode(s) do
{:ok, Base.encode64(:libsodium_crypto_box.seal(json, key))}
end
end
defimpl Jason.Encoder,
for: [InjectProcessor, InjectHMACProcessor, BearerAuth, MacaroonAuth, FlysrcAuth, Secret] do
def encode(struct, opts) do
struct
|> Map.from_struct()
|> Enum.filter(fn {_, v} -> v != nil end)
|> Enum.into(%{})
|> Jason.Encode.map(opts)
end
end
end