-module(aws4_request). -compile([no_auto_import, nowarn_unused_vars, nowarn_unused_function, nowarn_nomatch]). -export([signer/4, with_region/2, with_service/2, with_session_token/2, with_date_time/2, sign_bits/2, sign_string/2]). -export_type([signer/0]). -type signer() :: {signer, gleam@option:option({{integer(), integer(), integer()}, {integer(), integer(), integer()}}), binary(), binary(), binary(), binary(), gleam@option:option(binary())}. -file("/Users/louis/src/gleam/aws4_request/src/aws4_request.gleam", 26). -spec signer(binary(), binary(), binary(), binary()) -> signer(). signer(Access_key_id, Secret_access_key, Region, Service) -> {signer, none, Access_key_id, Secret_access_key, Region, Service, none}. -file("/Users/louis/src/gleam/aws4_request/src/aws4_request.gleam", 42). -spec with_region(signer(), binary()) -> signer(). with_region(Signer, Region) -> erlang:setelement(5, Signer, Region). -file("/Users/louis/src/gleam/aws4_request/src/aws4_request.gleam", 46). -spec with_service(signer(), binary()) -> signer(). with_service(Signer, Service) -> erlang:setelement(6, Signer, Service). -file("/Users/louis/src/gleam/aws4_request/src/aws4_request.gleam", 53). -spec with_session_token(signer(), binary()) -> signer(). with_session_token(Signer, Session_token) -> erlang:setelement(7, Signer, {some, Session_token}). -file("/Users/louis/src/gleam/aws4_request/src/aws4_request.gleam", 60). -spec with_date_time( signer(), {{integer(), integer(), integer()}, {integer(), integer(), integer()}} ) -> signer(). with_date_time(Signer, Date_time) -> erlang:setelement(2, Signer, {some, Date_time}). -file("/Users/louis/src/gleam/aws4_request/src/aws4_request.gleam", 206). -spec add_session_token_header(list({binary(), GXH}), gleam@option:option(GXH)) -> list({binary(), GXH}). add_session_token_header(Headers, Maybe_session_token) -> case Maybe_session_token of none -> Headers; {some, Session_token} -> gleam@list:prepend( Headers, {<<"x-amz-security-token"/utf8>>, Session_token} ) end. -file("/Users/louis/src/gleam/aws4_request/src/aws4_request.gleam", 202). -spec now() -> {{integer(), integer(), integer()}, {integer(), integer(), integer()}}. now() -> _pipe = os:system_time(1000), calendar:system_time_to_universal_time(_pipe, 1000). -file("/Users/louis/src/gleam/aws4_request/src/aws4_request.gleam", 75). -spec sign_bits(signer(), gleam@http@request:request(bitstring())) -> gleam@http@request:request(bitstring()). sign_bits(Signer, Request) -> Payload_hash = gleam@string:lowercase( binary:encode_hex(crypto:hash(sha256, erlang:element(4, Request))) ), {{Year, Month, Day}, {Hour, Minute, Second}} = gleam@option:lazy_unwrap( erlang:element(2, Signer), fun now/0 ), Date = gleam@string:concat( [gleam@string:pad_left(gleam@int:to_string(Year), 4, <<"0"/utf8>>), gleam@string:pad_left(gleam@int:to_string(Month), 2, <<"0"/utf8>>), gleam@string:pad_left(gleam@int:to_string(Day), 2, <<"0"/utf8>>)] ), Date_time = gleam@string:concat( [Date, <<"T"/utf8>>, gleam@string:pad_left(gleam@int:to_string(Hour), 2, <<"0"/utf8>>), gleam@string:pad_left(gleam@int:to_string(Minute), 2, <<"0"/utf8>>), gleam@string:pad_left(gleam@int:to_string(Second), 2, <<"0"/utf8>>), <<"Z"/utf8>>] ), Request@1 = gleam@http@request:set_header( Request, <<"host"/utf8>>, case erlang:element(7, Request) of none -> erlang:element(6, Request); {some, Port} -> <<<<(erlang:element(6, Request))/binary, ":"/utf8>>/binary, (gleam@int:to_string(Port))/binary>> end ), Method = gleam@string:uppercase( gleam@http:method_to_string(erlang:element(2, Request@1)) ), Headers = begin _pipe = erlang:element(3, Request@1), _pipe@1 = add_session_token_header(_pipe, erlang:element(7, Signer)), _pipe@2 = gleam@list:prepend( _pipe@1, {<<"x-amz-date"/utf8>>, Date_time} ), _pipe@3 = gleam@list:prepend( _pipe@2, {<<"x-amz-content-sha256"/utf8>>, Payload_hash} ), _pipe@4 = gleam@list:map( _pipe@3, fun(Header) -> {gleam@string:lowercase(erlang:element(1, Header)), erlang:element(2, Header)} end ), gleam@list:sort( _pipe@4, fun(A, B) -> gleam@string:compare(erlang:element(1, A), erlang:element(1, B)) end ) end, Header_names = begin _pipe@5 = Headers, _pipe@6 = gleam@list:map(_pipe@5, fun(H) -> erlang:element(1, H) end), gleam@string:join(_pipe@6, <<";"/utf8>>) end, Path@1 = case erlang:element(8, Request@1) of <<""/utf8>> -> <<"/"/utf8>>; Path -> Path end, Canonical_request = gleam@string:concat( [Method, <<"\n"/utf8>>, Path@1, <<"\n"/utf8>>, gleam@option:unwrap(erlang:element(9, Request@1), <<""/utf8>>), <<"\n"/utf8>>, begin _pipe@7 = Headers, _pipe@8 = gleam@list:map( _pipe@7, fun(H@1) -> <<<<(erlang:element(1, H@1))/binary, ":"/utf8>>/binary, (erlang:element(2, H@1))/binary>> end ), gleam@string:join(_pipe@8, <<"\n"/utf8>>) end, <<"\n"/utf8>>, <<"\n"/utf8>>, Header_names, <<"\n"/utf8>>, Payload_hash] ), Scope = gleam@string:concat( [Date, <<"/"/utf8>>, erlang:element(5, Signer), <<"/"/utf8>>, erlang:element(6, Signer), <<"/aws4_request"/utf8>>] ), To_sign = gleam@string:concat( [<<"AWS4-HMAC-SHA256"/utf8>>, <<"\n"/utf8>>, Date_time, <<"\n"/utf8>>, Scope, <<"\n"/utf8>>, gleam@string:lowercase( binary:encode_hex( crypto:hash(sha256, <>) ) )] ), Key = begin _pipe@9 = <<"AWS4"/utf8, (erlang:element(4, Signer))/binary>>, _pipe@10 = gleam@crypto:hmac(<>, sha256, _pipe@9), _pipe@11 = gleam@crypto:hmac( <<(erlang:element(5, Signer))/binary>>, sha256, _pipe@10 ), _pipe@12 = gleam@crypto:hmac( <<(erlang:element(6, Signer))/binary>>, sha256, _pipe@11 ), gleam@crypto:hmac(<<"aws4_request"/utf8>>, sha256, _pipe@12) end, Signature = begin _pipe@13 = <>, _pipe@14 = gleam@crypto:hmac(_pipe@13, sha256, Key), _pipe@15 = binary:encode_hex(_pipe@14), gleam@string:lowercase(_pipe@15) end, Authorization = gleam@string:concat( [<<"AWS4-HMAC-SHA256 Credential="/utf8>>, erlang:element(3, Signer), <<"/"/utf8>>, Scope, <<<<",SignedHeaders="/utf8, Header_names/binary>>/binary, ",Signature="/utf8>>, Signature] ), Headers@1 = [{<<"authorization"/utf8>>, Authorization} | Headers], erlang:setelement(3, Request@1, Headers@1). -file("/Users/louis/src/gleam/aws4_request/src/aws4_request.gleam", 66). -spec sign_string(signer(), gleam@http@request:request(binary())) -> gleam@http@request:request(bitstring()). sign_string(Signer, Request) -> sign_bits( Signer, gleam@http@request:map(Request, fun gleam_stdlib:identity/1) ).