Packages

A tesla middleware, for use with PlugHmac as a http client.

Current section

Files

Jump to
tesla_hmac_auth lib tesla_hmac_auth.ex
Raw

lib/tesla_hmac_auth.ex

defmodule TeslaHmacAuth do
@moduledoc """
A tesla middleware, for use with PlugHmac as a http client.
### Example usage
- Setting by client_id & secret:
```elixir
defmodule MyClient do
use Tesla
plug #{inspect(__MODULE__)}, client_id: "id", secret: "secret"
end
```
- Setting by get_secret_fun:
```elixir
defmodule MyClient do
use Tesla
plug #{inspect(__MODULE__)}, get_secret_fun: &MyConfig.get_secret/0
end
```
- Setting by config:
`config :tesla_hmac_auth, auth: {"client_id", "secret"}`
```elixir
defmodule MyClient do
use Tesla
plug #{inspect(__MODULE__)}
end
```
"""
@behaviour Tesla.Middleware
def call(env, next, opts) when is_list(opts) do
call(env, next, Map.new(opts))
end
def call(env, next, %{client_id: client_id, secret: secret} = opts) do
env
|> make_header(fn -> {:ok, client_id, secret} end, Map.drop(opts, [:client_id, :secret]))
|> Tesla.run(next)
end
def call(env, next, %{get_secret_fun: fun} = opts) when is_function(fun, 0) do
env
|> make_header(fun, Map.delete(opts, :get_secret_fun))
|> Tesla.run(next)
end
def call(env, next, opts) do
env
|> make_header(&__MODULE__.get_secret/0, opts || %{})
|> Tesla.run(next)
end
defp make_header(env, get_secret_fun, opts) do
key = Map.get(opts, :client_signature_name, "Authorization")
hmac_algo = Map.get(opts, :hmac_algo, :sha256)
method = to_string(env.method) |> String.upcase()
%{path: path} = URI.parse(env.url)
value =
PlugHmac.make_header(
hmac_algo,
get_secret_fun,
method,
path,
URI.encode_query(env.query),
env.body,
nil
)
Tesla.put_header(env, key, value)
end
def get_secret do
{client_id, secret} = Application.fetch_env!(:tesla_hmac_auth, :auth)
{:ok, client_id, secret}
end
end