Packages

AWS Signature Version 4 Signing Library - Community-maintained fork

Current section

Files

Jump to
ex_aws_auth lib aws_auth query_parameters.ex
Raw

lib/aws_auth/query_parameters.ex

defmodule AWSAuth.QueryParameters do
@moduledoc false
# http://docs.aws.amazon.com/AmazonS3/latest/API/sigv4-query-string-auth.html
def sign(
access_key,
secret_key,
http_method,
url,
region,
service,
headers,
request_time,
payload
) do
uri = URI.parse(url)
http_method = String.upcase(http_method)
region = String.downcase(region)
service = String.downcase(service)
headers = Map.put_new(headers, "host", uri.host)
amz_date = request_time |> AWSAuth.Utils.format_time()
date = request_time |> AWSAuth.Utils.format_date()
scope = "#{date}/#{region}/#{service}/aws4_request"
params =
case uri.query do
nil ->
Map.new()
_ ->
URI.decode_query(uri.query)
end
params =
params
|> Map.put("X-Amz-Algorithm", "AWS4-HMAC-SHA256")
|> Map.put("X-Amz-Credential", "#{access_key}/#{scope}")
|> Map.put("X-Amz-Date", amz_date)
|> Map.put("X-Amz-Expires", "86400")
|> Map.put("X-Amz-SignedHeaders", "#{Map.keys(headers) |> Enum.join(";")}")
hashed_payload =
if service == "s3",
do: :unsigned,
else: AWSAuth.Utils.hash_sha256(payload)
string_to_sign =
AWSAuth.Utils.build_canonical_request(
http_method,
uri.path,
params,
headers,
hashed_payload
)
|> AWSAuth.Utils.build_string_to_sign(amz_date, scope)
signature =
AWSAuth.Utils.build_signing_key(secret_key, date, region, service)
|> AWSAuth.Utils.build_signature(string_to_sign)
params = params |> Map.put("X-Amz-Signature", signature)
query_string = URI.encode_query(params) |> String.replace("+", "%20")
"#{uri.scheme}://#{uri.authority}#{uri.path || "/"}?#{query_string}"
end
end