diff --git a/CHANGELOG.md b/CHANGELOG.md index 6a317e8..5f2f621 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,8 @@ # Changes in Medidata.MAuth +## v3.0.4 +- **[Core]** Fixed an issue with HTTP requests having binary content (the authentication was failing in this case) + ## v3.0.3 - **[Core]** Fixed concurrency and memory issues with the `MAuthRequestRetrier` diff --git a/src/Medidata.MAuth.Core/Constants.cs b/src/Medidata.MAuth.Core/Constants.cs index 7e10930..4aad4ca 100644 --- a/src/Medidata.MAuth.Core/Constants.cs +++ b/src/Medidata.MAuth.Core/Constants.cs @@ -1,4 +1,5 @@ using System; +using System.Text; using System.Text.RegularExpressions; namespace Medidata.MAuth.Core @@ -27,5 +28,7 @@ internal static class Constants public static readonly string KeyNormalizeLinesStartRegexPattern = "^(?-----BEGIN [A-Z ]+[-]+)"; public static readonly string KeyNormalizeLinesEndRegexPattern = "(?-----END [A-Z ]+[-]+)$"; + + public static readonly byte[] NewLine = Encoding.UTF8.GetBytes("\n"); } } diff --git a/src/Medidata.MAuth.Core/MAuthAuthenticator.cs b/src/Medidata.MAuth.Core/MAuthAuthenticator.cs index 527cd0b..c93ecc2 100644 --- a/src/Medidata.MAuth.Core/MAuthAuthenticator.cs +++ b/src/Medidata.MAuth.Core/MAuthAuthenticator.cs @@ -35,7 +35,7 @@ public async Task AuthenticateRequest(HttpRequestMessage request) var authInfo = request.GetAuthenticationInfo(); var appInfo = await GetApplicationInfo(authInfo.ApplicationUuid); - return await authInfo.Payload.Verify(await request.GetSignature(authInfo), appInfo.PublicKey); + return authInfo.Payload.Verify(await request.GetSignature(authInfo), appInfo.PublicKey); } catch (ArgumentException ex) { diff --git a/src/Medidata.MAuth.Core/MAuthCoreExtensions.cs b/src/Medidata.MAuth.Core/MAuthCoreExtensions.cs index 47d434f..86a35fd 100644 --- a/src/Medidata.MAuth.Core/MAuthCoreExtensions.cs +++ b/src/Medidata.MAuth.Core/MAuthCoreExtensions.cs @@ -53,13 +53,13 @@ public static async Task CalculatePayload( /// If the signed data matches the signature, it returns ; otherwise it /// returns . /// - public static Task Verify(this byte[] signedData, byte[] signature, string publicKey) + public static bool Verify(this byte[] signedData, byte[] signature, string publicKey) { Pkcs1Encoding.StrictLengthEnabled = false; var cipher = CipherUtilities.GetCipher("RSA/ECB/PKCS1Padding"); cipher.Init(false, publicKey.AsCipherParameters()); - return Task.Run(() => cipher.DoFinal(signedData).SequenceEqual(signature)); + return cipher.DoFinal(signedData).SequenceEqual(signature); } /// @@ -73,11 +73,16 @@ public static Task Verify(this byte[] signedData, byte[] signature, string /// /// A Task object which will result the SHA512 hash of the signature when it completes. public static async Task GetSignature(this HttpRequestMessage request, AuthenticationInfo authInfo) => - ($"{request.Method.Method}\n" + - $"{request.RequestUri.AbsolutePath}\n" + - $"{(request.Content != null ? await request.Content.ReadAsStringAsync() : string.Empty)}\n" + - $"{authInfo.ApplicationUuid.ToHyphenString()}\n" + - $"{authInfo.SignedTime.ToUnixTimeSeconds()}") + new byte[][] + { + request.Method.Method.ToBytes(), Constants.NewLine, + request.RequestUri.AbsolutePath.ToBytes(), Constants.NewLine, + (request.Content != null ? await request.Content.ReadAsByteArrayAsync() : new byte[] { }), + Constants.NewLine, + authInfo.ApplicationUuid.ToHyphenString().ToBytes(), Constants.NewLine, + authInfo.SignedTime.ToUnixTimeSeconds().ToString().ToBytes() + } + .Concat() .AsSHA512Hash(); /// @@ -192,14 +197,10 @@ public static string ToHyphenString(this Guid uuid) => /// The collection of the HTTP headers to search in. /// The key to search in the headers collection. /// The value if found; otherwise a default value for the given type. - public static TValue GetFirstValueOrDefault(this HttpHeaders headers, string key) - { - IEnumerable values; - - return headers.TryGetValues(key, out values) ? + public static TValue GetFirstValueOrDefault(this HttpHeaders headers, string key) => + headers.TryGetValues(key, out IEnumerable values) ? (TValue)Convert.ChangeType(values.First(), typeof(TValue)) : default(TValue); - } /// /// Provides an SHA512 hash value of a string. @@ -207,8 +208,10 @@ public static TValue GetFirstValueOrDefault(this HttpHeaders headers, st /// The value for calculating the hash. /// The SHA512 hash of the input value as a hex-encoded byte array. public static byte[] AsSHA512Hash(this string value) => - Hex.Encode(SHA512.Create().ComputeHash(Encoding.UTF8.GetBytes(value))); + AsSHA512Hash(Encoding.UTF8.GetBytes(value)); + public static byte[] AsSHA512Hash(this byte[] value) => + Hex.Encode(SHA512.Create().ComputeHash(value)); /// /// Provides a string PEM (ASN.1) format key as an object. @@ -261,5 +264,21 @@ private static string InsertLineBreakAfterBegin(this string key) => private static string InsertLineBreakBeforeEnd(this string key) => Regex.Replace(key, Constants.KeyNormalizeLinesEndRegexPattern, "\n${end}"); + + + private static byte[] ToBytes(this string value) => Encoding.UTF8.GetBytes(value); + + private static byte[] Concat(this byte[][] values) + { + var result = new byte[values.Sum(x => x.Length)]; + var offset = 0; + foreach (var value in values) + { + Buffer.BlockCopy(value, 0, result, offset, value.Length); + offset += value.Length; + } + + return result; + } } } diff --git a/tests/Medidata.MAuth.Tests/Infrastructure/MAuthServerHandler.cs b/tests/Medidata.MAuth.Tests/Infrastructure/MAuthServerHandler.cs index 66bfee6..34e8876 100644 --- a/tests/Medidata.MAuth.Tests/Infrastructure/MAuthServerHandler.cs +++ b/tests/Medidata.MAuth.Tests/Infrastructure/MAuthServerHandler.cs @@ -25,7 +25,7 @@ protected override async Task SendAsync( var authInfo = request.GetAuthenticationInfo(); - if (!await authInfo.Payload.Verify( + if (!authInfo.Payload.Verify( await request.GetSignature(authInfo), TestExtensions.ServerPublicKey )) diff --git a/tests/Medidata.MAuth.Tests/Infrastructure/RequestData.cs b/tests/Medidata.MAuth.Tests/Infrastructure/RequestData.cs new file mode 100644 index 0000000..2f31944 --- /dev/null +++ b/tests/Medidata.MAuth.Tests/Infrastructure/RequestData.cs @@ -0,0 +1,38 @@ +using System; +using System.Net.Http; +using System.Runtime.Serialization; +using Medidata.MAuth.Core; + +namespace Medidata.MAuth.Tests.Infrastructure +{ + [DataContract] + internal class RequestData + { + [DataMember] + public Uri Url { get; set; } + + [DataMember] + public string Method { get; set; } + + [DataMember] + public DateTimeOffset SignedTime { get; set; } + + [DataMember] + public string Base64Content { get; set; } + + [DataMember] + public Guid ApplicationUuid { get; set; } + + [DataMember] + public string Payload { get; set; } + + [IgnoreDataMember] + public long SignedTimeUnixSeconds => SignedTime.ToUnixTimeSeconds(); + + [IgnoreDataMember] + public string MAuthHeader => $"MWS {ApplicationUuidString}:{Payload}"; + + [IgnoreDataMember] + public string ApplicationUuidString => ApplicationUuid.ToHyphenString(); + } +} diff --git a/tests/Medidata.MAuth.Tests/Infrastructure/TestData.cs b/tests/Medidata.MAuth.Tests/Infrastructure/TestData.cs deleted file mode 100644 index 1a19a36..0000000 --- a/tests/Medidata.MAuth.Tests/Infrastructure/TestData.cs +++ /dev/null @@ -1,42 +0,0 @@ -using System; -using System.Net.Http; -using System.Threading.Tasks; -using Medidata.MAuth.Core; - -namespace Medidata.MAuth.Tests.Infrastructure -{ - internal class TestData - { - public HttpMethod Method { get; private set; } - - public string Payload { get; private set; } - - public DateTimeOffset SignedTime { get; private set; } - - public string Content { get; private set; } - - public long SignedTimeUnixSeconds => SignedTime.ToUnixTimeSeconds(); - - public HttpRequestMessage Request => new HttpRequestMessage(Method, "http://localhost:29999/") - { - Content = Content != null ? new StringContent(Content) : null - }; - - public string MAuthHeader => $"MWS {TestExtensions.ClientUuid}:{Payload}"; - - public static async Task For(string method) - { - var lines = - (await TestExtensions.GetStringFromResource($"Medidata.MAuth.Tests.Mocks.Requests.{method}.txt")) - .Split(new[] { Environment.NewLine }, StringSplitOptions.RemoveEmptyEntries); - - return new TestData() - { - Method = new HttpMethod(method), - Payload = lines[0], - SignedTime = DateTimeOffset.Parse(lines[1]), - Content = lines.Length >= 3 ? lines[2] : null - }; - } - } -} diff --git a/tests/Medidata.MAuth.Tests/Infrastructure/TestExtensions.cs b/tests/Medidata.MAuth.Tests/Infrastructure/TestExtensions.cs index e343c29..fccf61a 100644 --- a/tests/Medidata.MAuth.Tests/Infrastructure/TestExtensions.cs +++ b/tests/Medidata.MAuth.Tests/Infrastructure/TestExtensions.cs @@ -1,8 +1,11 @@ using System; using System.IO; +using System.Net.Http; using System.Reflection; +using System.Text; using System.Threading.Tasks; using Medidata.MAuth.Core; +using Newtonsoft.Json; namespace Medidata.MAuth.Tests.Infrastructure { @@ -57,9 +60,34 @@ public static Task GetStringFromResource(string resourceName) } } + public static async Task FromResource(this string requestDataName) => + JsonConvert.DeserializeObject( + await GetStringFromResource($"Medidata.MAuth.Tests.Mocks.RequestData.{requestDataName}.json") + ); + private static Task GetKeyFromResource(string keyName) { return GetStringFromResource($"Medidata.MAuth.Tests.Mocks.Keys.{keyName}.pem"); } + + public static HttpRequestMessage ToHttpRequestMessage(this RequestData data) + { + var result = new HttpRequestMessage(new HttpMethod(data.Method), data.Url) + { + Content = !string.IsNullOrEmpty(data.Base64Content) ? + new ByteArrayContent(Convert.FromBase64String(data.Base64Content)) : + null, + }; + + result.Headers.Add(Constants.MAuthHeaderKey, $"MWS {data.ApplicationUuidString}:{data.Payload}"); + result.Headers.Add(Constants.MAuthTimeHeaderKey, data.SignedTimeUnixSeconds.ToString()); + + return result; + } + + public static string ToStringContent(this string base64Content) => + base64Content == null ? null : Encoding.UTF8.GetString(Convert.FromBase64String(base64Content)); + + public static HttpMethod ToHttpMethod(this string method) => new HttpMethod(method); } } diff --git a/tests/Medidata.MAuth.Tests/MAuthAspNetCoreTests.cs b/tests/Medidata.MAuth.Tests/MAuthAspNetCoreTests.cs index 44d865c..1d1a95c 100644 --- a/tests/Medidata.MAuth.Tests/MAuthAspNetCoreTests.cs +++ b/tests/Medidata.MAuth.Tests/MAuthAspNetCoreTests.cs @@ -1,5 +1,6 @@ using System.IO; using System.Net; +using System.Net.Http; using System.Threading.Tasks; using Medidata.MAuth.AspNetCore; using Medidata.MAuth.Core; @@ -21,7 +22,7 @@ public class MAuthAspNetCoreTests public async Task MAuthMiddleware_WithValidRequest_WillAuthenticate(string method) { // Arrange - var testData = await TestData.For(method); + var testData = await method.FromResource(); using (var server = new TestServer(new WebHostBuilder().Configure(app => { @@ -38,8 +39,7 @@ public async Task MAuthMiddleware_WithValidRequest_WillAuthenticate(string metho }))) { // Act - var response = await server.CreateClient().SendAsync( - await testData.Request.Sign(TestExtensions.ClientOptions(testData.SignedTime))); + var response = await server.CreateClient().SendAsync(testData.ToHttpRequestMessage()); // Assert Assert.Equal(HttpStatusCode.OK, response.StatusCode); @@ -54,7 +54,7 @@ public async Task MAuthMiddleware_WithValidRequest_WillAuthenticate(string metho public async Task MAuthMiddleware_WithoutMAuthHeader_WillNotAuthenticate(string method) { // Arrange - var testData = await TestData.For(method); + var testData = await method.FromResource(); using (var server = new TestServer(new WebHostBuilder().Configure(app => { @@ -70,7 +70,8 @@ public async Task MAuthMiddleware_WithoutMAuthHeader_WillNotAuthenticate(string }))) { // Act - var response = await server.CreateClient().SendAsync(testData.Request); + var response = await server.CreateClient().SendAsync( + new HttpRequestMessage(testData.Method.ToHttpMethod(), testData.Url)); // Assert Assert.Equal(HttpStatusCode.Unauthorized, response.StatusCode); @@ -85,7 +86,7 @@ public async Task MAuthMiddleware_WithoutMAuthHeader_WillNotAuthenticate(string public async Task MAuthMiddleware_WithEnabledExceptions_WillThrowException(string method) { // Arrange - var testData = await TestData.For(method); + var testData = await method.FromResource(); using (var server = new TestServer(new WebHostBuilder().Configure(app => { @@ -101,7 +102,8 @@ public async Task MAuthMiddleware_WithEnabledExceptions_WillThrowException(strin { // Act, Assert var ex = await Assert.ThrowsAsync( - () => server.CreateClient().SendAsync(testData.Request)); + () => server.CreateClient().SendAsync( + new HttpRequestMessage(testData.Method.ToHttpMethod(), testData.Url))); Assert.Equal("The request has invalid MAuth authentication headers.", ex.Message); Assert.NotNull(ex.InnerException); @@ -116,7 +118,7 @@ public async Task MAuthMiddleware_WithEnabledExceptions_WillThrowException(strin public async Task MAuthMiddleware_WithNonSeekableBodyStream_WillRestoreBodyStream(string method) { // Arrange - var testData = await TestData.For(method); + var testData = await method.FromResource(); var canSeek = false; var body = string.Empty; using (var server = new TestServer(new WebHostBuilder().Configure(app => @@ -139,12 +141,11 @@ public async Task MAuthMiddleware_WithNonSeekableBodyStream_WillRestoreBodyStrea }))) { // Act - var response = await server.CreateClient().SendAsync( - await testData.Request.Sign(TestExtensions.ClientOptions(testData.SignedTime))); + var response = await server.CreateClient().SendAsync(testData.ToHttpRequestMessage()); // Assert Assert.True(canSeek); - Assert.Equal(testData.Content ?? string.Empty, body); + Assert.Equal(testData.Base64Content.ToStringContent() ?? string.Empty, body); } } } diff --git a/tests/Medidata.MAuth.Tests/MAuthAuthenticatorTests.cs b/tests/Medidata.MAuth.Tests/MAuthAuthenticatorTests.cs index 2c3a6a3..b64edcf 100644 --- a/tests/Medidata.MAuth.Tests/MAuthAuthenticatorTests.cs +++ b/tests/Medidata.MAuth.Tests/MAuthAuthenticatorTests.cs @@ -8,49 +8,46 @@ namespace Medidata.MAuth.Tests { - public class MAuthAuthenticatorTests + public static class MAuthAuthenticatorTests { [Theory] [InlineData(null, "private key")] [InlineData("http://localhost", null)] - public void MAuthAuthenticator_WithInvalidOptions_WillThrowException(string mauthServiceUrl, string privateKey) - { - // Assert + public static void MAuthAuthenticator_WithInvalidOptions_WillThrowException( + string mauthServiceUrl, string privateKey) => Assert.Throws(() => new MAuthAuthenticator(new MAuthTestOptions() { ApplicationUuid = TestExtensions.ClientUuid, MAuthServiceUrl = mauthServiceUrl != null ? new Uri(mauthServiceUrl) : null, PrivateKey = privateKey })); - } [Fact] - public void MAuthAuthenticator_WithDefaultUuid_WillThrowException() - { + public static void MAuthAuthenticator_WithDefaultUuid_WillThrowException() => Assert.Throws(() => new MAuthAuthenticator(new MAuthTestOptions() - { - ApplicationUuid = default(Guid) - })); - } + { + ApplicationUuid = default(Guid) + })); [Theory] [InlineData("GET")] [InlineData("DELETE")] [InlineData("POST")] [InlineData("PUT")] - public async Task AuthenticateRequest_WithValidRequest_WillAuthenticate(string method) + public static async Task AuthenticateRequest_WithValidRequest_WillAuthenticate(string method) { // Arrange - var testData = await TestData.For(method); + var testData = await method.FromResource(); var authenticator = new MAuthAuthenticator(TestExtensions.ServerOptions); - var signedRequest = await testData.Request.AddAuthenticationInfo(new PrivateKeyAuthenticationInfo() - { - ApplicationUuid = TestExtensions.ClientUuid, - PrivateKey = TestExtensions.ClientPrivateKey, - SignedTime = testData.SignedTime - }); + var signedRequest = await testData.ToHttpRequestMessage() + .AddAuthenticationInfo(new PrivateKeyAuthenticationInfo() + { + ApplicationUuid = testData.ApplicationUuid, + PrivateKey = TestExtensions.ClientPrivateKey, + SignedTime = testData.SignedTime + }); // Act var isAuthenticated = await authenticator.AuthenticateRequest(signedRequest); @@ -65,20 +62,22 @@ public async Task AuthenticateRequest_WithValidRequest_WillAuthenticate(string m [InlineData(MAuthServiceRetryPolicy.RetryOnce)] [InlineData(MAuthServiceRetryPolicy.RetryTwice)] [InlineData(MAuthServiceRetryPolicy.Agressive)] - public async Task AuthenticateRequest_WithNumberOfAttempts_WillAuthenticate(MAuthServiceRetryPolicy policy) + public static async Task AuthenticateRequest_WithNumberOfAttempts_WillAuthenticate( + MAuthServiceRetryPolicy policy) { // Arrange - var testData = await TestData.For("GET"); + var testData = await "GET".FromResource(); var authenticator = new MAuthAuthenticator(TestExtensions.GetServerOptionsWithAttempts( policy, shouldSucceedWithin: true)); - var signedRequest = await testData.Request.AddAuthenticationInfo(new PrivateKeyAuthenticationInfo() - { - ApplicationUuid = TestExtensions.ClientUuid, - PrivateKey = TestExtensions.ClientPrivateKey, - SignedTime = testData.SignedTime - }); + var signedRequest = await testData.ToHttpRequestMessage() + .AddAuthenticationInfo(new PrivateKeyAuthenticationInfo() + { + ApplicationUuid = testData.ApplicationUuid, + PrivateKey = TestExtensions.ClientPrivateKey, + SignedTime = testData.SignedTime + }); // Act var isAuthenticated = await authenticator.AuthenticateRequest(signedRequest); @@ -92,21 +91,22 @@ public async Task AuthenticateRequest_WithNumberOfAttempts_WillAuthenticate(MAut [InlineData(MAuthServiceRetryPolicy.RetryOnce)] [InlineData(MAuthServiceRetryPolicy.RetryTwice)] [InlineData(MAuthServiceRetryPolicy.Agressive)] - public async Task AuthenticateRequest_AfterNumberOfAttempts_WillThrowExceptionWithRequestFailure( + public static async Task AuthenticateRequest_AfterNumberOfAttempts_WillThrowExceptionWithRequestFailure( MAuthServiceRetryPolicy policy) { // Arrange - var testData = await TestData.For("GET"); + var testData = await "GET".FromResource(); var authenticator = new MAuthAuthenticator(TestExtensions.GetServerOptionsWithAttempts( policy, shouldSucceedWithin: false)); - var signedRequest = await testData.Request.AddAuthenticationInfo(new PrivateKeyAuthenticationInfo() - { - ApplicationUuid = TestExtensions.ClientUuid, - PrivateKey = TestExtensions.ClientPrivateKey, - SignedTime = testData.SignedTime - }); + var signedRequest = await testData.ToHttpRequestMessage() + .AddAuthenticationInfo(new PrivateKeyAuthenticationInfo() + { + ApplicationUuid = testData.ApplicationUuid, + PrivateKey = TestExtensions.ClientPrivateKey, + SignedTime = testData.SignedTime + }); // Act var exception = (await Assert.ThrowsAsync( @@ -125,14 +125,14 @@ public async Task AuthenticateRequest_AfterNumberOfAttempts_WillThrowExceptionWi [InlineData("DELETE")] [InlineData("POST")] [InlineData("PUT")] - public async Task SignRequest_WithValidRequest_WillSignProperly(string method) + public static async Task SignRequest_WithValidRequest_WillSignProperly(string method) { // Arrange - var testData = await TestData.For(method); - var expectedMAuthHeader = $"MWS {TestExtensions.ClientUuid.ToHyphenString()}:{testData.Payload}"; + var testData = await method.FromResource(); + var expectedMAuthHeader = testData.MAuthHeader; // Act - var actual = await testData.Request.Sign(TestExtensions.ClientOptions(testData.SignedTime)); + var actual = await testData.ToHttpRequestMessage().Sign(TestExtensions.ClientOptions(testData.SignedTime)); // Assert Assert.Equal(expectedMAuthHeader, actual.Headers.GetFirstValueOrDefault(Constants.MAuthHeaderKey)); diff --git a/tests/Medidata.MAuth.Tests/MAuthCoreExtensionsTests.cs b/tests/Medidata.MAuth.Tests/MAuthCoreExtensionsTests.cs index 85cca9b..15f8fa5 100644 --- a/tests/Medidata.MAuth.Tests/MAuthCoreExtensionsTests.cs +++ b/tests/Medidata.MAuth.Tests/MAuthCoreExtensionsTests.cs @@ -10,34 +10,34 @@ namespace Medidata.MAuth.Tests { - public class MAuthCoreExtensionsTests + public static class MAuthCoreExtensionsTests { [Theory] [InlineData("GET")] [InlineData("DELETE")] [InlineData("POST")] [InlineData("PUT")] - public async Task CalculatePayload_WithRequestAndAuthInfo_WillReturnCorrectPayload(string method) + public static async Task CalculatePayload_WithRequestAndAuthInfo_WillReturnCorrectPayload(string method) { // Arrange - var testData = await TestData.For(method); + var testData = await method.FromResource(); var authInfo = new PrivateKeyAuthenticationInfo() { - ApplicationUuid = TestExtensions.ClientUuid, + ApplicationUuid = testData.ApplicationUuid, SignedTime = testData.SignedTime, PrivateKey = TestExtensions.ClientPrivateKey }; // Act - var result = await testData.Request.CalculatePayload(authInfo); + var result = await testData.ToHttpRequestMessage().CalculatePayload(authInfo); // Assert Assert.Equal(testData.Payload, result); } [Fact] - public async Task Verify_WithCorrectlySignedData_WillVerifyTheDataAsValid() + public static void Verify_WithCorrectlySignedData_WillVerifyTheDataAsValid() { // Arrange var signature = "This is a signature."; @@ -49,7 +49,7 @@ public async Task Verify_WithCorrectlySignedData_WillVerifyTheDataAsValid() var signedData = signer.ProcessBlock(unsignedData, 0, unsignedData.Length); // Act - var result = await signedData.Verify(Encoding.UTF8.GetBytes(signature), TestExtensions.ClientPublicKey); + var result = signedData.Verify(Encoding.UTF8.GetBytes(signature), TestExtensions.ClientPublicKey); // Assert Assert.True(result); @@ -60,49 +60,70 @@ public async Task Verify_WithCorrectlySignedData_WillVerifyTheDataAsValid() [InlineData("DELETE")] [InlineData("POST")] [InlineData("PUT")] - public async Task GetSignature_WithRequest_WillReturnTheCorrectSignature(string method) + public static async Task GetSignature_WithRequest_WillReturnTheCorrectSignature(string method) { // Arrange - var testData = await TestData.For(method); + var testData = await method.FromResource(); var expectedSignature = - ($"{method}\n/\n{testData.Content}\n{TestExtensions.ClientUuid.ToHyphenString()}\n" + - $"{testData.SignedTime.ToUnixTimeSeconds()}") + ($"{testData.Method}\n" + + $"{testData.Url.AbsolutePath}\n" + + $"{testData.Base64Content.ToStringContent()}\n" + + $"{testData.ApplicationUuidString}\n" + + $"{testData.SignedTimeUnixSeconds}") .AsSHA512Hash(); var authInfo = new PrivateKeyAuthenticationInfo() { - ApplicationUuid = TestExtensions.ClientUuid, + ApplicationUuid = testData.ApplicationUuid, SignedTime = testData.SignedTime }; // Act - var result = await testData.Request.GetSignature(authInfo); + var result = await testData.ToHttpRequestMessage().GetSignature(authInfo); // Assert Assert.Equal(expectedSignature, result); } + [Fact] + public static async Task CalculatePayload_WithBinaryContent_WillCalculateTheProperPayload() + { + // Arrange + var testData = await "POSTWithBinaryData".FromResource(); + + // Act + var result = await testData.ToHttpRequestMessage().CalculatePayload(new PrivateKeyAuthenticationInfo() + { + ApplicationUuid = testData.ApplicationUuid, + SignedTime = testData.SignedTime, + PrivateKey = TestExtensions.ClientPrivateKey + }); + + // Assert + Assert.Equal(testData.Payload, result); + } + [Theory] [InlineData("GET")] [InlineData("DELETE")] [InlineData("POST")] [InlineData("PUT")] - public async Task GetAuthenticationInfo_WithSignedRequest_WillReturnCorrectAuthInfo(string method) + public static async Task GetAuthenticationInfo_WithSignedRequest_WillReturnCorrectAuthInfo(string method) { // Arrange - var testData = await TestData.For(method); - var request = new HttpRequestMessage(testData.Method, TestExtensions.TestUri); + var testData = await method.FromResource(); + var request = new HttpRequestMessage(new HttpMethod(testData.Method), TestExtensions.TestUri); request.Headers.Add( - Constants.MAuthHeaderKey, $"MWS {TestExtensions.ClientUuid.ToHyphenString()}:{testData.Payload}"); + Constants.MAuthHeaderKey, testData.MAuthHeader); request.Headers.Add(Constants.MAuthTimeHeaderKey, testData.SignedTimeUnixSeconds.ToString()); // Act var actual = request.GetAuthenticationInfo(); // Assert - Assert.Equal(TestExtensions.ClientUuid, actual.ApplicationUuid); + Assert.Equal(testData.ApplicationUuid, actual.ApplicationUuid); Assert.Equal(Convert.FromBase64String(testData.Payload), actual.Payload); Assert.Equal(testData.SignedTime, actual.SignedTime); } @@ -112,21 +133,21 @@ public async Task GetAuthenticationInfo_WithSignedRequest_WillReturnCorrectAuthI [InlineData("DELETE")] [InlineData("POST")] [InlineData("PUT")] - public async Task AddAuthenticationInfo_WithRequestAndAuthInfo_WillAddCorrectInformation(string method) + public static async Task AddAuthenticationInfo_WithRequestAndAuthInfo_WillAddCorrectInformation(string method) { // Arrange - var testData = await TestData.For(method); - var expectedMAuthHeader = $"MWS {TestExtensions.ClientUuid.ToHyphenString()}:{testData.Payload}"; + var testData = await method.FromResource(); + var expectedMAuthHeader = testData.MAuthHeader; var authInfo = new PrivateKeyAuthenticationInfo() { - ApplicationUuid = TestExtensions.ClientUuid, + ApplicationUuid = testData.ApplicationUuid, SignedTime = testData.SignedTime, PrivateKey = TestExtensions.ClientPrivateKey }; // Act - var actual = await testData.Request.AddAuthenticationInfo(authInfo); + var actual = await testData.ToHttpRequestMessage().AddAuthenticationInfo(authInfo); // Assert Assert.Equal(expectedMAuthHeader, actual.Headers.GetFirstValueOrDefault(Constants.MAuthHeaderKey)); @@ -140,7 +161,7 @@ public async Task AddAuthenticationInfo_WithRequestAndAuthInfo_WillAddCorrectInf [InlineData("LinuxLineEnding.pem")] [InlineData("WindowsLineEnding.pem")] [InlineData("NoLineEnding.pem")] - public void AsCipherParameters_WithDifferentLineEndingKeys_WillReadTheKeysSuccessfully(string keyFilename) + public static void AsCipherParameters_WithDifferentLineEnding_WillReadTheKeysSuccessfully(string keyFilename) { // Arrange var keyPath = $"Mocks\\Keys\\{keyFilename}"; diff --git a/tests/Medidata.MAuth.Tests/MAuthOwinTests.cs b/tests/Medidata.MAuth.Tests/MAuthOwinTests.cs index c744972..33863d1 100644 --- a/tests/Medidata.MAuth.Tests/MAuthOwinTests.cs +++ b/tests/Medidata.MAuth.Tests/MAuthOwinTests.cs @@ -12,17 +12,17 @@ namespace Medidata.MAuth.Tests { - public class MAuthOwinTests + public static class MAuthOwinTests { [Theory] [InlineData("GET")] [InlineData("DELETE")] [InlineData("POST")] [InlineData("PUT")] - public async Task MAuthMiddleware_WithValidRequest_WillAuthenticate(string method) + public static async Task MAuthMiddleware_WithValidRequest_WillAuthenticate(string method) { // Arrange - var testData = await TestData.For(method); + var testData = await method.FromResource(); using (var server = TestServer.Create(app => { @@ -38,8 +38,7 @@ public async Task MAuthMiddleware_WithValidRequest_WillAuthenticate(string metho })) { // Act - var response = await server.HttpClient.SendAsync( - await testData.Request.Sign(TestExtensions.ClientOptions(testData.SignedTime))); + var response = await server.HttpClient.SendAsync(testData.ToHttpRequestMessage()); // Assert Assert.Equal(HttpStatusCode.OK, response.StatusCode); @@ -51,10 +50,10 @@ public async Task MAuthMiddleware_WithValidRequest_WillAuthenticate(string metho [InlineData("DELETE")] [InlineData("POST")] [InlineData("PUT")] - public async Task MAuthMiddleware_WithoutMAuthHeader_WillNotAuthenticate(string method) + public static async Task MAuthMiddleware_WithoutMAuthHeader_WillNotAuthenticate(string method) { // Arrange - var testData = await TestData.For(method); + var testData = await method.FromResource(); using (var server = TestServer.Create(app => { @@ -70,7 +69,8 @@ public async Task MAuthMiddleware_WithoutMAuthHeader_WillNotAuthenticate(string })) { // Act - var response = await server.HttpClient.SendAsync(testData.Request); + var response = await server.HttpClient.SendAsync( + new HttpRequestMessage(testData.Method.ToHttpMethod(), testData.Url)); // Assert Assert.Equal(HttpStatusCode.Unauthorized, response.StatusCode); @@ -82,10 +82,10 @@ public async Task MAuthMiddleware_WithoutMAuthHeader_WillNotAuthenticate(string [InlineData("DELETE")] [InlineData("POST")] [InlineData("PUT")] - public async Task MAuthMiddleware_WithEnabledExceptions_WillThrowException(string method) + public static async Task MAuthMiddleware_WithEnabledExceptions_WillThrowException(string method) { // Arrange - var testData = await TestData.For(method); + var testData = await method.FromResource(); using (var server = TestServer.Create(app => { @@ -103,7 +103,8 @@ public async Task MAuthMiddleware_WithEnabledExceptions_WillThrowException(strin { // Act, Assert var ex = await Assert.ThrowsAsync( - () => server.HttpClient.SendAsync(testData.Request)); + () => server.HttpClient.SendAsync( + new HttpRequestMessage(testData.Method.ToHttpMethod(), testData.Url))); Assert.Equal("The request has invalid MAuth authentication headers.", ex.Message); Assert.NotNull(ex.InnerException); @@ -115,10 +116,10 @@ public async Task MAuthMiddleware_WithEnabledExceptions_WillThrowException(strin [InlineData("DELETE")] [InlineData("POST")] [InlineData("PUT")] - public async Task MAuthMiddleware_WithNonSeekableBodyStream_WillRestoreBodyStream(string method) + public static async Task MAuthMiddleware_WithNonSeekableBodyStream_WillRestoreBodyStream(string method) { // Arrange - var testData = await TestData.For(method); + var testData = await method.FromResource(); var canSeek = false; var body = string.Empty; @@ -142,12 +143,11 @@ public async Task MAuthMiddleware_WithNonSeekableBodyStream_WillRestoreBodyStrea })) { // Act - var response = await new HttpClient().SendAsync( - await testData.Request.Sign(TestExtensions.ClientOptions(testData.SignedTime))); + var response = await new HttpClient().SendAsync(testData.ToHttpRequestMessage()); // Assert Assert.True(canSeek); - Assert.Equal(testData.Content ?? string.Empty, body); + Assert.Equal(testData.Base64Content.ToStringContent() ?? string.Empty, body); } } } diff --git a/tests/Medidata.MAuth.Tests/MAuthSigningHandlerTests.cs b/tests/Medidata.MAuth.Tests/MAuthSigningHandlerTests.cs index cdacc55..cd3a306 100644 --- a/tests/Medidata.MAuth.Tests/MAuthSigningHandlerTests.cs +++ b/tests/Medidata.MAuth.Tests/MAuthSigningHandlerTests.cs @@ -6,24 +6,24 @@ namespace Medidata.MAuth.Tests { - public class MAuthSigningHandlerTests + public static class MAuthSigningHandlerTests { [Theory] [InlineData("GET")] [InlineData("DELETE")] [InlineData("POST")] [InlineData("PUT")] - public async Task SendAsync_WithValidRequest_WillSignProperly(string method) + public static async Task SendAsync_WithValidRequest_WillSignProperly(string method) { // Arrange - var testData = await TestData.For(method); + var testData = await method.FromResource(); var actual = new AssertSigningHandler(); var signingHandler = new MAuthSigningHandler(TestExtensions.ClientOptions(testData.SignedTime), actual); // Act using (var client = new HttpClient(signingHandler)) { - await client.SendAsync(testData.Request); + await client.SendAsync(testData.ToHttpRequestMessage()); } // Assert diff --git a/tests/Medidata.MAuth.Tests/MAuthWebApiTests.cs b/tests/Medidata.MAuth.Tests/MAuthWebApiTests.cs index 5e46bb4..4004b0b 100644 --- a/tests/Medidata.MAuth.Tests/MAuthWebApiTests.cs +++ b/tests/Medidata.MAuth.Tests/MAuthWebApiTests.cs @@ -8,17 +8,17 @@ namespace Medidata.MAuth.Tests { - public class MAuthWebApiTests + public static class MAuthWebApiTests { [Theory] [InlineData("GET")] [InlineData("DELETE")] [InlineData("POST")] [InlineData("PUT")] - public async Task MAuthAuthenticatingHandler_WithValidRequest_WillAuthenticate(string method) + public static async Task MAuthAuthenticatingHandler_WithValidRequest_WillAuthenticate(string method) { // Arrange - var testData = await TestData.For(method); + var testData = await method.FromResource(); var actual = new AssertSigningHandler(); var handler = new MAuthAuthenticatingHandler(new MAuthWebApiOptions() @@ -32,8 +32,7 @@ public async Task MAuthAuthenticatingHandler_WithValidRequest_WillAuthenticate(s using (var server = new HttpClient(handler)) { // Act - var response = await server.SendAsync( - await testData.Request.Sign(TestExtensions.ClientOptions(testData.SignedTime))); + var response = await server.SendAsync(testData.ToHttpRequestMessage()); // Assert Assert.Equal(HttpStatusCode.OK, response.StatusCode); @@ -47,10 +46,10 @@ public async Task MAuthAuthenticatingHandler_WithValidRequest_WillAuthenticate(s [InlineData("DELETE")] [InlineData("POST")] [InlineData("PUT")] - public async Task MAuthAuthenticatingHandler_WithoutMAuthHeader_WillNotAuthenticate(string method) + public static async Task MAuthAuthenticatingHandler_WithoutMAuthHeader_WillNotAuthenticate(string method) { // Arrange - var testData = await TestData.For(method); + var testData = await method.FromResource(); var handler = new MAuthAuthenticatingHandler(new MAuthWebApiOptions() { @@ -63,7 +62,8 @@ public async Task MAuthAuthenticatingHandler_WithoutMAuthHeader_WillNotAuthentic using (var server = new HttpClient(handler)) { // Act - var response = await server.SendAsync(testData.Request); + var response = await server.SendAsync( + new HttpRequestMessage(testData.Method.ToHttpMethod(), testData.Url)); // Assert Assert.Equal(HttpStatusCode.Unauthorized, response.StatusCode); @@ -75,10 +75,10 @@ public async Task MAuthAuthenticatingHandler_WithoutMAuthHeader_WillNotAuthentic [InlineData("DELETE")] [InlineData("POST")] [InlineData("PUT")] - public async Task MAuthAuthenticatingHandler_WithEnabledExceptions_WillThrowException(string method) + public static async Task MAuthAuthenticatingHandler_WithEnabledExceptions_WillThrowException(string method) { // Arrange - var testData = await TestData.For(method); + var testData = await method.FromResource(); var handler = new MAuthAuthenticatingHandler(new MAuthWebApiOptions() { @@ -93,7 +93,8 @@ public async Task MAuthAuthenticatingHandler_WithEnabledExceptions_WillThrowExce { // Act, Assert var ex = await Assert.ThrowsAsync( - () => server.SendAsync(testData.Request)); + () => server.SendAsync( + new HttpRequestMessage(testData.Method.ToHttpMethod(), testData.Url))); Assert.Equal("The request has invalid MAuth authentication headers.", ex.Message); Assert.NotNull(ex.InnerException); diff --git a/tests/Medidata.MAuth.Tests/Medidata.MAuth.Tests.csproj b/tests/Medidata.MAuth.Tests/Medidata.MAuth.Tests.csproj index 209daca..9c39df1 100644 --- a/tests/Medidata.MAuth.Tests/Medidata.MAuth.Tests.csproj +++ b/tests/Medidata.MAuth.Tests/Medidata.MAuth.Tests.csproj @@ -11,6 +11,13 @@ true + + + + + + + @@ -18,19 +25,11 @@ - - - - - - Always - - - Always - - - Always - + + + + + PreserveNewest @@ -62,6 +61,7 @@ + diff --git a/tests/Medidata.MAuth.Tests/Mocks/RequestData/DELETE.json b/tests/Medidata.MAuth.Tests/Mocks/RequestData/DELETE.json new file mode 100644 index 0000000..e674ac3 --- /dev/null +++ b/tests/Medidata.MAuth.Tests/Mocks/RequestData/DELETE.json @@ -0,0 +1,7 @@ +{ + "Url": "http://localhost:29999/", + "Method": "DELETE", + "ApplicationUuid": "192cce84-8466-490e-b03e-074f82da3ee2", + "SignedTime": "2016-08-01 05:40:38 +0000", + "Payload": "C6vv/XIurgTnbp3YMPcejteTrVfXtb3NY/2A9NFmiMh85uDQ9rnZr1fXPdmX5tQX2rUh5g3KT65ky3c4gi0/fwKJbFLCv+AoTtNl1jTwam4ZBp76/8pd1WSEnXBMyKu9qpCpnEhxQZLJkBTjmg1gyin4/r+slxDfktwSYPUkkeK41ewgwudI/t76qZOE9kX2VZpqHAgGBKRACbOpclmkdtMQ3Fbg/pSWrPN5ve34+TCNZbcqPI7E0dRfAzcAOD5DNftVcv2jKy3vJ68J0HnvdDIj03xVemjMRewDveD4OG4DGjP6HF4MouYy0QnbWIE+EVvUFRy81xhneTR10yDcYA==" +} \ No newline at end of file diff --git a/tests/Medidata.MAuth.Tests/Mocks/RequestData/GET.json b/tests/Medidata.MAuth.Tests/Mocks/RequestData/GET.json new file mode 100644 index 0000000..49f5f8f --- /dev/null +++ b/tests/Medidata.MAuth.Tests/Mocks/RequestData/GET.json @@ -0,0 +1,7 @@ +{ + "Url": "http://localhost:29999/", + "Method": "GET", + "ApplicationUuid": "192cce84-8466-490e-b03e-074f82da3ee2", + "SignedTime": "2016-08-01 03:22:47 +0000", + "Payload": "hg1RmUN/PNfiOpGRieEd77k9QnUluHag5UP7v/3azj8WHNmG9aHPZjPvwzDgCLCPFTthtaWOk5LSgHjQUcr/qWcg5o+Z+dbvzfbZpqkrwkzxrPLdzdZkulXSXNs+xEBFs1dQxLBL58jJ3BOvWPscWGYzd8IQThJ6rjNZiD+/lMGyDBm0BJgOHcBJ0AThywdEvOMXYQqR3daDM8OY2souleMzU1t0A1naq67TqTMAi5vEVCXvJ4AJhoNvrjATpzg/hM7ozXy91NgO0nVqJErcJBu3qX8UU4sqsQOP26ROTNHed/cBMdjzQZ/Bm/jMtWRtPmGozNzW12utRzh/Twzagg==" +} \ No newline at end of file diff --git a/tests/Medidata.MAuth.Tests/Mocks/RequestData/POST.json b/tests/Medidata.MAuth.Tests/Mocks/RequestData/POST.json new file mode 100644 index 0000000..b639f9a --- /dev/null +++ b/tests/Medidata.MAuth.Tests/Mocks/RequestData/POST.json @@ -0,0 +1,8 @@ +{ + "Url": "http://localhost:29999/", + "Method": "POST", + "ApplicationUuid": "192cce84-8466-490e-b03e-074f82da3ee2", + "SignedTime": "2016-08-01 03:31:54 +0000", + "Base64Content": "VGhlIHJlcXVlc3QgYm9keSBmb3IgdGhlIFBPU1QgbWVzc2FnZS4=", + "Payload": "cdsjH35jR0IR77riAxMkYOWT8ZNrZzlF336HM274sFvUwV57vZ0200/sO4f2NXkwru9iiLIDAoo7ZKI8atWt96cEGVXE+5EkN8BJa0iLkhaqZ9fEqj6F6YiB6QH6JJa2RiAW4xZmvFFVjjc6crxkk9MxB8qv/l2Ta08JMZg6npfjQG6OQ0DDPckkYWKHXq2f8dfwoWe/jhBBrzT9TdMmxO74GT/e5FffcBIQFVw6Cm1DBoQFETU61SMtI/4AS5hewGMbHjvCdIRzV7Wg3GDnLsNCXqk/pNV0vWLL+jXd4Zqx8VUhFDUGq7yn9ZjslBhkca80DoQmX7Zgd/4BGUzTxg==" +} \ No newline at end of file diff --git a/tests/Medidata.MAuth.Tests/Mocks/RequestData/POSTWithBinaryData.json b/tests/Medidata.MAuth.Tests/Mocks/RequestData/POSTWithBinaryData.json new file mode 100644 index 0000000..f551516 --- /dev/null +++ b/tests/Medidata.MAuth.Tests/Mocks/RequestData/POSTWithBinaryData.json @@ -0,0 +1,8 @@ +{ + "Url": "http://localhost:29999/", + "Method": "POST", + "ApplicationUuid": "192cce84-8466-490e-b03e-074f82da3ee2", + "SignedTime": "2018-10-02 08:21:03 +0000", + "Base64Content": "N3q8ryccAAPP2NhAnAoAAAAAAABUAAAAAAAAAJp51s8AJhvKRmda8ne4fYbYQdsFNc2DpXwSpQXbkL0vFNNxcpaoin2EVnGNaiKYq549w1XvzKXD3XbQa2rmXszZWApBl1bI/FsLDKGC0VHA+Y6actTa9q0WzOvPT7/aMG+3/N3IbuV6O9dsvLNbWeoADUnubbql0yh6JA15cgda8pWI/9o6LnMsEPHBctImUxDUvnAdxMll37Vx9jnjKVTZ3FUqN6kJ6LpZgYlX3pFsgT8ABjgdhg4dIE7xwUdom4LWsylukG/JYGNuCi58JLtx5H8I1mUgnjpXDSL1Z6xRSpypddIQjv+3MpHD5iQlYTkhfwmczvSQZG+aSkOk6A5BL67QV4ozo03RH2nP3QqTQnwEWhmyvWV5AQGWukryjLbhilhIaN7oqS/B9Jhve666xIhfg8Ev7F+lrHgvtue1cnbaCVFXuyZJs0jYfRds4wy6Ytkh8dE=", + "Payload": "pXO9EecWIU1Qf0diqYhTypEfSnT822YFviS4K0Jq3OfZjpDb1fL5b8ePDgD9BXLLM1Sp8+wh90RyE3QkMnfuQL1pHD+ODnPfglIQFvOAtuqVEVHN3ztQ4l8LZcPD1pX3PC+8Aj3WzgbCaMDg6trArkZKFNE2IWuwuLvaWGHfANBCfF/VVINAtZ8ZUSDJrYT9vkfdFvQDsEYDwtdlt9fY6EvhNRtILXXafchtk0c9eC3VC1jBlWwcK+v1OM3YKKEa9oqR9wv7bjxS2sBfkVA6Av4cm1O6uUCYJoxbrKtmfU6sBHhBW55B+NLLoNajfxU+quaaoxmX/x3KaTW3QFVUYQ==" +} \ No newline at end of file diff --git a/tests/Medidata.MAuth.Tests/Mocks/RequestData/PUT.json b/tests/Medidata.MAuth.Tests/Mocks/RequestData/PUT.json new file mode 100644 index 0000000..86dfcc2 --- /dev/null +++ b/tests/Medidata.MAuth.Tests/Mocks/RequestData/PUT.json @@ -0,0 +1,8 @@ +{ + "Url": "http://localhost:29999/", + "Method": "PUT", + "ApplicationUuid": "192cce84-8466-490e-b03e-074f82da3ee2", + "SignedTime": "2016-08-01 05:38:19 +0000", + "Base64Content": "VGhlIHJlcXVlc3QgYm9keSBmb3IgdGhlIFBVVCBtZXNzYWdlLg==", + "Payload": "h++GyB+btZfl0yRbhnIMqVJqytxFakYKpwvcVmI6ofTMSp5HjVSn54wwEVoCFEz1Esvc9rEwHlruavR1qxFSj7FBzwTM6eKiJywTSeNqDqf1SYmjppl7giz7KAGRY2bmxoyV0g63a5TncbbSmBKJSngYs1x1kskFILt8gDeEKHZHNxLqgPwXuzPpNUiwCvtxypIsC6YEHml59TRAXjsHJHC8HxxOWQW+io9Pb6w1adgI9nzekyxgQX8+LVZRn9mBLiux+6O5N5mY7V1yONeMifHwVhTMouyJDwGBda1/0E7IUlFv2wsxJIO4O/ulkwbk1XBECUdIe7ITtnrC6zY1Fg==" +} \ No newline at end of file diff --git a/tests/Medidata.MAuth.Tests/Mocks/Requests/DELETE.txt b/tests/Medidata.MAuth.Tests/Mocks/Requests/DELETE.txt deleted file mode 100644 index 83064de..0000000 --- a/tests/Medidata.MAuth.Tests/Mocks/Requests/DELETE.txt +++ /dev/null @@ -1,2 +0,0 @@ -C6vv/XIurgTnbp3YMPcejteTrVfXtb3NY/2A9NFmiMh85uDQ9rnZr1fXPdmX5tQX2rUh5g3KT65ky3c4gi0/fwKJbFLCv+AoTtNl1jTwam4ZBp76/8pd1WSEnXBMyKu9qpCpnEhxQZLJkBTjmg1gyin4/r+slxDfktwSYPUkkeK41ewgwudI/t76qZOE9kX2VZpqHAgGBKRACbOpclmkdtMQ3Fbg/pSWrPN5ve34+TCNZbcqPI7E0dRfAzcAOD5DNftVcv2jKy3vJ68J0HnvdDIj03xVemjMRewDveD4OG4DGjP6HF4MouYy0QnbWIE+EVvUFRy81xhneTR10yDcYA== -2016-08-01 5:40:38 +0000 \ No newline at end of file diff --git a/tests/Medidata.MAuth.Tests/Mocks/Requests/GET.txt b/tests/Medidata.MAuth.Tests/Mocks/Requests/GET.txt deleted file mode 100644 index 17f402c..0000000 --- a/tests/Medidata.MAuth.Tests/Mocks/Requests/GET.txt +++ /dev/null @@ -1,2 +0,0 @@ -hg1RmUN/PNfiOpGRieEd77k9QnUluHag5UP7v/3azj8WHNmG9aHPZjPvwzDgCLCPFTthtaWOk5LSgHjQUcr/qWcg5o+Z+dbvzfbZpqkrwkzxrPLdzdZkulXSXNs+xEBFs1dQxLBL58jJ3BOvWPscWGYzd8IQThJ6rjNZiD+/lMGyDBm0BJgOHcBJ0AThywdEvOMXYQqR3daDM8OY2souleMzU1t0A1naq67TqTMAi5vEVCXvJ4AJhoNvrjATpzg/hM7ozXy91NgO0nVqJErcJBu3qX8UU4sqsQOP26ROTNHed/cBMdjzQZ/Bm/jMtWRtPmGozNzW12utRzh/Twzagg== -2016-08-01 3:22:47 +0000 \ No newline at end of file diff --git a/tests/Medidata.MAuth.Tests/Mocks/Requests/POST.txt b/tests/Medidata.MAuth.Tests/Mocks/Requests/POST.txt deleted file mode 100644 index 7d4bc05..0000000 --- a/tests/Medidata.MAuth.Tests/Mocks/Requests/POST.txt +++ /dev/null @@ -1,3 +0,0 @@ -cdsjH35jR0IR77riAxMkYOWT8ZNrZzlF336HM274sFvUwV57vZ0200/sO4f2NXkwru9iiLIDAoo7ZKI8atWt96cEGVXE+5EkN8BJa0iLkhaqZ9fEqj6F6YiB6QH6JJa2RiAW4xZmvFFVjjc6crxkk9MxB8qv/l2Ta08JMZg6npfjQG6OQ0DDPckkYWKHXq2f8dfwoWe/jhBBrzT9TdMmxO74GT/e5FffcBIQFVw6Cm1DBoQFETU61SMtI/4AS5hewGMbHjvCdIRzV7Wg3GDnLsNCXqk/pNV0vWLL+jXd4Zqx8VUhFDUGq7yn9ZjslBhkca80DoQmX7Zgd/4BGUzTxg== -2016-08-01 3:31:54 +0000 -The request body for the POST message. \ No newline at end of file diff --git a/tests/Medidata.MAuth.Tests/Mocks/Requests/PUT.txt b/tests/Medidata.MAuth.Tests/Mocks/Requests/PUT.txt deleted file mode 100644 index 66cc82a..0000000 --- a/tests/Medidata.MAuth.Tests/Mocks/Requests/PUT.txt +++ /dev/null @@ -1,3 +0,0 @@ -h++GyB+btZfl0yRbhnIMqVJqytxFakYKpwvcVmI6ofTMSp5HjVSn54wwEVoCFEz1Esvc9rEwHlruavR1qxFSj7FBzwTM6eKiJywTSeNqDqf1SYmjppl7giz7KAGRY2bmxoyV0g63a5TncbbSmBKJSngYs1x1kskFILt8gDeEKHZHNxLqgPwXuzPpNUiwCvtxypIsC6YEHml59TRAXjsHJHC8HxxOWQW+io9Pb6w1adgI9nzekyxgQX8+LVZRn9mBLiux+6O5N5mY7V1yONeMifHwVhTMouyJDwGBda1/0E7IUlFv2wsxJIO4O/ulkwbk1XBECUdIe7ITtnrC6zY1Fg== -2016-08-01 5:38:19 +0000 -The request body for the PUT message. \ No newline at end of file diff --git a/tests/Medidata.MAuth.Tests/UtilityExtensionsTest.cs b/tests/Medidata.MAuth.Tests/UtilityExtensionsTest.cs index 4d67295..43d6d48 100644 --- a/tests/Medidata.MAuth.Tests/UtilityExtensionsTest.cs +++ b/tests/Medidata.MAuth.Tests/UtilityExtensionsTest.cs @@ -6,14 +6,14 @@ namespace Medidata.MAuth.Tests { - public class UtilityExtensionsTest + public static class UtilityExtensionsTest { [Fact] - public async Task TryParseAuthenticationHeader_WithValidAuthHeader_WillSucceed() + public static async Task TryParseAuthenticationHeader_WithValidAuthHeader_WillSucceed() { // Arrange - var request = await TestData.For("GET"); - var expected = (TestExtensions.ClientUuid, request.Payload); + var request = await "GET".FromResource(); + var expected = (request.ApplicationUuid, request.Payload); // Act var result = request.MAuthHeader.TryParseAuthenticationHeader(out var actual); @@ -24,7 +24,7 @@ public async Task TryParseAuthenticationHeader_WithValidAuthHeader_WillSucceed() } [Fact] - public void TryParseAuthenticationHeader_WithInvalidAuthHeader_WillFail() + public static void TryParseAuthenticationHeader_WithInvalidAuthHeader_WillFail() { // Arrange var invalid = "invalid"; @@ -37,7 +37,7 @@ public void TryParseAuthenticationHeader_WithInvalidAuthHeader_WillFail() } [Fact] - public void ParseAuthenticationHeader_WithInvalidAuthHeader_WillThrowException() + public static void ParseAuthenticationHeader_WithInvalidAuthHeader_WillThrowException() { // Arrange var invalid = "invalid"; diff --git a/version.props b/version.props index 152c914..6045642 100644 --- a/version.props +++ b/version.props @@ -1,6 +1,6 @@  - 3.0.3 + 3.0.4