Skip to content

Commit 97f9c2b

Browse files
committed
Fixed issue #1
1 parent a570ef1 commit 97f9c2b

File tree

2 files changed

+93
-15
lines changed
  • Mastercard.Developer.OAuth1Signer.Core
  • Mastercard.Developer.OAuth1Signer.Tests/NetCore

2 files changed

+93
-15
lines changed

Mastercard.Developer.OAuth1Signer.Core/OAuth.cs

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -71,8 +71,11 @@ internal static Dictionary<string, List<string>> ExtractQueryParams(string uri)
7171
return queryParamCollection;
7272
}
7373

74-
var queryParameterString = uri.Substring(beginIndex);
75-
var queryParams = queryParameterString.Split('&', '?');
74+
var rawQueryString = uri.Substring(beginIndex);
75+
var decodedQueryString = Uri.UnescapeDataString(rawQueryString);
76+
bool mustEncode = !decodedQueryString.Equals(rawQueryString);
77+
78+
var queryParams = rawQueryString.Split('&', '?');
7679
foreach (var queryParam in queryParams)
7780
{
7881
if (string.IsNullOrEmpty(queryParam))
@@ -83,8 +86,8 @@ internal static Dictionary<string, List<string>> ExtractQueryParams(string uri)
8386
var separatorIndex = queryParam.IndexOf('=');
8487
var key = separatorIndex < 0 ? queryParam : Uri.UnescapeDataString(queryParam.Substring(0, separatorIndex));
8588
var value = separatorIndex < 0 ? string.Empty : Uri.UnescapeDataString(queryParam.Substring(separatorIndex + 1));
86-
var encodedKey = ToUriRfc3986(key);
87-
var encodedValue = ToUriRfc3986(value);
89+
var encodedKey = mustEncode ? ToUriRfc3986(key) : key;
90+
var encodedValue = mustEncode ? ToUriRfc3986(value) : value;
8891

8992
if (!queryParamCollection.ContainsKey(encodedKey))
9093
{

Mastercard.Developer.OAuth1Signer.Tests/NetCore/OAuthTest.cs

Lines changed: 86 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -10,27 +10,102 @@ namespace Mastercard.Developer.OAuth1Signer.Tests.NetCore
1010
[TestClass]
1111
public class OAuthTest
1212
{
13-
[TestMethod]
14-
public void TestExtractQueryParams_ShouldExtractEncodedParams()
15-
{
16-
var queryParams = OAuth.ExtractQueryParams("https://sandbox.api.mastercard.com?param1=plus+value&param2=colon:value&param3=a space~");
17-
Assert.AreEqual(3, queryParams.Count);
18-
Assert.IsFalse(new List<string> { "plus%2Bvalue" }.Except(queryParams["param1"]).Any());
19-
Assert.IsFalse(new List<string> { "colon%3Avalue" }.Except(queryParams["param2"]).Any());
20-
Assert.IsFalse(new List<string> { "a%20space~" }.Except(queryParams["param3"]).Any());
21-
}
22-
2313
[TestMethod]
2414
public void TestExtractQueryParams_ShouldSupportDuplicateKeysAndEmptyValues()
2515
{
26-
var queryParams = OAuth.ExtractQueryParams("https://sandbox.api.mastercard.com/audiences/v1/getcountries?offset=0&offset=1&length=10&empty&odd=");
16+
// GIVEN
17+
const string uri = "https://sandbox.api.mastercard.com/audiences/v1/getcountries?offset=0&offset=1&length=10&empty&odd=";
18+
19+
// WHEN
20+
var queryParams = OAuth.ExtractQueryParams(uri);
21+
22+
// THEN
2723
Assert.AreEqual(4, queryParams.Count);
2824
Assert.IsFalse(new List<string> { "10" }.Except(queryParams["length"]).Any());
2925
Assert.IsFalse(new List<string> { "0", "1" }.Except(queryParams["offset"]).Any());
3026
Assert.IsFalse(new List<string> { string.Empty }.Except(queryParams["empty"]).Any());
3127
Assert.IsFalse(new List<string> { string.Empty }.Except(queryParams["odd"]).Any());
3228
}
3329

30+
[TestMethod]
31+
public void TestExtractQueryParams_ShouldSupportRfcExample()
32+
{
33+
// GIVEN
34+
const string uri = "https://example.com/request?b5=%3D%253D&a3=a&c%40=&a2=r%20b"; // See: https://tools.ietf.org/html/rfc5849#section-3.4.1.3.1
35+
36+
// WHEN
37+
var queryParams = OAuth.ExtractQueryParams(uri);
38+
39+
// THEN
40+
Assert.AreEqual(4, queryParams.Count);
41+
Assert.IsFalse(new List<string> { "%3D%253D" }.Except(queryParams["b5"]).Any());
42+
Assert.IsFalse(new List<string> { "a" }.Except(queryParams["a3"]).Any());
43+
Assert.IsFalse(new List<string> { string.Empty }.Except(queryParams["c%40"]).Any());
44+
Assert.IsFalse(new List<string> { "r%20b" }.Except(queryParams["a2"]).Any());
45+
}
46+
47+
[TestMethod]
48+
public void TestExtractQueryParams_ShouldNotEncodeParams_WhenUriStringWithDecodedParams()
49+
{
50+
// GIVEN
51+
const string uri = "https://example.com/request?colon=:&plus=+&comma=,";
52+
53+
// WHEN
54+
var queryParams = OAuth.ExtractQueryParams(uri);
55+
56+
// THEN
57+
Assert.AreEqual(3, queryParams.Count);
58+
Assert.IsFalse(new List<string> { ":" }.Except(queryParams["colon"]).Any());
59+
Assert.IsFalse(new List<string> { "+" }.Except(queryParams["plus"]).Any());
60+
Assert.IsFalse(new List<string> { "," }.Except(queryParams["comma"]).Any());
61+
}
62+
63+
[TestMethod]
64+
public void TestExtractQueryParams_ShouldEncodeParams_WhenUriStringWithEncodedParams()
65+
{
66+
// GIVEN
67+
const string uri = "https://example.com/request?colon=%3A&plus=%2B&comma=%2C";
68+
69+
// WHEN
70+
var queryParams = OAuth.ExtractQueryParams(uri);
71+
72+
// THEN
73+
Assert.AreEqual(3, queryParams.Count);
74+
Assert.IsFalse(new List<string> { "%3A" }.Except(queryParams["colon"]).Any());
75+
Assert.IsFalse(new List<string> { "%2B" }.Except(queryParams["plus"]).Any());
76+
Assert.IsFalse(new List<string> { "%2C" }.Except(queryParams["comma"]).Any());
77+
}
78+
79+
[TestMethod]
80+
public void TestParameterEncoding_ShouldCreateExpectedSignatureBaseString_WhenQueryParamsEncodedInUri()
81+
{
82+
// GIVEN
83+
const string uri = "https://example.com/?param=token1%3Atoken2";
84+
85+
// WHEN
86+
var queryParams = OAuth.ExtractQueryParams(uri);
87+
var paramString = OAuth.GetOAuthParamString(queryParams, new Dictionary<string, string>());
88+
var baseString = OAuth.GetSignatureBaseString("https://example.com", "GET", paramString);
89+
90+
// THEN
91+
Assert.AreEqual("GET&https%3A%2F%2Fexample.com&param%3Dtoken1%253Atoken2", baseString);
92+
}
93+
94+
[TestMethod]
95+
public void TestParameterEncoding_ShouldCreateExpectedSignatureBaseString_WhenQueryParamsNotEncodedInUri()
96+
{
97+
// GIVEN
98+
const string uri = "https://example.com/?param=token1:token2";
99+
100+
// WHEN
101+
var queryParams = OAuth.ExtractQueryParams(uri);
102+
var paramString = OAuth.GetOAuthParamString(queryParams, new Dictionary<string, string>());
103+
var baseString = OAuth.GetSignatureBaseString("https://example.com", "GET", paramString);
104+
105+
// THEN
106+
Assert.AreEqual("GET&https%3A%2F%2Fexample.com&param%3Dtoken1%3Atoken2", baseString);
107+
}
108+
34109
[TestMethod]
35110
public void TestGetBodyHash()
36111
{

0 commit comments

Comments
 (0)