Fix issue of signature mismatch for resource path with UrlSegment

This commit is contained in:
Parvathi Mallampalli 2022-03-30 14:17:01 -07:00
parent 2539b7e83a
commit f1b2bc7b3e
4 changed files with 49 additions and 15 deletions

View File

@ -59,7 +59,7 @@ namespace Amazon.SellingPartnerAPIAA
canonicalizedRequest.AppendFormat("{0}\n", restRequest.Method);
//CanonicalURI
canonicalizedRequest.AppendFormat("{0}\n", AwsSignerHelper.ExtractCanonicalURIParameters(restRequest.Resource));
canonicalizedRequest.AppendFormat("{0}\n", AwsSignerHelper.ExtractCanonicalURIParameters(restRequest));
//CanonicalQueryString
canonicalizedRequest.AppendFormat("{0}\n", AwsSignerHelper.ExtractCanonicalQueryString(restRequest));

View File

@ -38,10 +38,11 @@ namespace Amazon.SellingPartnerAPIAA
/// <summary>
/// Returns URI encoded version of absolute path
/// </summary>
/// <param name="resource">Resource path(absolute path) from the request</param>
/// <param name="request">RestRequest</param>
/// <returns>URI encoded version of absolute path</returns>
public virtual string ExtractCanonicalURIParameters(string resource)
public virtual string ExtractCanonicalURIParameters(IRestRequest request)
{
string resource = request.Resource;
string canonicalUri = string.Empty;
if (string.IsNullOrEmpty(resource))
@ -54,6 +55,17 @@ namespace Amazon.SellingPartnerAPIAA
{
canonicalUri = Slash;
}
IDictionary<string, string> pathParameters = request.Parameters
.Where(parameter => ParameterType.UrlSegment.Equals(parameter.Type))
.ToDictionary(parameter => parameter.Name.Trim().ToString(), parameter => parameter.Value.ToString());
// Replace path parameter with actual value.
// Ex: /products/pricing/v0/items/{Asin}/offers -> /products/pricing/v0/items/AB12CD3E4Z/offers
foreach (string parameter in pathParameters.Keys)
{
resource = resource.Replace("{" + parameter + "}", pathParameters[parameter]);
}
//Split path at / into segments
IEnumerable<string> encodedSegments = resource.Split(new char[] { '/' }, StringSplitOptions.None);
@ -76,12 +88,12 @@ namespace Amazon.SellingPartnerAPIAA
{
IDictionary<string, string> queryParameters = request.Parameters
.Where(parameter => ParameterType.QueryString.Equals(parameter.Type))
.ToDictionary(header => header.Name.Trim().ToString(), header => header.Value.ToString());
.ToDictionary(parameter => parameter.Name.Trim().ToString(), parameter => parameter.Value.ToString());
SortedDictionary<string, string> sortedqueryParameters = new SortedDictionary<string, string>(queryParameters);
SortedDictionary<string, string> sortedQueryParameters = new SortedDictionary<string, string>(queryParameters);
StringBuilder canonicalQueryString = new StringBuilder();
foreach (var key in sortedqueryParameters.Keys)
foreach (var key in sortedQueryParameters.Keys)
{
if (canonicalQueryString.Length > 0)
{
@ -89,7 +101,7 @@ namespace Amazon.SellingPartnerAPIAA
}
canonicalQueryString.AppendFormat("{0}={1}",
Utils.UrlEncode(key),
Utils.UrlEncode(sortedqueryParameters[key]));
Utils.UrlEncode(sortedQueryParameters[key]));
}
return canonicalQueryString.ToString();

View File

@ -43,7 +43,7 @@ namespace Amazon.SellingPartnerAPIAATests
string expectedStringToSign = "testStringToSign";
mockAWSSignerHelper.Setup(signerHelper => signerHelper.InitializeHeaders(request, TestHost))
.Returns(signingDate);
mockAWSSignerHelper.Setup(signerHelper => signerHelper.ExtractCanonicalURIParameters(request.Resource))
mockAWSSignerHelper.Setup(signerHelper => signerHelper.ExtractCanonicalURIParameters(request))
.Returns("testURIParameters");
mockAWSSignerHelper.Setup(signerHelper => signerHelper.ExtractCanonicalQueryString(request))
.Returns("testCanonicalQueryString");
@ -63,7 +63,7 @@ namespace Amazon.SellingPartnerAPIAATests
IRestRequest actualRestRequest = sigV4SignerUnderTest.Sign(request, TestHost);
mockAWSSignerHelper.Verify(signerHelper => signerHelper.InitializeHeaders(request, TestHost));
mockAWSSignerHelper.Verify(signerHelper => signerHelper.ExtractCanonicalURIParameters(request.Resource));
mockAWSSignerHelper.Verify(signerHelper => signerHelper.ExtractCanonicalURIParameters(request));
mockAWSSignerHelper.Verify(signerHelper => signerHelper.ExtractCanonicalQueryString(request));
mockAWSSignerHelper.Verify(signerHelper => signerHelper.ExtractCanonicalHeaders(request));
mockAWSSignerHelper.Verify(signerHelper => signerHelper.ExtractSignedHeaders(request));

View File

@ -34,35 +34,57 @@ namespace Amazon.SellingPartnerAPIAATests
public void TestExtractCanonicalURIParameters()
{
IRestRequest request = new RestRequest(TestResourcePath, Method.GET);
string result = awsSignerHelperUnderTest.ExtractCanonicalURIParameters(request.Resource);
Assert.Equal("/iam/user", result);
string result = awsSignerHelperUnderTest.ExtractCanonicalURIParameters(request);
Assert.Equal(Slash + TestResourcePath, result);
}
[Fact]
public void TestExtractCanonicalURIParameters_UrlSegments()
{
IRestRequest request = new RestRequest("products/pricing/v0/items/{Asin}/offers/{SellerSKU}", Method.GET);
request.AddUrlSegment("Asin", "AB12CD3E4Z");
request.AddUrlSegment("SellerSKU", "1234567890");
string result = awsSignerHelperUnderTest.ExtractCanonicalURIParameters(request);
Assert.Equal("/products/pricing/v0/items/AB12CD3E4Z/offers/1234567890", result);
}
[Fact]
public void TestExtractCanonicalURIParameters_IncorrectUrlSegment()
{
IRestRequest request = new RestRequest("products/pricing/v0/items/{Asin}/offers", Method.GET);
request.AddUrlSegment("asin", "AB12CD3E4Z");
string result = awsSignerHelperUnderTest.ExtractCanonicalURIParameters(request);
Assert.Equal("/products/pricing/v0/items/%257BAsin%257D/offers", result);
}
[Fact]
public void TestExtractCanonicalURIParameters_ResourcePathWithSpace()
{
string result = awsSignerHelperUnderTest.ExtractCanonicalURIParameters("iam/ user");
IRestRequest request = new RestRequest("iam/ user", Method.GET);
string result = awsSignerHelperUnderTest.ExtractCanonicalURIParameters(request);
Assert.Equal("/iam/%2520user", result);
}
[Fact]
public void TestExtractCanonicalURIParameters_EmptyResourcePath()
{
string result = awsSignerHelperUnderTest.ExtractCanonicalURIParameters(string.Empty);
IRestRequest request = new RestRequest(string.Empty, Method.GET);
string result = awsSignerHelperUnderTest.ExtractCanonicalURIParameters(request);
Assert.Equal(Slash, result);
}
[Fact]
public void TestExtractCanonicalURIParameters_NullResourcePath()
{
string result = awsSignerHelperUnderTest.ExtractCanonicalURIParameters(null);
string result = awsSignerHelperUnderTest.ExtractCanonicalURIParameters(new RestRequest());
Assert.Equal(Slash, result);
}
[Fact]
public void TestExtractCanonicalURIParameters_SlashPath()
{
string result = awsSignerHelperUnderTest.ExtractCanonicalURIParameters(Slash);
IRestRequest request = new RestRequest(Slash, Method.GET);
string result = awsSignerHelperUnderTest.ExtractCanonicalURIParameters(request);
Assert.Equal(Slash, result);
}