270 lines
10 KiB
C#
270 lines
10 KiB
C#
|
using System;
|
|||
|
using Xunit;
|
|||
|
using RestSharp;
|
|||
|
using Amazon.SellingPartnerAPIAA;
|
|||
|
using System.Text;
|
|||
|
using Moq;
|
|||
|
|
|||
|
namespace Amazon.SellingPartnerAPIAATests
|
|||
|
{
|
|||
|
public class AWSSignerHelperTest
|
|||
|
{
|
|||
|
private const string Slash = "/";
|
|||
|
private const string ISOSigningDateTime = "20200504T121212Z";
|
|||
|
private const string ISOSigningDate = "20200504";
|
|||
|
private const string TestAccessKeyId = "aKey";
|
|||
|
private const string TestSecretKey = "sKey";
|
|||
|
private const string TestRegion = "us-east-1";
|
|||
|
private const string TestResourcePath = "iam/user";
|
|||
|
private const string TestHost = "sellingpartnerapi.amazon.com";
|
|||
|
private const string JsonMediaType = "application/json; charset=utf-8";
|
|||
|
|
|||
|
private static readonly DateTime SigningDate = DateTime.Parse("2020-05-04 12:12:12");
|
|||
|
|
|||
|
private AWSSignerHelper awsSignerHelperUnderTest;
|
|||
|
|
|||
|
public AWSSignerHelperTest()
|
|||
|
{
|
|||
|
var mockDateHelper = new Mock<IDateHelper>();
|
|||
|
mockDateHelper.Setup(dateHelper => dateHelper.GetUtcNow()).Returns(SigningDate);
|
|||
|
awsSignerHelperUnderTest = new AWSSignerHelper() { DateHelper = mockDateHelper.Object };
|
|||
|
}
|
|||
|
|
|||
|
[Fact]
|
|||
|
public void TestExtractCanonicalURIParameters()
|
|||
|
{
|
|||
|
IRestRequest request = new RestRequest(TestResourcePath, Method.GET);
|
|||
|
string result = awsSignerHelperUnderTest.ExtractCanonicalURIParameters(request.Resource);
|
|||
|
Assert.Equal("/iam/user", result);
|
|||
|
}
|
|||
|
|
|||
|
[Fact]
|
|||
|
public void TestExtractCanonicalURIParameters_ResourcePathWithSpace()
|
|||
|
{
|
|||
|
string result = awsSignerHelperUnderTest.ExtractCanonicalURIParameters("iam/ user");
|
|||
|
Assert.Equal("/iam/%2520user", result);
|
|||
|
}
|
|||
|
|
|||
|
[Fact]
|
|||
|
public void TestExtractCanonicalURIParameters_EmptyResourcePath()
|
|||
|
{
|
|||
|
string result = awsSignerHelperUnderTest.ExtractCanonicalURIParameters(string.Empty);
|
|||
|
Assert.Equal(Slash, result);
|
|||
|
}
|
|||
|
|
|||
|
[Fact]
|
|||
|
public void TestExtractCanonicalURIParameters_NullResourcePath()
|
|||
|
{
|
|||
|
string result = awsSignerHelperUnderTest.ExtractCanonicalURIParameters(null);
|
|||
|
Assert.Equal(Slash, result);
|
|||
|
}
|
|||
|
|
|||
|
[Fact]
|
|||
|
public void TestExtractCanonicalURIParameters_SlashPath()
|
|||
|
{
|
|||
|
string result = awsSignerHelperUnderTest.ExtractCanonicalURIParameters(Slash);
|
|||
|
Assert.Equal(Slash, result);
|
|||
|
}
|
|||
|
|
|||
|
[Fact]
|
|||
|
public void TestExtractCanonicalQueryString()
|
|||
|
{
|
|||
|
IRestRequest request = new RestRequest();
|
|||
|
request.AddQueryParameter("Version", "2010-05-08");
|
|||
|
request.AddQueryParameter("Action", "ListUsers");
|
|||
|
request.AddQueryParameter("RequestId", "1");
|
|||
|
|
|||
|
string result = awsSignerHelperUnderTest.ExtractCanonicalQueryString(request);
|
|||
|
//Query parameters in canonical order
|
|||
|
Assert.Equal("Action=ListUsers&RequestId=1&Version=2010-05-08", result);
|
|||
|
}
|
|||
|
|
|||
|
[Fact]
|
|||
|
public void TestExtractCanonicalQueryString_EmptyQueryParameters()
|
|||
|
{
|
|||
|
string result = awsSignerHelperUnderTest.ExtractCanonicalQueryString(new RestRequest());
|
|||
|
Assert.Empty(result);
|
|||
|
}
|
|||
|
|
|||
|
[Fact]
|
|||
|
public void TestExtractCanonicalQueryString_WithUrlEncoding()
|
|||
|
{
|
|||
|
IRestRequest request = new RestRequest();
|
|||
|
request.AddQueryParameter("Action^", "ListUsers$Roles");
|
|||
|
string result = awsSignerHelperUnderTest.ExtractCanonicalQueryString(request);
|
|||
|
Assert.Equal("Action%5E=ListUsers%24Roles", result);
|
|||
|
}
|
|||
|
|
|||
|
[Fact]
|
|||
|
public void TestExtractCanonicalHeaders()
|
|||
|
{
|
|||
|
IRestRequest request = new RestRequest();
|
|||
|
request.AddHeader("X-Amz-Date", "20150830T123600Z");
|
|||
|
request.AddHeader("Host", "iam.amazonaws.com");
|
|||
|
request.AddHeader("Content-Type", JsonMediaType);
|
|||
|
|
|||
|
string result = awsSignerHelperUnderTest.ExtractCanonicalHeaders(request);
|
|||
|
Assert.Equal("content-type:application/json; charset=utf-8\nhost:iam.amazonaws.com\n" +
|
|||
|
"x-amz-date:20150830T123600Z\n", result);
|
|||
|
}
|
|||
|
|
|||
|
[Fact]
|
|||
|
public void TestExtractCanonicalHeaders_NoHeader()
|
|||
|
{
|
|||
|
string result = awsSignerHelperUnderTest.ExtractCanonicalHeaders(new RestRequest());
|
|||
|
Assert.Empty(result);
|
|||
|
}
|
|||
|
|
|||
|
[Fact]
|
|||
|
public void TestExtractSignedHeaders()
|
|||
|
{
|
|||
|
IRestRequest request = new RestRequest();
|
|||
|
request.AddHeader("X-Amz-Date", "20150830T123600Z");
|
|||
|
request.AddHeader("Host", "iam.amazonaws.com");
|
|||
|
request.AddHeader("Content-Type", JsonMediaType);
|
|||
|
|
|||
|
string result = awsSignerHelperUnderTest.ExtractSignedHeaders(request);
|
|||
|
Assert.Equal("content-type;host;x-amz-date", result);
|
|||
|
}
|
|||
|
|
|||
|
[Fact]
|
|||
|
public void TestExtractSignedHeaders_NoHeader()
|
|||
|
{
|
|||
|
string result = awsSignerHelperUnderTest.ExtractSignedHeaders(new RestRequest());
|
|||
|
Assert.Empty(result);
|
|||
|
}
|
|||
|
|
|||
|
[Fact]
|
|||
|
public void TestHashRequestBody()
|
|||
|
{
|
|||
|
IRestRequest request = new RestRequest(TestResourcePath, Method.POST);
|
|||
|
request.AddJsonBody("{\"test\":\"payload\"}");
|
|||
|
|
|||
|
string result = awsSignerHelperUnderTest.HashRequestBody(request);
|
|||
|
Assert.NotEmpty(result);
|
|||
|
}
|
|||
|
|
|||
|
[Fact]
|
|||
|
public void TestHashRequestBody_NoBody()
|
|||
|
{
|
|||
|
string result = awsSignerHelperUnderTest.HashRequestBody(new RestRequest());
|
|||
|
Assert.NotEmpty(result);
|
|||
|
}
|
|||
|
|
|||
|
[Fact]
|
|||
|
public void TestBuildStringToSign()
|
|||
|
{
|
|||
|
string expectedCanonicalHash = "foo";
|
|||
|
StringBuilder expectedStringBuilder = new StringBuilder();
|
|||
|
expectedStringBuilder.AppendLine("AWS4-HMAC-SHA256");
|
|||
|
expectedStringBuilder.AppendLine(ISOSigningDateTime);
|
|||
|
expectedStringBuilder.AppendFormat("{0}/{1}/execute-api/aws4_request\n", ISOSigningDate, TestRegion);
|
|||
|
expectedStringBuilder.Append(expectedCanonicalHash);
|
|||
|
|
|||
|
string result = awsSignerHelperUnderTest.BuildStringToSign(SigningDate, expectedCanonicalHash, TestRegion);
|
|||
|
|
|||
|
Assert.Equal(expectedStringBuilder.ToString(), result);
|
|||
|
}
|
|||
|
|
|||
|
[Fact]
|
|||
|
public void TestInitializeHeadersReturnsUtcNow()
|
|||
|
{
|
|||
|
Assert.Equal(SigningDate, awsSignerHelperUnderTest.InitializeHeaders(new RestRequest(), TestHost));
|
|||
|
}
|
|||
|
|
|||
|
[Fact]
|
|||
|
public void TestInitializeHeadersSetsUtcNowXAmzDateHeader()
|
|||
|
{
|
|||
|
IRestRequest request = new RestRequest();
|
|||
|
awsSignerHelperUnderTest.InitializeHeaders(request, TestHost);
|
|||
|
|
|||
|
Parameter actualParameter = request.Parameters.Find(parameter =>
|
|||
|
ParameterType.HttpHeader.Equals(parameter.Type) && parameter.Name == AWSSignerHelper.XAmzDateHeaderName);
|
|||
|
|
|||
|
Assert.Equal(ISOSigningDateTime, actualParameter.Value);
|
|||
|
}
|
|||
|
|
|||
|
[Fact]
|
|||
|
public void TestInitializeHeadersOverwritesXAmzDateHeader()
|
|||
|
{
|
|||
|
IRestRequest request = new RestRequest();
|
|||
|
request.AddHeader(AWSSignerHelper.XAmzDateHeaderName, "foobar");
|
|||
|
|
|||
|
awsSignerHelperUnderTest.InitializeHeaders(request, TestHost);
|
|||
|
|
|||
|
Parameter actualParameter = request.Parameters.Find(parameter =>
|
|||
|
ParameterType.HttpHeader.Equals(parameter.Type) && parameter.Name == AWSSignerHelper.XAmzDateHeaderName);
|
|||
|
|
|||
|
Assert.Equal(ISOSigningDateTime, actualParameter.Value);
|
|||
|
}
|
|||
|
|
|||
|
[Fact]
|
|||
|
public void TestAddSignatureToRequest()
|
|||
|
{
|
|||
|
IRestRequest restRequest = new RestRequest();
|
|||
|
string expectedAccessKeyId = TestAccessKeyId;
|
|||
|
string expectedRegion = TestRegion;
|
|||
|
string expectedSignature = "testCalculatedSignature";
|
|||
|
string expectedSignedHeaders = "header1;header2";
|
|||
|
|
|||
|
string expectedAuthorizationHeaderValue = string.Format("AWS4-HMAC-SHA256 " +
|
|||
|
"Credential={0}/{1}/{2}/execute-api/aws4_request, SignedHeaders={3}, Signature={4}",
|
|||
|
expectedAccessKeyId,
|
|||
|
ISOSigningDate,
|
|||
|
expectedRegion,
|
|||
|
expectedSignedHeaders,
|
|||
|
expectedSignature);
|
|||
|
|
|||
|
awsSignerHelperUnderTest.AddSignature(restRequest,
|
|||
|
expectedAccessKeyId,
|
|||
|
expectedSignedHeaders,
|
|||
|
expectedSignature,
|
|||
|
expectedRegion,
|
|||
|
SigningDate);
|
|||
|
|
|||
|
Parameter actualParameter = restRequest.Parameters.Find(parameter =>
|
|||
|
ParameterType.HttpHeader.Equals(parameter.Type) && parameter.Name == AWSSignerHelper.AuthorizationHeaderName);
|
|||
|
|
|||
|
Assert.Equal(expectedAuthorizationHeaderValue, actualParameter.Value);
|
|||
|
}
|
|||
|
|
|||
|
[Fact]
|
|||
|
public void TestCalculateSignature()
|
|||
|
{
|
|||
|
string signature = awsSignerHelperUnderTest.CalculateSignature("testString",
|
|||
|
SigningDate,
|
|||
|
TestSecretKey,
|
|||
|
TestRegion);
|
|||
|
Assert.Equal("7e2c7c2e330123ef7468b41d8ddaf3841e6ef56959b9116b44ded5466cf96405", signature);
|
|||
|
}
|
|||
|
|
|||
|
[Fact]
|
|||
|
public void TestInitializeHeadersSetsHostHeader()
|
|||
|
{
|
|||
|
IRestRequest restRequest = new RestRequest();
|
|||
|
|
|||
|
awsSignerHelperUnderTest.InitializeHeaders(restRequest, TestHost);
|
|||
|
|
|||
|
Parameter actualParamter = restRequest.Parameters.Find(parameter =>
|
|||
|
ParameterType.HttpHeader.Equals(parameter.Type) && parameter.Name == AWSSignerHelper.HostHeaderName);
|
|||
|
|
|||
|
Assert.Equal(TestHost, actualParamter.Value);
|
|||
|
}
|
|||
|
|
|||
|
[Fact]
|
|||
|
public void TestInitializeHeadersOverwritesHostHeader()
|
|||
|
{
|
|||
|
IRestRequest restRequest = new RestRequest();
|
|||
|
|
|||
|
restRequest.AddHeader(AWSSignerHelper.HostHeaderName, "foobar");
|
|||
|
|
|||
|
awsSignerHelperUnderTest.InitializeHeaders(restRequest, TestHost);
|
|||
|
|
|||
|
Parameter actualParamter = restRequest.Parameters.Find(parameter =>
|
|||
|
ParameterType.HttpHeader.Equals(parameter.Type) && parameter.Name == AWSSignerHelper.HostHeaderName);
|
|||
|
|
|||
|
Assert.Equal(TestHost, actualParamter.Value);
|
|||
|
}
|
|||
|
}
|
|||
|
}
|