From d45fb80fef1a1235955b08b5d5d43a0caad3b001 Mon Sep 17 00:00:00 2001 From: pgvandelden Date: Mon, 22 Mar 2021 11:35:00 +0100 Subject: [PATCH 1/2] use sha256 in launch --- lib/lti.ex | 4 ++-- test/lti_test.exs | 12 ++++++------ 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/lib/lti.ex b/lib/lti.ex index 65aa44e..4eb124a 100644 --- a/lib/lti.ex +++ b/lib/lti.ex @@ -15,7 +15,7 @@ defmodule LTI do oauth_version: "1.0", oauth_nonce: nonce(), oauth_timestamp: timestamp(), - oauth_signature_method: "HMAC-SHA1" + oauth_signature_method: "HMAC-SHA256" } end @@ -28,7 +28,7 @@ defmodule LTI do %OAuthData{} = oauth_params, %LaunchParams{} = launch_params ) do - :sha + :sha256 |> hmac_fun( encode_secret(secret), base_string(creds, oauth_params, launch_params) diff --git a/test/lti_test.exs b/test/lti_test.exs index e417e7e..11c1fe8 100644 --- a/test/lti_test.exs +++ b/test/lti_test.exs @@ -27,7 +27,7 @@ defmodule LTITest do oauth_version: "1.0", oauth_nonce: "nonce", oauth_timestamp: "timestamp", - oauth_signature_method: "HMAC-SHA1" + oauth_signature_method: "HMAC-SHA256" } @valid_launch_params %LTI.LaunchParams{ @@ -52,12 +52,12 @@ defmodule LTITest do launch_data = LTI.launch_query(oauth_params, @valid_launch_params, []) assert "roles=Student" in launch_data - assert "oauth_signature_method=HMAC-SHA1" in launch_data + assert "oauth_signature_method=HMAC-SHA256" in launch_data end test "signature/3 encodes all the variables" do assert LTI.signature(@credentials, @oauth_credentials, @valid_launch_params) == - "NgK2X7WQb+CwHikcJMjqnJTsSBk=" + "709pOpaAubqFMg2w3dPgNj5psL2NKr+of14tl3dYC2c=" end test "signature/3 encodes all the variables, with url with capitals" do @@ -66,12 +66,12 @@ defmodule LTITest do @oauth_credentials, @valid_launch_params ) == - "NgK2X7WQb+CwHikcJMjqnJTsSBk=" + "709pOpaAubqFMg2w3dPgNj5psL2NKr+of14tl3dYC2c=" end test "signature/3 with url with query string parameters" do assert LTI.signature(@credentials_with_query_string, @oauth_credentials, @valid_launch_params) == - "68JVqL7aRC1meflszD8p+onIvWI=" + "LzQhP77ayGyHsS7RnRLzHuLd56Oy1+iL1h9HY2tyGmk=" end test "signature/3 with url with query string with nested query parameters" do @@ -79,7 +79,7 @@ defmodule LTITest do @credentials_with_nested_query_string, @oauth_credentials, @valid_launch_params - ) == "f/DC8AEzcDcMUPs07nc0tPG8/CM=" + ) == "AUU3pCgwluS7tRBLRCGnXeoY9MK2NCX+P5VpofkIgE0=" end test "oauth_params/1 should always be different" do From 86eeca9cd6bc8e386d6c1fe61c9e341529156f7b Mon Sep 17 00:00:00 2001 From: pgvandelden Date: Mon, 22 Mar 2021 11:36:57 +0100 Subject: [PATCH 2/2] use signature_method dynamically in api call --- lib/lti_result.ex | 38 ++-- test/lti_result_test.exs | 406 ++++++++++++++++++++++----------------- 2 files changed, 249 insertions(+), 195 deletions(-) diff --git a/lib/lti_result.ex b/lib/lti_result.ex index eeb4cc0..4d0c7d2 100644 --- a/lib/lti_result.ex +++ b/lib/lti_result.ex @@ -27,24 +27,31 @@ defmodule LTIResult do {:ok, "iyyQNRQyXTlpLJPJns3ireWjQxo%3D"} """ def signature(url, oauth_header, secret) do - {parameters, [{"oauth_signature", received_signature}]} = - extract_header_elements(oauth_header) - - with {:ok, _} <- validate_parameters(parameters) do - basestring = base_string(url, parameters) - - signature = generate_signature(secret, basestring) - - if signature == received_signature do - {:ok, signature} - else - {:error, [:unmatching_signatures]} + with {parameters, [{"oauth_signature", received_signature}]} <- + extract_header_elements(oauth_header), + {:ok, _} <- validate_parameters(parameters), + {_, signature_method} <- + List.keyfind( + parameters, + "oauth_signature_method", + 0, + {"oauth_signature_method", "HMAC-SHA1"} + ), + basestring <- base_string(url, parameters), + signature <- generate_signature(secret, signature_method, basestring) do + case signature == received_signature do + true -> + {:ok, signature} + + false -> + {:error, [:unmatching_signatures]} end end end - defp generate_signature(secret, basestring) do - :sha + defp generate_signature(secret, signature_method, basestring) do + signature_method + |> get_signature_method() |> LTI.hmac_fun( percent_encode(secret) <> "&", basestring @@ -52,6 +59,9 @@ defmodule LTIResult do |> Base.encode64() end + defp get_signature_method("HMAC-SHA256"), do: :sha256 + defp get_signature_method(_), do: :sha + defp extract_header_elements(header) do header |> String.trim_leading("OAuth ") diff --git a/test/lti_result_test.exs b/test/lti_result_test.exs index d3661b8..65282bd 100644 --- a/test/lti_result_test.exs +++ b/test/lti_result_test.exs @@ -2,186 +2,230 @@ defmodule LTIResultTest do use ExUnit.Case doctest LTIResult, only: [signature: 4] - test "returns {:ok, determined_signature} if the signature is correct" do - return = - LTIResult.signature( - "https://example.com", - "OAuth oauth_consumer_key=\"key1234\",oauth_signature_method=\"HMAC-SHA1\",oauth_timestamp=\"1525076552\",oauth_nonce=\"123\",oauth_version=\"1.0\",oauth_signature=\"iyyQNRQyXTlpLJPJns3ireWjQxo%3D\"", - "random_secret" - ) - - assert return == {:ok, "iyyQNRQyXTlpLJPJns3ireWjQxo="} - end - - test "returns {:ok, determined_signature} regardless of the position of the signature in the oauth header" do - return = - LTIResult.signature( - "https://example.com", - "OAuth oauth_consumer_key=\"key1234\",oauth_signature_method=\"HMAC-SHA1\",oauth_signature=\"iyyQNRQyXTlpLJPJns3ireWjQxo%3D\",oauth_timestamp=\"1525076552\",oauth_nonce=\"123\",oauth_version=\"1.0\"", - "random_secret" - ) - - assert return == {:ok, "iyyQNRQyXTlpLJPJns3ireWjQxo="} - end - - test "returns identical signatures for downcase url and url with capitals" do - return1 = - LTIResult.signature( - "https://example.com", - "OAuth oauth_consumer_key=\"key1234\",oauth_signature_method=\"HMAC-SHA1\",oauth_timestamp=\"1525076552\",oauth_nonce=\"123\",oauth_version=\"1.0\",oauth_signature=\"iyyQNRQyXTlpLJPJns3ireWjQxo%3D\"", - "random_secret" - ) - - return2 = - LTIResult.signature( - "https://ExamPle.com", - "OAuth oauth_consumer_key=\"key1234\",oauth_signature_method=\"HMAC-SHA1\",oauth_timestamp=\"1525076552\",oauth_nonce=\"123\",oauth_version=\"1.0\",oauth_signature=\"iyyQNRQyXTlpLJPJns3ireWjQxo%3D\"", - "random_secret" - ) - - assert return1 == return2 - end - - test "returns {:ok, determined_signature} if a bodyhash is included" do - return = - LTIResult.signature( - "http://474c3d0e.ngrok.io/capp11/api/v1/lti_results", - "OAuth oauth_version=\"1.0\",oauth_nonce=\"tjtwip19l78355dl\",oauth_timestamp=\"1528808890\",oauth_consumer_key=\"Defacto\",oauth_body_hash=\"qvrl3dbLTUqxHeCDqof%2Ffz%2Bygc0%3D\",oauth_signature_method=\"HMAC-SHA1\",oauth_signature=\"WF9NUX6QCgKXNb2nNYEZ4evBmSk%3D\"", - "random_secret" - ) - - assert return == {:ok, "WF9NUX6QCgKXNb2nNYEZ4evBmSk="} - end - - test "returns an error if the signature is incorrect due to difference in key" do - return = - LTIResult.signature( - "https://example.com", - "OAuth oauth_consumer_key=\"key12345\",oauth_signature_method=\"HMAC-SHA1\",oauth_timestamp=\"1525076552\",oauth_nonce=\"123\",oauth_version=\"1.0\",oauth_signature=\"iyyQNRQyXTlpLJPJns3ireWjQxo%3D\"", - "random_secret" - ) - - assert return == {:error, [:unmatching_signatures]} - end - - test "returns an error if the signature is incorrect due to difference in method" do - return = - LTIResult.signature( - "https://example.com", - "OAuth oauth_consumer_key=\"key1234\",oauth_signature_method=\"HMAC-SHA2\",oauth_timestamp=\"1525076552\",oauth_nonce=\"123\",oauth_version=\"1.0\",oauth_signature=\"iyyQNRQyXTlpLJPJns3ireWjQxo%3D\"", - "random_secret" - ) - - assert return == {:error, [:unmatching_signatures]} - end - - test "returns an error if the signature is incorrect due to difference in timestamp" do - return = - LTIResult.signature( - "https://example.com", - "OAuth oauth_consumer_key=\"key1234\",oauth_signature_method=\"HMAC-SHA1\",oauth_timestamp=\"152500000\",oauth_nonce=\"123\",oauth_version=\"1.0\",oauth_signature=\"iyyQNRQyXTlpLJPJns3ireWjQxo%3D\"", - "random_secret" - ) - - assert return == {:error, [:unmatching_signatures]} - end - - test "returns an error if the signature is incorrect due to difference in nonce" do - return = - LTIResult.signature( - "https://example.com", - "OAuth oauth_consumer_key=\"key1234\",oauth_signature_method=\"HMAC-SHA1\",oauth_timestamp=\"1525076552\",oauth_nonce=\"32123\",oauth_version=\"1.0\",oauth_signature=\"iyyQNRQyXTlpLJPJns3ireWjQxo%3D\"", - "random_secret" - ) - - assert return == {:error, [:unmatching_signatures]} - end - - test "returns an error if version is incorrect" do - return = - LTIResult.signature( - "https://example.com", - "OAuth oauth_consumer_key=\"key1234\",oauth_signature_method=\"HMAC-SHA1\",oauth_timestamp=\"1525076552\",oauth_nonce=\"123\",oauth_version=\"2.0\",oauth_signature=\"iyyQNRQyXTlpLJPJns3ireWjQxo%3D\"", - "random_secret" - ) - - assert return == {:error, [:incorrect_version]} - end - - test "returns an error if duplicated parameters are present" do - return = - LTIResult.signature( - "https://example.com", - "OAuth oauth_consumer_key=\"key1234\",oauth_consumer_key=\"key1234\",oauth_signature_method=\"HMAC-SHA1\",oauth_timestamp=\"1525076552\",oauth_nonce=\"123\",oauth_version=\"1.0\",oauth_signature=\"iyyQNRQyXTlpLJPJns3ireWjQxo%3D\"", - "random_secret" - ) - - assert return == {:error, [:duplicated_parameters]} - end - - test "returns an error if the consumer key is missing" do - return = - LTIResult.signature( - "https://example.com", - "OAuth oauth_signature_method=\"HMAC-SHA1\",oauth_timestamp=\"1525076552\",oauth_nonce=\"123\",oauth_version=\"1.0\",oauth_signature=\"iyyQNRQyXTlpLJPJns3ireWjQxo%3D\"", - "random_secret" - ) - - assert return == {:error, [:missing_required_parameters]} - end - - test "returns an error if the signature method is missing" do - return = - LTIResult.signature( - "https://example.com", - "OAuth oauth_consumer_key=\"key1234\",oauth_timestamp=\"1525076552\",oauth_nonce=\"123\",oauth_version=\"1.0\",oauth_signature=\"iyyQNRQyXTlpLJPJns3ireWjQxo%3D\"", - "random_secret" - ) - - assert return == {:error, [:missing_required_parameters]} - end - - test "returns an error if the timestamp is missing" do - return = - LTIResult.signature( - "https://example.com", - "OAuth oauth_consumer_key=\"key1234\",oauth_signature_method=\"HMAC-SHA1\",oauth_nonce=\"123\",oauth_version=\"1.0\",oauth_signature=\"iyyQNRQyXTlpLJPJns3ireWjQxo%3D\"", - "random_secret" - ) - - assert return == {:error, [:missing_required_parameters]} - end - - test "returns an error if oauth version is missing" do - return = - LTIResult.signature( - "https://example.com", - "OAuth oauth_consumer_key=\"key1234\",oauth_signature_method=\"HMAC-SHA1\",oauth_timestamp=\"1525076552\",oauth_nonce=\"123\",oauth_signature=\"iyyQNRQyXTlpLJPJns3ireWjQxo%3D\"", - "random_secret" - ) - - assert return == {:error, [:incorrect_version, :missing_required_parameters]} - end - - test "returns an error if nonce is missing" do - return = - LTIResult.signature( - "https://example.com", - "OAuth oauth_consumer_key=\"key1234\",oauth_signature_method=\"HMAC-SHA1\",oauth_timestamp=\"1525076552\",oauth_version=\"1.0\",oauth_signature=\"iyyQNRQyXTlpLJPJns3ireWjQxo%3D\"", - "random_secret" - ) - - assert return == {:error, [:missing_required_parameters]} - end - - test "returns an error if an unsupported parameter is provided" do - return = - LTIResult.signature( - "https://example.com", - "OAuth unsupported_derpvalue=\"123\",oauth_consumer_key=\"key1234\",oauth_signature_method=\"HMAC-SHA1\",oauth_timestamp=\"1525076552\",oauth_nonce=\"123\",oauth_version=\"1.0\",oauth_signature=\"iyyQNRQyXTlpLJPJns3ireWjQxo%3D\"", - "random_secret" - ) - - assert return == {:error, [:unsupported_parameters]} + describe "signature_method SHMAC-SHA1" do + test "returns {:ok, determined_signature} if the signature is correct" do + return = + LTIResult.signature( + "https://example.com", + "OAuth oauth_consumer_key=\"key1234\",oauth_signature_method=\"HMAC-SHA1\",oauth_timestamp=\"1525076552\",oauth_nonce=\"123\",oauth_version=\"1.0\",oauth_signature=\"iyyQNRQyXTlpLJPJns3ireWjQxo%3D\"", + "random_secret" + ) + + assert return == {:ok, "iyyQNRQyXTlpLJPJns3ireWjQxo="} + end + + test "returns {:ok, determined_signature} regardless of the position of the signature in the oauth header" do + return = + LTIResult.signature( + "https://example.com", + "OAuth oauth_consumer_key=\"key1234\",oauth_signature_method=\"HMAC-SHA1\",oauth_signature=\"iyyQNRQyXTlpLJPJns3ireWjQxo%3D\",oauth_timestamp=\"1525076552\",oauth_nonce=\"123\",oauth_version=\"1.0\"", + "random_secret" + ) + + assert return == {:ok, "iyyQNRQyXTlpLJPJns3ireWjQxo="} + end + + test "returns identical signatures for downcase url and url with capitals" do + return1 = + LTIResult.signature( + "https://example.com", + "OAuth oauth_consumer_key=\"key1234\",oauth_signature_method=\"HMAC-SHA1\",oauth_timestamp=\"1525076552\",oauth_nonce=\"123\",oauth_version=\"1.0\",oauth_signature=\"iyyQNRQyXTlpLJPJns3ireWjQxo%3D\"", + "random_secret" + ) + + return2 = + LTIResult.signature( + "https://ExamPle.com", + "OAuth oauth_consumer_key=\"key1234\",oauth_signature_method=\"HMAC-SHA1\",oauth_timestamp=\"1525076552\",oauth_nonce=\"123\",oauth_version=\"1.0\",oauth_signature=\"iyyQNRQyXTlpLJPJns3ireWjQxo%3D\"", + "random_secret" + ) + + assert return1 == return2 + end + + test "returns {:ok, determined_signature} if a bodyhash is included" do + return = + LTIResult.signature( + "http://474c3d0e.ngrok.io/capp11/api/v1/lti_results", + "OAuth oauth_version=\"1.0\",oauth_nonce=\"tjtwip19l78355dl\",oauth_timestamp=\"1528808890\",oauth_consumer_key=\"Defacto\",oauth_body_hash=\"qvrl3dbLTUqxHeCDqof%2Ffz%2Bygc0%3D\",oauth_signature_method=\"HMAC-SHA1\",oauth_signature=\"WF9NUX6QCgKXNb2nNYEZ4evBmSk%3D\"", + "random_secret" + ) + + assert return == {:ok, "WF9NUX6QCgKXNb2nNYEZ4evBmSk="} + end + + test "returns an error if the signature is incorrect due to difference in key" do + return = + LTIResult.signature( + "https://example.com", + "OAuth oauth_consumer_key=\"key12345\",oauth_signature_method=\"HMAC-SHA1\",oauth_timestamp=\"1525076552\",oauth_nonce=\"123\",oauth_version=\"1.0\",oauth_signature=\"iyyQNRQyXTlpLJPJns3ireWjQxo%3D\"", + "random_secret" + ) + + assert return == {:error, [:unmatching_signatures]} + end + + test "returns an error if the signature is incorrect due to difference in method" do + return = + LTIResult.signature( + "https://example.com", + "OAuth oauth_consumer_key=\"key1234\",oauth_signature_method=\"HMAC-SHA2\",oauth_timestamp=\"1525076552\",oauth_nonce=\"123\",oauth_version=\"1.0\",oauth_signature=\"iyyQNRQyXTlpLJPJns3ireWjQxo%3D\"", + "random_secret" + ) + + assert return == {:error, [:unmatching_signatures]} + end + + test "returns an error if the signature is incorrect due to difference in timestamp" do + return = + LTIResult.signature( + "https://example.com", + "OAuth oauth_consumer_key=\"key1234\",oauth_signature_method=\"HMAC-SHA1\",oauth_timestamp=\"152500000\",oauth_nonce=\"123\",oauth_version=\"1.0\",oauth_signature=\"iyyQNRQyXTlpLJPJns3ireWjQxo%3D\"", + "random_secret" + ) + + assert return == {:error, [:unmatching_signatures]} + end + + test "returns an error if the signature is incorrect due to difference in nonce" do + return = + LTIResult.signature( + "https://example.com", + "OAuth oauth_consumer_key=\"key1234\",oauth_signature_method=\"HMAC-SHA1\",oauth_timestamp=\"1525076552\",oauth_nonce=\"32123\",oauth_version=\"1.0\",oauth_signature=\"iyyQNRQyXTlpLJPJns3ireWjQxo%3D\"", + "random_secret" + ) + + assert return == {:error, [:unmatching_signatures]} + end + + test "returns an error if version is incorrect" do + return = + LTIResult.signature( + "https://example.com", + "OAuth oauth_consumer_key=\"key1234\",oauth_signature_method=\"HMAC-SHA1\",oauth_timestamp=\"1525076552\",oauth_nonce=\"123\",oauth_version=\"2.0\",oauth_signature=\"iyyQNRQyXTlpLJPJns3ireWjQxo%3D\"", + "random_secret" + ) + + assert return == {:error, [:incorrect_version]} + end + + test "returns an error if duplicated parameters are present" do + return = + LTIResult.signature( + "https://example.com", + "OAuth oauth_consumer_key=\"key1234\",oauth_consumer_key=\"key1234\",oauth_signature_method=\"HMAC-SHA1\",oauth_timestamp=\"1525076552\",oauth_nonce=\"123\",oauth_version=\"1.0\",oauth_signature=\"iyyQNRQyXTlpLJPJns3ireWjQxo%3D\"", + "random_secret" + ) + + assert return == {:error, [:duplicated_parameters]} + end + + test "returns an error if the consumer key is missing" do + return = + LTIResult.signature( + "https://example.com", + "OAuth oauth_signature_method=\"HMAC-SHA1\",oauth_timestamp=\"1525076552\",oauth_nonce=\"123\",oauth_version=\"1.0\",oauth_signature=\"iyyQNRQyXTlpLJPJns3ireWjQxo%3D\"", + "random_secret" + ) + + assert return == {:error, [:missing_required_parameters]} + end + + test "returns an error if the signature method is missing" do + return = + LTIResult.signature( + "https://example.com", + "OAuth oauth_consumer_key=\"key1234\",oauth_timestamp=\"1525076552\",oauth_nonce=\"123\",oauth_version=\"1.0\",oauth_signature=\"iyyQNRQyXTlpLJPJns3ireWjQxo%3D\"", + "random_secret" + ) + + assert return == {:error, [:missing_required_parameters]} + end + + test "returns an error if the timestamp is missing" do + return = + LTIResult.signature( + "https://example.com", + "OAuth oauth_consumer_key=\"key1234\",oauth_signature_method=\"HMAC-SHA1\",oauth_nonce=\"123\",oauth_version=\"1.0\",oauth_signature=\"iyyQNRQyXTlpLJPJns3ireWjQxo%3D\"", + "random_secret" + ) + + assert return == {:error, [:missing_required_parameters]} + end + + test "returns an error if oauth version is missing" do + return = + LTIResult.signature( + "https://example.com", + "OAuth oauth_consumer_key=\"key1234\",oauth_signature_method=\"HMAC-SHA1\",oauth_timestamp=\"1525076552\",oauth_nonce=\"123\",oauth_signature=\"iyyQNRQyXTlpLJPJns3ireWjQxo%3D\"", + "random_secret" + ) + + assert return == {:error, [:incorrect_version, :missing_required_parameters]} + end + + test "returns an error if nonce is missing" do + return = + LTIResult.signature( + "https://example.com", + "OAuth oauth_consumer_key=\"key1234\",oauth_signature_method=\"HMAC-SHA1\",oauth_timestamp=\"1525076552\",oauth_version=\"1.0\",oauth_signature=\"iyyQNRQyXTlpLJPJns3ireWjQxo%3D\"", + "random_secret" + ) + + assert return == {:error, [:missing_required_parameters]} + end + + test "returns an error if an unsupported parameter is provided" do + return = + LTIResult.signature( + "https://example.com", + "OAuth unsupported_derpvalue=\"123\",oauth_consumer_key=\"key1234\",oauth_signature_method=\"HMAC-SHA1\",oauth_timestamp=\"1525076552\",oauth_nonce=\"123\",oauth_version=\"1.0\",oauth_signature=\"iyyQNRQyXTlpLJPJns3ireWjQxo%3D\"", + "random_secret" + ) + + assert return == {:error, [:unsupported_parameters]} + end + end + + describe "signature_method SHMAC-SHA256" do + test "returns {:ok, determined_signature} if the signature is correct" do + return = + LTIResult.signature( + "https://example.com", + "OAuth oauth_consumer_key=\"key1234\",oauth_signature_method=\"HMAC-SHA256\",oauth_timestamp=\"1525076552\",oauth_nonce=\"123\",oauth_version=\"1.0\",oauth_signature=\"wLwhR7dk5e4dVsvlhjK+fyWKSGzKw+v+tO96twgaHI8%3D\"", + "random_secret" + ) + + assert return == {:ok, "wLwhR7dk5e4dVsvlhjK+fyWKSGzKw+v+tO96twgaHI8="} + end + + test "returns identical signatures for downcase url and url with capitals" do + return1 = + LTIResult.signature( + "https://example.com", + "OAuth oauth_consumer_key=\"key1234\",oauth_signature_method=\"HMAC-SHA256\",oauth_timestamp=\"1525076552\",oauth_nonce=\"123\",oauth_version=\"1.0\",oauth_signature=\"iyyQNRQyXTlpLJPJns3ireWjQxo%3D\"", + "random_secret" + ) + + return2 = + LTIResult.signature( + "https://ExamPle.com", + "OAuth oauth_consumer_key=\"key1234\",oauth_signature_method=\"HMAC-SHA256\",oauth_timestamp=\"1525076552\",oauth_nonce=\"123\",oauth_version=\"1.0\",oauth_signature=\"iyyQNRQyXTlpLJPJns3ireWjQxo%3D\"", + "random_secret" + ) + + assert return1 == return2 + end + + test "returns {:ok, determined_signature} if a bodyhash is included" do + return = + LTIResult.signature( + "http://474c3d0e.ngrok.io/capp11/api/v1/lti_results", + "OAuth oauth_version=\"1.0\",oauth_nonce=\"tjtwip19l78355dl\",oauth_timestamp=\"1528808890\",oauth_consumer_key=\"Defacto\",oauth_body_hash=\"qvrl3dbLTUqxHeCDqof%2Ffz%2Bygc0%3D\",oauth_signature_method=\"HMAC-SHA256\",oauth_signature=\"aols3rXaIgpdQ9Ux4jQtbSl9E/AX+kvl7xp6BPzzzmk%3D\"", + "random_secret" + ) + + assert return == {:ok, "aols3rXaIgpdQ9Ux4jQtbSl9E/AX+kvl7xp6BPzzzmk="} + end end end