1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93
defmodule ExOvh.Ovh.Auth do
alias LoggingUtils
alias ExOvh.Ovh.Defaults
alias ExOvh.Ovh.Cache
@default_headers ["Content-Type": "application/json; charset=utf-8"]
@methods [:get, :post, :put, :delete]
@timeout 10_000
############################
# Public
############################
@spec prep_request(method :: atom, uri :: String.t, params :: map, signed :: boolean) :: tuple
def prep_request(method, uri, params, signed \\ :true), do: prep_request(ExOvh, method, uri, params, signed)
@spec prep_request(client :: atom, method :: atom, uri :: String.t, params :: map, signed :: boolean) :: tuple
def prep_request(client, method, uri, params, signed)
def prep_request(client, method, uri, params, :false) when method in [:get, :delete] do
uri = uri(config, uri)
if params !== :nil and params !== "", do: uri = uri <> URI.encode_query(params)
options = [ headers: headers([]), timeout: @timeout ]
{method, uri, options}
end
def prep_request(client, method, uri, params, :false) when method in [:post, :put] do
uri = uri(config, uri)
if params !== "" and params !== :nil, do: params = Poison.encode!(params)
options = [ body: params, headers: headers([]), timeout: @timeout ]
{method, uri, options}
end
def prep_request(client, method, uri, params, :true) when method in [:get, :delete] do
uri = uri(config, uri)
config = config(client)
if params !== :nil and params !== "", do: uri = uri <> URI.encode_query(params)
consumer_key = get_consumer_key(config)
opts = [app_secret(config), app_key(config), consumer_key, Atom.to_string(method), uri, ""]
options = [ headers: headers(opts, client), timeout: @timeout ]
{method, uri, options}
end
def prep_request(client, method, uri, params, :true) when method in [:post, :put] do
uri = uri(config, uri)
config = config(client)
consumer_key = get_consumer_key(config)
if params !== "" and params !== :nil and method in [:post, :put], do: params = Poison.encode!(params)
opts = [app_secret(config), consumer_key, Atom.to_string(method), uri, params]
options = [ body: params, headers: headers(opts, client), timeout: @timeout ]
{method, uri, options}
end
############################
# Private
############################
defp headers(opts) when opts === [], do: @default_headers
defp headers([app_secret, app_key, consumer_key, method, uri, body] = opts, client) do
time = :os.system_time(:seconds) + Cache.get_time_diff(client)
@default_headers ++
[
"X-Ovh-Application": app_key,
"X-Ovh-Consumer": consumer_key,
"X-Ovh-Timestamp": time,
"X-Ovh-Signature": sign_request([app_secret, consumer_key, String.upcase(method), uri, body, time])
]
end
defp sign_request([app_secret, consumer_key, method, uri, body, time] = opts) do
pre_hash = Enum.join(opts, "+") |> LoggingUtils.log_return(:debug)
post_hash = :crypto.hash(:sha, pre_hash) |> Base.encode16(case: :lower)
"$1$" <> post_hash
end
defp config(), do: Cache.get_config(ExOvh)
defp config(client), do: Cache.get_config(client)
defp endpoint(config), do: Defaults.endpoints()[config[:endpoint]]
defp api_version(config), do: config[:api_version]
defp uri(config, uri), do: endpoint(config) <> api_version(config) <> uri
defp app_secret(config), do: config[:application_secret]
defp app_key(config), do: config[:application_key]
defp get_consumer_key(config), do: config[:consumer_key]
end