Skip to content

Commit

Permalink
formatting changes
Browse files Browse the repository at this point in the history
  • Loading branch information
handnot2 committed Nov 7, 2017
1 parent 04cbc87 commit e0d69bd
Show file tree
Hide file tree
Showing 12 changed files with 830 additions and 447 deletions.
11 changes: 11 additions & 0 deletions .formatter.exs
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
[
inputs: [
"mix.exs",
"{config,lib,test}/**/*.{ex,exs}"
],

locals_without_parens: [
plug: 1,
plug: 2
]
]
4 changes: 4 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,9 @@
## Changelog

### v0.7.2

- Formatting changes

### v0.7.1

- Skipping tests related to duplicate query parameters. The AWS Signature V4 specs
Expand Down
90 changes: 53 additions & 37 deletions lib/sigaws.ex
Original file line number Diff line number Diff line change
Expand Up @@ -110,8 +110,7 @@ defmodule Sigaws do
"""
@spec sign_req(binary, keyword) :: {:ok, map, map} | {:error, atom, binary}
def sign_req(url, additional_named_input) when is_list(additional_named_input) do
with {:ok, vinput} <- validate_signing_input(url, additional_named_input)
do
with {:ok, vinput} <- validate_signing_input(url, additional_named_input) do
Signer.sign_req(vinput)
end
end
Expand All @@ -137,8 +136,7 @@ defmodule Sigaws do
"""
@spec sign_url(binary, keyword) :: {:ok, map, map} | {:error, atom, binary}
def sign_url(url, additional_named_input) when is_list(additional_named_input) do
with {:ok, vinput} <- validate_signing_input(url, additional_named_input)
do
with {:ok, vinput} <- validate_signing_input(url, additional_named_input) do
Signer.sign_url(vinput)
end
end
Expand Down Expand Up @@ -174,22 +172,27 @@ defmodule Sigaws do
| `{:error, :mismatched, "X-Amz-Date"}` |
"""
@spec verify(binary, keyword) :: {:ok, Ctxt.t} | {:error, atom, binary}
@spec verify(binary, keyword) :: {:ok, Ctxt.t()} | {:error, atom, binary}
def verify(req_path, opts) do
opts_map = Map.new(opts)
with {:ok, provider} <- provider_opt(opts_map),
{:ok, method} <- method_opt(opts_map),
{:ok, qs} <- qs_opt(opts_map),
{:ok, params} <- qp_opt(opts_map),
{:ok, headers} <- headers_opt(opts_map),
{:ok, body} <- body_opt(opts_map)
do

with {:ok, provider} <- provider_opt(opts_map),
{:ok, method} <- method_opt(opts_map),
{:ok, qs} <- qs_opt(opts_map),
{:ok, params} <- qp_opt(opts_map),
{:ok, headers} <- headers_opt(opts_map),
{:ok, body} <- body_opt(opts_map) do
params = qs |> URI.decode_query() |> Map.merge(params)
headers = headers |> Util.downcase_keys()

validated_opts = %{
method: method, params: params, headers: headers, body: body,
method: method,
params: params,
headers: headers,
body: body,
provider: provider
}

if Verifier.presigned?(params) do
Verifier.verify_url(req_path, validated_opts)
else
Expand All @@ -201,43 +204,53 @@ defmodule Sigaws do
end
end

@spec validate_signing_input(binary, keyword) ::
{:ok, map} | {:error, atom, binary}
@spec validate_signing_input(binary, keyword) :: {:ok, map} | {:error, atom, binary}
defp validate_signing_input(url, opts) do
with opts_map = Map.new(opts),
{:ok, method} <- method_opt(opts_map),
{:ok, params} <- qp_opt(opts_map),
{:ok, headers} <- headers_opt(opts_map),
{:ok, body} <- body_opt(opts_map),
{:ok, method} <- method_opt(opts_map),
{:ok, params} <- qp_opt(opts_map),
{:ok, headers} <- headers_opt(opts_map),
{:ok, body} <- body_opt(opts_map),
{:ok, signed_at_amz_dt} <- signed_at_opt(opts_map),
{:ok, dt} <- Util.parse_amz_dt(signed_at_amz_dt),
{:ok, rg} <- region_opt(opts_map),
{:ok, sv} <- service_opt(opts_map),
{:ok, creds} <- creds_opts(opts_map),
{:ok, normalize_path} <- normalize_path_opt(opts_map)
do
{:ok, dt} <- Util.parse_amz_dt(signed_at_amz_dt),
{:ok, rg} <- region_opt(opts_map),
{:ok, sv} <- service_opt(opts_map),
{:ok, creds} <- creds_opts(opts_map),
{:ok, normalize_path} <- normalize_path_opt(opts_map) do
%URI{path: req_path, query: qs} = uri = URI.parse(url)
req_path = if req_path, do: req_path, else: "/"

params = (qs || "") |> URI.decode_query() |> Map.merge(params)
headers = headers |> Util.downcase_keys() |> Map.put_new("host", uri_host(uri))

signing_key = case creds do
%{secret: secret} ->
{:ok, key} = dt |> DateTime.to_date() |> Util.signing_key(rg, sv, secret)
key
%{signing_key: key} -> key
end

{:ok, %{req_path: req_path, method: method, normalize_path: normalize_path,
params: params, headers: headers, body: body,
signed_at: signed_at_amz_dt, region: rg, service: sv,
access_key: creds[:access_key], signing_key: signing_key}}
signing_key =
case creds do
%{secret: secret} ->
{:ok, key} = dt |> DateTime.to_date() |> Util.signing_key(rg, sv, secret)
key

%{signing_key: key} ->
key
end

{:ok, %{
req_path: req_path,
method: method,
normalize_path: normalize_path,
params: params,
headers: headers,
body: body,
signed_at: signed_at_amz_dt,
region: rg,
service: sv,
access_key: creds[:access_key],
signing_key: signing_key
}}
end
end

defp uri_host(%URI{scheme: "https", host: h, port: 443}), do: h
defp uri_host(%URI{scheme: "http", host: h, port: 80}), do: h
defp uri_host(%URI{scheme: "http", host: h, port: 80}), do: h
defp uri_host(%URI{host: nil}), do: ""
defp uri_host(%URI{host: h, port: nil}), do: h
defp uri_host(%URI{host: h, port: p}), do: "#{h}:#{p}"
Expand All @@ -248,6 +261,7 @@ defmodule Sigaws do
v = String.upcase(m)
if v in @http_methods, do: {:ok, v}, else: @method_error
end

defp method_opt(%{method: _}), do: @method_error
defp method_opt(_), do: {:ok, "GET"}

Expand Down Expand Up @@ -281,12 +295,14 @@ defmodule Sigaws do
defp signed_at_opt(%{signed_at: %DateTime{time_zone: "Etc/UTC"} = dt}) do
{:ok, %DateTime{dt | microsecond: {0, 0}} |> Util.amz_dt_iso()}
end

defp signed_at_opt(%{signed_at: s}) when is_binary(s) do
case Util.parse_amz_dt(s) do
{:ok, _} -> {:ok, s}
_ -> @signed_at_error
end
end

defp signed_at_opt(%{signed_at: _}), do: @signed_at_error
defp signed_at_opt(_), do: {:ok, Util.amz_dt_now() |> Util.amz_dt_iso()}

Expand Down
28 changes: 17 additions & 11 deletions lib/sigaws/ctxt.ex
Original file line number Diff line number Diff line change
Expand Up @@ -25,16 +25,22 @@ defmodule Sigaws.Ctxt do
@type expires_in :: integer | nil

@type t :: %__MODULE__{
access_key: binary,
region: binary,
service: binary,
signed_at_amz_dt: binary,
expires_in: expires_in,
signed_headers: signed_headers,
signature: binary
}
access_key: binary,
region: binary,
service: binary,
signed_at_amz_dt: binary,
expires_in: expires_in,
signed_headers: signed_headers,
signature: binary
}

defstruct [:access_key, :region, :service,
:signed_at_amz_dt, :expires_in,
:signed_headers, :signature]
defstruct [
:access_key,
:region,
:service,
:signed_at_amz_dt,
:expires_in,
:signed_headers,
:signature
]
end
10 changes: 4 additions & 6 deletions lib/sigaws/provider.ex
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
defmodule Sigaws.Provider do

@moduledoc """
This behavior defines the callbacks expected from an implementation needed
for signature verification.
Expand All @@ -13,7 +12,7 @@ defmodule Sigaws.Provider do
- region is not one of supported regions
- service is not one of supported services
- request expired (based on `signed_at_amz_dt` and `expires_in`)
The `signing_key` callback is called only when
`pre_verification` succeeds without any error. This key should be generated
as outlined
Expand Down Expand Up @@ -43,8 +42,7 @@ defmodule Sigaws.Provider do
| `{:error, atom, binary}` | For other errors as defined by the implementation |
| `:ok` | Verification passes |
"""
@callback pre_verification(ctxt :: Ctxt.t) ::
:ok | {:error, reason :: atom, info :: binary}
@callback pre_verification(ctxt :: Ctxt.t()) :: :ok | {:error, reason :: atom, info :: binary}

@doc """
Return the signing key to be used for verification based on access key ID
Expand All @@ -60,6 +58,6 @@ defmodule Sigaws.Provider do
| `{:error, atom, binary}` | For other errors as defined by the implementation |
| `{:ok, binary}` | Valid signing key is generated |
"""
@callback signing_key(ctxt :: Ctxt.t) ::
{:ok, key :: binary} | {:error, reason :: atom, info :: binary}
@callback signing_key(ctxt :: Ctxt.t()) ::
{:ok, key :: binary} | {:error, reason :: atom, info :: binary}
end
Loading

0 comments on commit e0d69bd

Please sign in to comment.