Skip to content

Commit

Permalink
Merge pull request #23 from mdsol/develop
Browse files Browse the repository at this point in the history
Release of v2.4.0
  • Loading branch information
bvillanueva-mdsol authored Jul 28, 2017
2 parents 451d1ea + b8b1051 commit dbde2fb
Show file tree
Hide file tree
Showing 7 changed files with 121 additions and 11 deletions.
5 changes: 4 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,8 @@
# Changes in Medidata.MAuth

## v2.4.0
- **[Core]** Added a utility extension class to help using MAuth specific processing methods

## v2.3.0
- **[AspNetCore]** Added a new middleware to be able to use MAuth with the ASP.NET Core MVC
infrastructure
Expand Down Expand Up @@ -35,4 +38,4 @@ an `MAuthOptions` instance (which in turn set to be an abstract class)
with a `MemoryStream` in cases when the original body stream is not seekable.

## v1.0.0
- Initial version
- Initial version
5 changes: 3 additions & 2 deletions Medidata.MAuth.sln
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@

Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio 15
VisualStudioVersion = 15.0.26430.13
VisualStudioVersion = 15.0.26430.16
MinimumVisualStudioVersion = 10.0.40219.1
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "src", "src", "{2A4336AA-6F7D-414B-AB2B-81A8F2E82A48}"
EndProject
Expand All @@ -11,6 +11,7 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution
CHANGELOG.md = CHANGELOG.md
LICENSE.md = LICENSE.md
README.md = README.md
version.props = version.props
EndProjectSection
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Medidata.MAuth.Core", "src\Medidata.MAuth.Core\Medidata.MAuth.Core.csproj", "{C9A9FECB-DB5B-40C3-B7CC-F0251853DDE6}"
Expand All @@ -29,7 +30,7 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "build", "build", "{F8B8C2CD
build\common.props = build\common.props
EndProjectSection
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Medidata.MAuth.AspNetCore", "src\Medidata.MAuth.AspNetCore\Medidata.MAuth.AspNetCore.csproj", "{1BC50789-3BAE-4D87-B89C-C2658BFF6522}"
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Medidata.MAuth.AspNetCore", "src\Medidata.MAuth.AspNetCore\Medidata.MAuth.AspNetCore.csproj", "{1BC50789-3BAE-4D87-B89C-C2658BFF6522}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Expand Down
9 changes: 3 additions & 6 deletions src/Medidata.MAuth.Core/MAuthCoreExtensions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -97,15 +97,12 @@ public static PayloadAuthenticationInfo GetAuthenticationInfo(this HttpRequestMe
if (signedTime == default(long))
throw new ArgumentException("Invalid MAuth signed time header value.", nameof(signedTime));

var match = Constants.AuthenticationHeaderRegex.Match(authHeader);

if (!match.Success)
throw new ArgumentException("Invalid MAuth authentication header value.", nameof(authHeader));
var (uuid, payload) = authHeader.ParseAuthenticationHeader();

return new PayloadAuthenticationInfo()
{
ApplicationUuid = new Guid(match.Groups["uuid"].Value),
Payload = Convert.FromBase64String(match.Groups["payload"].Value),
ApplicationUuid = uuid,
Payload = Convert.FromBase64String(payload),
SignedTime = signedTime.FromUnixTimeSeconds()
};
}
Expand Down
3 changes: 2 additions & 1 deletion src/Medidata.MAuth.Core/Medidata.MAuth.Core.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,8 @@
</PropertyGroup>

<ItemGroup>
<PackageReference Include="Newtonsoft.Json" Version="10.0.2" />
<PackageReference Include="Newtonsoft.Json" Version="10.0.3" />
<PackageReference Include="System.ValueTuple" Version="4.3.1" />
</ItemGroup>

<ItemGroup Condition=" '$(TargetFramework)' == 'netstandard1.4' ">
Expand Down
59 changes: 59 additions & 0 deletions src/Medidata.MAuth.Core/UtilityExtensions.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
using System;

namespace Medidata.MAuth.Core
{
/// <summary>
/// Contains utility extension methods for MAuth.
/// </summary>
public static class UtilityExtensions
{
/// <summary>
/// Parses an MAuth authentication HTTP header value for the application uuid and the MAuth signature payload.
/// If the parsing is not successful, an <see cref="ArgumentException"/> is thrown.
/// </summary>
/// <param name="headerValue">
/// The value of the X-MWS-Authentication HTTP header containing the application uuid and the MAuth signature
/// payload.
/// </param>
/// <returns>The application uuid and the payload encoded with Base64 encoding.</returns>
public static (Guid Uuid, string Base64Payload) ParseAuthenticationHeader(this string headerValue) =>
headerValue.TryParseAuthenticationHeader(out var result) ?
result :
throw new ArgumentException("Invalid MAuth authentication header value.", nameof(headerValue));

/// <summary>
/// Parses an MAuth authentication HTTP header value for the application uuid and the MAuth signature payload.
/// A return value indicates whether the parsing succeeded.
/// </summary>
/// <param name="headerValue">
/// The value of the X-MWS-Authentication HTTP header containing the application uuid and the MAuth signature
/// payload.
/// </param>
/// <param name="result">
/// When this method returns, contains the application uuid and the Base64 encoded MAuth signature
/// payload contained in <paramref name="headerValue"/> if the parsing succeeded, or the default value of a
/// (<see cref="Guid"/>, <see cref="string"/>) tuple if the parsing failed. The parsing fails if the
/// <paramref name="headerValue"/> is <see langword="null"/> or <see cref="string.Empty"/>, or not of the
/// correct format. This parameter is passed uninitialized; any value originally supplied in
/// <paramref name="result"/> will be overwritten.</param>
/// <returns>
/// <see langword="true"/> if <paramref name="headerValue"/> was parsed successfully; otherwise,
/// <see langword="false"/>.
/// </returns>
public static bool TryParseAuthenticationHeader(this string headerValue,
out (Guid Uuid, string Base64Payload) result)
{
var match = Constants.AuthenticationHeaderRegex.Match(headerValue);

result = default((Guid, string));

if (!match.Success)
return false;

result.Uuid = new Guid(match.Groups["uuid"].Value);
result.Base64Payload = match.Groups["payload"].Value;

return true;
}
}
}
49 changes: 49 additions & 0 deletions tests/Medidata.MAuth.Tests/UtilityExtensionsTest.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
using System;
using System.Threading.Tasks;
using Medidata.MAuth.Core;
using Medidata.MAuth.Tests.Infrastructure;
using Xunit;

namespace Medidata.MAuth.Tests
{
public class UtilityExtensionsTest
{
[Fact]
public async Task TryParseAuthenticationHeader_WithValidAuthHeader_WillSucceed()
{
// Arrange
var request = await TestData.For("GET");
var expected = (TestExtensions.ClientUuid, request.Payload);

// Act
var result = request.MAuthHeader.TryParseAuthenticationHeader(out var actual);

// Assert
Assert.True(result);
Assert.Equal(expected, actual);
}

[Fact]
public void TryParseAuthenticationHeader_WithInvalidAuthHeader_WillFail()
{
// Arrange
var invalid = "invalid";

// Act
var result = invalid.TryParseAuthenticationHeader(out var actual);

// Assert
Assert.False(result);
}

[Fact]
public void ParseAuthenticationHeader_WithInvalidAuthHeader_WillThrowException()
{
// Arrange
var invalid = "invalid";

// Act, Assert
Assert.Throws<ArgumentException>(() => invalid.ParseAuthenticationHeader());
}
}
}
2 changes: 1 addition & 1 deletion version.props
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
<?xml version="1.0" encoding="utf-8"?>
<Project>
<PropertyGroup>
<Version>2.3.0</Version>
<Version>2.4.0</Version>
</PropertyGroup>
</Project>

0 comments on commit dbde2fb

Please sign in to comment.