/*
* Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License").
* You may not use this file except in compliance with the License.
* A copy of the License is located at
*
* http://aws.amazon.com/apache2.0
*
* or in the "license" file accompanying this file. This file is distributed
* on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
* express or implied. See the License for the specific language governing
* permissions and limitations under the License.
*/
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Amazon.Runtime;
using Amazon.Runtime.Internal;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using Moq;
namespace AWSSDK.UnitTests.Runtime
{
///
/// Tests behavior
///
[TestClass]
public class BearerTokenSignerTests : RuntimePipelineTestBase
{
[TestMethod]
[TestCategory("UnitTest")]
[TestCategory("Runtime")]
public void SignThrowsExceptionIfSchemeIsHttp()
{
var signer = new BearerTokenSigner();
var mockRequest = new Mock();
mockRequest
.Setup(x => x.Endpoint)
.Returns(new Uri("http://non-secure-endpoint.com"));
Exception exception = null;
try
{
signer.Sign(
mockRequest.Object,
clientConfig: null,
metrics: null,
credentials: null);
}
catch (Exception e)
{
exception = e;
}
Assert.IsNotNull(exception);
Assert.IsInstanceOfType(exception, typeof(AmazonClientException));
Assert.IsTrue(exception.Message.Contains("Endpoint must not use 'http'"));
}
#if AWS_ASYNC_API
[TestMethod]
[TestCategory("UnitTest")]
[TestCategory("Runtime")]
public async Task SignAsyncThrowsExceptionIfSchemeIsHttp()
{
var signer = new BearerTokenSigner();
var mockRequest = new Mock();
mockRequest
.Setup(x => x.Endpoint)
.Returns(new Uri("http://non-secure-endpoint.com"));
Exception exception = null;
try
{
await signer.SignAsync(
mockRequest.Object,
clientConfig: null,
metrics: null,
credentials: null);
}
catch (Exception e)
{
exception = e;
}
Assert.IsNotNull(exception);
Assert.IsTrue(exception.Message.Contains("Endpoint must not use 'http'"));
}
#endif
[TestMethod]
[TestCategory("UnitTest")]
[TestCategory("Runtime")]
public void MinimalBearerAuthCase()
{
var fakeAuthToken = "mF_9.B5f-4.1JqM";
var mockConfig = new MockClientConfig
{
AWSTokenProvider = new StaticTokenProvider(fakeAuthToken)
};
var pipeline = new RuntimePipeline(new MockHandler());
pipeline.AddHandler(new Signer());
pipeline.AddHandler(new CredentialsRetriever(new AnonymousAWSCredentials()));
var context = CreateTestContext(new BearerTokenSigner(), null, mockConfig);
pipeline.InvokeSync(context);
AssertAuthorizationHeaderIs(context, fakeAuthToken);
}
#if AWS_ASYNC_API
[TestMethod]
[TestCategory("UnitTest")]
[TestCategory("Runtime")]
public async Task MinimalBearerAuthCaseAsync()
{
var fakeAuthToken = "mF_9.B5f-4.1JqM";
var mockConfig = new MockClientConfig
{
AWSTokenProvider = new StaticTokenProvider(fakeAuthToken)
};
var pipeline = new RuntimePipeline(new MockHandler());
pipeline.AddHandler(new Signer());
pipeline.AddHandler(new CredentialsRetriever(new AnonymousAWSCredentials()));
var context = CreateTestContext(new BearerTokenSigner(), null, mockConfig);
await pipeline.InvokeAsync(context);
AssertAuthorizationHeaderIs(context, fakeAuthToken);
}
#endif
[TestMethod]
[TestCategory("UnitTest")]
[TestCategory("Runtime")]
public void LongerTokenCase()
{
var fakeAuthToken = "eW91J3JlIG5vdCBzdXBwb3NlZCB0byBkZWNvZGUgdGhpcyE";
var mockConfig = new MockClientConfig
{
AWSTokenProvider = new StaticTokenProvider(fakeAuthToken)
};
var pipeline = new RuntimePipeline(new MockHandler());
pipeline.AddHandler(new Signer());
pipeline.AddHandler(new CredentialsRetriever(new AnonymousAWSCredentials()));
var context = CreateTestContext(new BearerTokenSigner(), null, mockConfig);
pipeline.InvokeSync(context);
AssertAuthorizationHeaderIs(context, fakeAuthToken);
}
#if AWS_ASYNC_API
[TestMethod]
[TestCategory("UnitTest")]
[TestCategory("Runtime")]
public async Task LongerTokenCaseAsync()
{
var fakeAuthToken = "eW91J3JlIG5vdCBzdXBwb3NlZCB0byBkZWNvZGUgdGhpcyE";
var mockConfig = new MockClientConfig
{
AWSTokenProvider = new StaticTokenProvider(fakeAuthToken)
};
var pipeline = new RuntimePipeline(new MockHandler());
pipeline.AddHandler(new Signer());
pipeline.AddHandler(new CredentialsRetriever(new AnonymousAWSCredentials()));
var context = CreateTestContext(new BearerTokenSigner(), null, mockConfig);
await pipeline.InvokeAsync(context);
AssertAuthorizationHeaderIs(context, fakeAuthToken);
}
#endif
[TestMethod]
[TestCategory("UnitTest")]
[TestCategory("Runtime")]
public void SingerShouldOverrideExistingHeader()
{
var fakeAuthToken = "mF_9.B5f-4.1JqM";
var mockConfig = new MockClientConfig
{
AWSTokenProvider = new StaticTokenProvider(fakeAuthToken)
};
var pipeline = new RuntimePipeline(new MockHandler());
pipeline.AddHandler(new Signer());
pipeline.AddHandler(new CredentialsRetriever(new AnonymousAWSCredentials()));
var context = CreateTestContext(new BearerTokenSigner(), null, mockConfig);
context.RequestContext.Request.Headers.Add("Authorization", "Bearer foo");
AssertAuthorizationHeaderIs(context, "foo");
pipeline.InvokeSync(context);
AssertAuthorizationHeaderIs(context, fakeAuthToken);
}
#if AWS_ASYNC_API
[TestMethod]
[TestCategory("UnitTest")]
[TestCategory("Runtime")]
public async Task SingerShouldOverrideExistingHeaderAsync()
{
var fakeAuthToken = "mF_9.B5f-4.1JqM";
var mockConfig = new MockClientConfig
{
AWSTokenProvider = new StaticTokenProvider(fakeAuthToken)
};
var pipeline = new RuntimePipeline(new MockHandler());
pipeline.AddHandler(new Signer());
pipeline.AddHandler(new CredentialsRetriever(new AnonymousAWSCredentials()));
var context = CreateTestContext(new BearerTokenSigner(), null, mockConfig);
context.RequestContext.Request.Headers.Add("Authorization", "Bearer foo");
AssertAuthorizationHeaderIs(context, "foo");
await pipeline.InvokeAsync(context);
AssertAuthorizationHeaderIs(context, fakeAuthToken);
}
#endif
[TestMethod]
[TestCategory("UnitTest")]
[TestCategory("Runtime")]
public void SingerRequiresAToken()
{
var mockConfig = new MockClientConfig
{
AWSTokenProvider = new AWSTokenProviderChain() // chain is empty
};
var pipeline = new RuntimePipeline(new MockHandler());
pipeline.AddHandler(new Signer());
pipeline.AddHandler(new CredentialsRetriever(new AnonymousAWSCredentials()));
var context = CreateTestContext(new BearerTokenSigner(), null, mockConfig);
Exception exception = null;
try
{
pipeline.InvokeSync(context);
}
catch (Exception e)
{
exception = e;
}
Assert.IsNotNull(exception);
Assert.IsInstanceOfType(exception, typeof(AmazonClientException));
Assert.AreEqual(exception.Message, "No Token found. Operation requires a Bearer token.");
}
#if AWS_ASYNC_API
[TestMethod]
[TestCategory("UnitTest")]
[TestCategory("Runtime")]
public async Task SingerRequiresATokenAsync()
{
var mockConfig = new MockClientConfig
{
AWSTokenProvider = new AWSTokenProviderChain() // chain is empty
};
var pipeline = new RuntimePipeline(new MockHandler());
pipeline.AddHandler(new Signer());
pipeline.AddHandler(new CredentialsRetriever(new AnonymousAWSCredentials()));
var context = CreateTestContext(new BearerTokenSigner(), null, mockConfig);
Exception exception = null;
try
{
await pipeline.InvokeAsync(context);
}
catch (Exception e)
{
exception = e;
}
Assert.IsNotNull(exception);
Assert.IsInstanceOfType(exception, typeof(AmazonClientException));
Assert.AreEqual(exception.Message, "No Token found. Operation requires a Bearer token.");
}
#endif
private void AssertAuthorizationHeaderIs(IExecutionContext context, string expected)
{
if (!context.RequestContext.Request.Headers.TryGetValue("Authorization", out var authHeader))
Assert.Fail("No Authorization header found");
expected = expected.Replace("Bearer ", "");
Assert.AreEqual($"Bearer {expected}", authHeader);
}
}
}