Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add support for realm protocol param #28

Open
wants to merge 5 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
21 changes: 9 additions & 12 deletions lib/oauther.ex
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ defmodule OAuther do
:consumer_secret,
:token,
:token_secret,
realm: nil,
method: :hmac_sha1
]

Expand All @@ -13,6 +14,7 @@ defmodule OAuther do
consumer_secret: String.t(),
token: nil | String.t(),
token_secret: nil | String.t(),
realm: nil | String.t(),
method: :hmac_sha1 | :hmac_sha256 | :rsa_sha1 | :plaintext
}
end
Expand All @@ -22,9 +24,7 @@ defmodule OAuther do

@spec credentials(Enumerable.t()) :: Credentials.t() | no_return
def credentials(args) do
Enum.reduce(args, %Credentials{}, fn {key, val}, acc ->
:maps.update(key, val, acc)
end)
struct(Credentials, args)
end

@spec sign(String.t(), URI.t() | String.t(), params, Credentials.t()) :: params
Expand All @@ -50,8 +50,10 @@ defmodule OAuther do
{"oauth_signature_method", signature_method(creds.method)},
{"oauth_timestamp", timestamp()},
{"oauth_version", "1.0"}
| maybe_put_token(params, creds.token)
| params
]
|> maybe_add("oauth_token", creds.token)
|> maybe_add("realm", creds.realm)
end

@spec signature(String.t(), URI.t() | String.t(), params, Credentials.t()) :: binary
Expand Down Expand Up @@ -91,7 +93,7 @@ defmodule OAuther do
end

defp protocol_param?({key, _value}) do
String.starts_with?(key, "oauth_")
String.starts_with?(key, "oauth_") or key == "realm"
end

defp compose_header([_ | _] = params) do
Expand Down Expand Up @@ -176,13 +178,8 @@ defmodule OAuther do
megasec * 1_000_000 + sec
end

defp maybe_put_token(params, value) do
if is_nil(value) do
params
else
[{"oauth_token", value} | params]
end
end
defp maybe_add(params, _key, nil = _value), do: params
defp maybe_add(params, key, value), do: [{key, value} | params]

defp signature_method(:plaintext), do: "PLAINTEXT"
defp signature_method(:hmac_sha1), do: "HMAC-SHA1"
Expand Down
280 changes: 203 additions & 77 deletions test/oauther_test.exs
Original file line number Diff line number Diff line change
@@ -1,99 +1,225 @@
defmodule OAutherTest do
use ExUnit.Case

test "HMAC-SHA1 signature" do
creds =
OAuther.credentials(
consumer_secret: "kd94hf93k423kf44",
token_secret: "pfkkdhi9sl3r4s00",
consumer_key: "dpf43f3p2l4k3l03",
token: "nnch734d00sl2jdk"
)

params = protocol_params(creds)
assert signature(params, creds, "/photos") == "tR3+Ty81lMeYAr/Fid0kMTYa/WM="
describe "credentials/1" do
test "returns Credentials struct" do
assert %OAuther.Credentials{
consumer_key: "dpf43f3p2l4k3l03",
consumer_secret: "kd94hf93k423kf44",
method: :hmac_sha1,
token: "nnch734d00sl2jdk",
token_secret: "pfkkdhi9sl3r4s00",
realm: "Photos"
} ==
OAuther.credentials(
consumer_key: "dpf43f3p2l4k3l03",
consumer_secret: "kd94hf93k423kf44",
token: "nnch734d00sl2jdk",
token_secret: "pfkkdhi9sl3r4s00",
realm: "Photos"
)
end

test "by default realm is set to nil" do
assert %OAuther.Credentials{
consumer_key: "dpf43f3p2l4k3l03",
consumer_secret: "kd94hf93k423kf44",
method: :hmac_sha1,
token: "nnch734d00sl2jdk",
token_secret: "pfkkdhi9sl3r4s00",
realm: nil
} ==
OAuther.credentials(
consumer_key: "dpf43f3p2l4k3l03",
consumer_secret: "kd94hf93k423kf44",
token: "nnch734d00sl2jdk",
token_secret: "pfkkdhi9sl3r4s00"
)
end
end

test "HMAC-SHA256 signature" do
creds =
OAuther.credentials(
method: :hmac_sha256,
consumer_secret: "kd94hf93k423kf44",
token_secret: "pfkkdhi9sl3r4s00",
consumer_key: "dpf43f3p2l4k3l03",
token: "nnch734d00sl2jdk"
)

params = protocol_params(creds)
assert signature(params, creds, "/photos") == "WVPzl1j6ZsnkIjWr7e3OZ3jkenL57KwaLFhYsroX1hg="
describe "sign/4" do
test "returns list of params with oauth_signature" do
creds =
OAuther.credentials(
consumer_secret: "kd94hf93k423kf44",
token_secret: "pfkkdhi9sl3r4s00",
consumer_key: "dpf43f3p2l4k3l03",
token: "nnch734d00sl2jdk",
realm: "Photos"
)

assert [
{"oauth_signature", _},
{"realm", "Photos"},
{"oauth_token", "nnch734d00sl2jdk"},
{"oauth_consumer_key", "dpf43f3p2l4k3l03"},
{"oauth_nonce", _},
{"oauth_signature_method", "HMAC-SHA1"},
{"oauth_timestamp", _},
{"oauth_version", "1.0"},
{"custom_param", "123"}
] = OAuther.sign("get", "http://test.com", [{"custom_param", "123"}], creds)
end
end

test "RSA-SHA1 signature" do
creds =
OAuther.credentials(
method: :rsa_sha1,
consumer_secret: fixture_path("private_key.pem"),
consumer_key: "dpf43f3p2l4k3l03"
)
describe "header/1" do
test "Authorization header" do
{header, req_params} =
OAuther.header([
{"oauth_consumer_key", "dpf43f3p2l4k3l03"},
{"oauth_signature_method", "PLAINTEXT"},
{"oauth_signature", "kd94hf93k423kf44&"},
{"realm", "Photos"},
{"build", "Luna Park"}
])

assert header ==
{"Authorization",
~S(OAuth oauth_consumer_key="dpf43f3p2l4k3l03", oauth_signature_method="PLAINTEXT", oauth_signature="kd94hf93k423kf44%26", realm="Photos")}

assert req_params == [{"build", "Luna Park"}]
end
end

params = protocol_params(creds)
describe "protocol_params/2" do
test "returns params list with protocol params" do
creds =
OAuther.credentials(
consumer_secret: "kd94hf93k423kf44",
token_secret: "pfkkdhi9sl3r4s00",
consumer_key: "dpf43f3p2l4k3l03",
token: "nnch734d00sl2jdk",
realm: "Photos"
)

assert [
{"realm", "Photos"},
{"oauth_token", "nnch734d00sl2jdk"},
{"oauth_consumer_key", "dpf43f3p2l4k3l03"},
{"oauth_nonce", _},
{"oauth_signature_method", "HMAC-SHA1"},
{"oauth_timestamp", _},
{"oauth_version", "1.0"},
{"custom_param", "123"}
] = OAuther.protocol_params([{"custom_param", "123"}], creds)
end

assert signature(params, creds, "/photos") ==
"cyZ9hTJnRfkOnF5+OzxXWKKG+hRY+/esxdQAluJem1RlHkZQRsFEevOS5x+A1ZoS+aYlTU3xdHkEKIb/+xuqaavAUFVaIF/5448XsXqSTJomvpoC1c7yw5ArNZnPRLYwK3XYHaIr5FHXbiCG/ze093i2MpsusQU6Shn8lGJNMWE="
test "when realm is not present it's not included in the list of protocol params" do
creds =
OAuther.credentials(
consumer_secret: "kd94hf93k423kf44",
token_secret: "pfkkdhi9sl3r4s00",
consumer_key: "dpf43f3p2l4k3l03",
token: "nnch734d00sl2jdk",
realm: nil
)

assert [
{"oauth_token", "nnch734d00sl2jdk"},
{"oauth_consumer_key", "dpf43f3p2l4k3l03"},
{"oauth_nonce", _},
{"oauth_signature_method", "HMAC-SHA1"},
{"oauth_timestamp", _},
{"oauth_version", "1.0"},
{"custom_param", "123"}
] = OAuther.protocol_params([{"custom_param", "123"}], creds)
end
end

private_key = File.read!(fixture_path("private_key.pem"))
describe "signature/4" do
test "HMAC-SHA1 signature" do
creds =
OAuther.credentials(
consumer_secret: "kd94hf93k423kf44",
token_secret: "pfkkdhi9sl3r4s00",
consumer_key: "dpf43f3p2l4k3l03",
token: "nnch734d00sl2jdk"
)

params = protocol_params(creds)
assert signature(params, creds, "/photos") == "tR3+Ty81lMeYAr/Fid0kMTYa/WM="
end

creds =
OAuther.credentials(
method: :rsa_sha1,
consumer_secret: private_key,
consumer_key: "dpf43f3p2l4k3l03"
)
test "HMAC-SHA256 signature" do
creds =
OAuther.credentials(
method: :hmac_sha256,
consumer_secret: "kd94hf93k423kf44",
token_secret: "pfkkdhi9sl3r4s00",
consumer_key: "dpf43f3p2l4k3l03",
token: "nnch734d00sl2jdk"
)

params = protocol_params(creds)
assert signature(params, creds, "/photos") == "WVPzl1j6ZsnkIjWr7e3OZ3jkenL57KwaLFhYsroX1hg="
end

params = protocol_params(creds)
test "RSA-SHA1 signature" do
creds =
OAuther.credentials(
method: :rsa_sha1,
consumer_secret: fixture_path("private_key.pem"),
consumer_key: "dpf43f3p2l4k3l03"
)

assert signature(params, creds, "/photos") ==
"cyZ9hTJnRfkOnF5+OzxXWKKG+hRY+/esxdQAluJem1RlHkZQRsFEevOS5x+A1ZoS+aYlTU3xdHkEKIb/+xuqaavAUFVaIF/5448XsXqSTJomvpoC1c7yw5ArNZnPRLYwK3XYHaIr5FHXbiCG/ze093i2MpsusQU6Shn8lGJNMWE="
end
params = protocol_params(creds)

test "PLAINTEXT signature" do
creds =
OAuther.credentials(
method: :plaintext,
consumer_secret: "kd94hf93k423kf44",
consumer_key: "dpf43f3p2l4k3l03"
)
assert signature(params, creds, "/photos") ==
"cyZ9hTJnRfkOnF5+OzxXWKKG+hRY+/esxdQAluJem1RlHkZQRsFEevOS5x+A1ZoS+aYlTU3xdHkEKIb/+xuqaavAUFVaIF/5448XsXqSTJomvpoC1c7yw5ArNZnPRLYwK3XYHaIr5FHXbiCG/ze093i2MpsusQU6Shn8lGJNMWE="

assert signature([], creds, "/photos") == "kd94hf93k423kf44&"
end
private_key = File.read!(fixture_path("private_key.pem"))

test "signature with query params" do
creds =
OAuther.credentials(
consumer_secret: "kd94hf93k423kf44",
token_secret: "pfkkdhi9sl3r4s00",
consumer_key: "dpf43f3p2l4k3l03",
token: "nnch734d00sl2jdk"
)

params = protocol_params(creds)
assert signature(params, creds, "/photos?size=large") == "dzTFIxhRqhwfFqoXYgo4+hoPr2M="
end
creds =
OAuther.credentials(
method: :rsa_sha1,
consumer_secret: private_key,
consumer_key: "dpf43f3p2l4k3l03"
)

params = protocol_params(creds)

assert signature(params, creds, "/photos") ==
"cyZ9hTJnRfkOnF5+OzxXWKKG+hRY+/esxdQAluJem1RlHkZQRsFEevOS5x+A1ZoS+aYlTU3xdHkEKIb/+xuqaavAUFVaIF/5448XsXqSTJomvpoC1c7yw5ArNZnPRLYwK3XYHaIr5FHXbiCG/ze093i2MpsusQU6Shn8lGJNMWE="
end

test "Authorization header" do
{header, req_params} =
OAuther.header([
{"oauth_consumer_key", "dpf43f3p2l4k3l03"},
{"oauth_signature_method", "PLAINTEXT"},
{"oauth_signature", "kd94hf93k423kf44&"},
{"build", "Luna Park"}
])
test "PLAINTEXT signature" do
creds =
OAuther.credentials(
method: :plaintext,
consumer_secret: "kd94hf93k423kf44",
consumer_key: "dpf43f3p2l4k3l03"
)

assert header ==
{"Authorization",
~S(OAuth oauth_consumer_key="dpf43f3p2l4k3l03", oauth_signature_method="PLAINTEXT", oauth_signature="kd94hf93k423kf44%26")}
assert signature([], creds, "/photos") == "kd94hf93k423kf44&"
end

assert req_params == [{"build", "Luna Park"}]
test "signature with query params" do
creds =
OAuther.credentials(
consumer_secret: "kd94hf93k423kf44",
token_secret: "pfkkdhi9sl3r4s00",
consumer_key: "dpf43f3p2l4k3l03",
token: "nnch734d00sl2jdk"
)

params = protocol_params(creds)
assert signature(params, creds, "/photos?size=large") == "dzTFIxhRqhwfFqoXYgo4+hoPr2M="
end

test "signature with realm" do
creds =
OAuther.credentials(
consumer_secret: "kd94hf93k423kf44",
token_secret: "pfkkdhi9sl3r4s00",
consumer_key: "dpf43f3p2l4k3l03",
token: "nnch734d00sl2jdk",
realm: "Photos"
)

params = protocol_params(creds)
assert signature(params, creds, "/photos") == "9QG3oRtIpkf/+slqLB7SDlccBZU="
end
end

defp fixture_path(file_path) do
Expand Down