defmodule Chalk.Client.ExchangeCredentials do
alias Chalk.Client
alias Chalk.Client.Request
defmodule Req do
@derive Jason.Encoder
defstruct client_id: nil, client_secret: nil, grant_type: nil
@type t :: %__MODULE__{
client_id: String.t(),
client_secret: String.t(),
grant_type: String.t()
}
end
defmodule Token do
@derive Jason.Encoder
# @enforce_keys [:access_token, :expires_in, :expires_at]
defstruct access_token: nil,
primary_environment: nil,
token_type: nil,
expires_in: nil,
expires_at: nil,
api_server: nil,
engines: [{nil, nil}]
@type t :: %__MODULE__{
access_token: String.t(),
token_type: String.t(),
primary_environment: String.t(),
expires_in: integer(),
expires_at: integer(),
api_server: String.t(),
engines: [{String.t(), String.t()}]
}
def valid?(%__MODULE__{} = token) do
{:ok, exp, _} = DateTime.from_iso8601(token.expires_at)
exp >= DateTime.utc_now() |> DateTime.add(5 * 60, :second)
end
end
def exchange_credentials(params, config \\ %{}) do
config = config |> Map.put(:unauthenticated, true)
c = config[:client] || Chalk
Request
|> struct(method: :post, endpoint: "v1/oauth/token", body: params)
|> Request.add_metadata(config)
|> c.send_request(Client.new(config))
|> c.handle_response(&map_exchange_credentials(&1))
end
defp map_exchange_credentials(body) do
Poison.Decode.decode(body, %{as: %Token{}})
end
end