Skip to content

Commit 09eba14

Browse files
Merge pull request #9 from Mastercard/feature/netcore-support
Add support for the "csharp-netcore" OpenAPI Generator and RestSharp "non Portable"
2 parents 3a15b40 + a145da9 commit 09eba14

File tree

12 files changed

+333
-9
lines changed

12 files changed

+333
-9
lines changed

Mastercard.Developer.OAuth1Signer.Core/Mastercard.Developer.OAuth1Signer.Core.csproj

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
<PropertyGroup>
44
<TargetFramework>netstandard1.3</TargetFramework>
55
<GeneratePackageOnBuild>true</GeneratePackageOnBuild>
6-
<Version>1.2.7</Version>
6+
<Version>1.3.0</Version>
77
<Product>Mastercard.Developer.OAuth1Signer.Core</Product>
88
<Authors>Mastercard</Authors>
99
<Company>Mastercard</Company>
@@ -16,7 +16,7 @@
1616
<SignAssembly>true</SignAssembly>
1717
<AssemblyOriginatorKeyFile>../Identity.snk</AssemblyOriginatorKeyFile>
1818
<AssemblyVersion>1.0.0.0</AssemblyVersion> <!-- Frozen -->
19-
<FileVersion>1.2.7.0</FileVersion> <!-- Same version as the package version -->
19+
<FileVersion>1.3.0.0</FileVersion> <!-- Same version as the package version -->
2020
<DocumentationFile>Mastercard.Developer.OAuth1Signer.Core.xml</DocumentationFile>
2121
<IncludeSymbols>true</IncludeSymbols>
2222
<SymbolPackageFormat>snupkg</SymbolPackageFormat>

Mastercard.Developer.OAuth1Signer.RestSharp/Authenticators/RestSharpOAuth1Authenticator.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ namespace Mastercard.Developer.OAuth1Signer.RestSharp.Authenticators
1010
{
1111
/// <inheritdoc />
1212
/// <summary>
13-
/// A RestSharp authenticator for computing and adding an OAuth1 authorization header to HTTP requests.
13+
/// A RestSharp Portable authenticator for computing and adding an OAuth1 authorization header to HTTP requests.
1414
/// </summary>
1515
public class RestSharpOAuth1Authenticator : IAuthenticator
1616
{

Mastercard.Developer.OAuth1Signer.RestSharp/Mastercard.Developer.OAuth1Signer.RestSharp.csproj

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3,20 +3,20 @@
33
<PropertyGroup>
44
<TargetFramework>netstandard1.3</TargetFramework>
55
<GeneratePackageOnBuild>true</GeneratePackageOnBuild>
6-
<Version>1.2.7</Version>
6+
<Version>1.3.0</Version>
77
<Product>Mastercard.Developer.OAuth1Signer.RestSharp</Product>
88
<Authors>Mastercard</Authors>
99
<Company>Mastercard</Company>
1010
<PackageLicenseFile>LICENSE</PackageLicenseFile>
1111
<PackageProjectUrl>https://github.com/Mastercard/oauth1-signer-csharp</PackageProjectUrl>
1212
<PackageReleaseNotes>See: https://github.com/Mastercard/oauth1-signer-csharp/releases</PackageReleaseNotes>
1313
<RepositoryUrl>https://github.com/Mastercard/oauth1-signer-csharp</RepositoryUrl>
14-
<Description>Zero dependency library for generating a Mastercard API compliant OAuth signature</Description>
14+
<Description>RestSharp Portable extension for generating a Mastercard API compliant OAuth signature</Description>
1515
<!-- See: https://docs.microsoft.com/en-us/dotnet/standard/library-guidance/strong-naming -->
1616
<SignAssembly>true</SignAssembly>
1717
<AssemblyOriginatorKeyFile>../Identity.snk</AssemblyOriginatorKeyFile>
1818
<AssemblyVersion>1.0.0.0</AssemblyVersion> <!-- Frozen -->
19-
<FileVersion>1.2.7.0</FileVersion> <!-- Same version as the package version -->
19+
<FileVersion>1.3.0.0</FileVersion> <!-- Same version as the package version -->
2020
<DocumentationFile>Mastercard.Developer.OAuth1Signer.RestSharp.xml</DocumentationFile>
2121
<IncludeSymbols>true</IncludeSymbols>
2222
<SymbolPackageFormat>snupkg</SymbolPackageFormat>

Mastercard.Developer.OAuth1Signer.RestSharp/Signers/RestSharpSigner.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@
1010
namespace Mastercard.Developer.OAuth1Signer.RestSharp.Signers
1111
{
1212
/// <summary>
13-
/// Utility class for signing RestSharp request objects.
13+
/// Utility class for signing RestSharp Portable request objects.
1414
/// </summary>
1515
public sealed class RestSharpSigner : BaseSigner
1616
{
Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
using System;
2+
using System.Net;
3+
using System.Net.Http;
4+
using System.Security.Cryptography;
5+
using System.Threading.Tasks;
6+
using Mastercard.Developer.OAuth1Signer.RestSharpV2.Signers;
7+
using RestSharp;
8+
using RestSharp.Authenticators;
9+
10+
#pragma warning disable 1591
11+
12+
namespace Mastercard.Developer.OAuth1Signer.RestSharpV2.Authenticators
13+
{
14+
/// <inheritdoc />
15+
/// <summary>
16+
/// A RestSharp authenticator for computing and adding an OAuth1 authorization header to HTTP requests.
17+
/// </summary>
18+
public class RestSharpOAuth1Authenticator : IAuthenticator
19+
{
20+
private Uri BaseUri { get; }
21+
private RestSharpSigner Signer { get; }
22+
23+
public RestSharpOAuth1Authenticator(string consumerKey, RSA signingKey, Uri baseUri)
24+
{
25+
BaseUri = baseUri ?? throw new ArgumentNullException(nameof(baseUri));
26+
Signer = new RestSharpSigner(consumerKey, signingKey);
27+
}
28+
29+
public Task PreAuthenticate(IRestClient client, IRestRequest request, ICredentials credentials) => Task.Run(() => Signer.Sign(BaseUri, request));
30+
31+
public Task PreAuthenticate(HttpClient client, HttpRequestMessage request, ICredentials credentials) => throw new NotImplementedException();
32+
33+
public bool CanPreAuthenticate(IRestClient client, IRestRequest request, ICredentials credentials) => true;
34+
35+
public bool CanPreAuthenticate(HttpClient client, HttpRequestMessage request, ICredentials credentials) => false;
36+
37+
public bool CanHandleChallenge(HttpClient client, HttpRequestMessage request, ICredentials credentials, HttpResponseMessage response) => false;
38+
39+
public Task HandleChallenge(HttpClient client, HttpRequestMessage request, ICredentials credentials, HttpResponseMessage response) => throw new NotImplementedException();
40+
41+
public void Authenticate(IRestClient client, IRestRequest request)
42+
{
43+
throw new NotImplementedException();
44+
}
45+
}
46+
}
Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
<Project Sdk="Microsoft.NET.Sdk">
2+
3+
<PropertyGroup>
4+
<TargetFramework>netstandard2.0</TargetFramework>
5+
<GeneratePackageOnBuild>true</GeneratePackageOnBuild>
6+
<Version>1.3.0</Version>
7+
<Product>Mastercard.Developer.OAuth1Signer.RestSharpV2</Product>
8+
<Authors>Mastercard</Authors>
9+
<Company>Mastercard</Company>
10+
<PackageLicenseFile>LICENSE</PackageLicenseFile>
11+
<PackageProjectUrl>https://github.com/Mastercard/oauth1-signer-csharp</PackageProjectUrl>
12+
<PackageReleaseNotes>See: https://github.com/Mastercard/oauth1-signer-csharp/releases</PackageReleaseNotes>
13+
<RepositoryUrl>https://github.com/Mastercard/oauth1-signer-csharp</RepositoryUrl>
14+
<Description>RestSharp extension for generating a Mastercard API compliant OAuth signature</Description>
15+
<!-- See: https://docs.microsoft.com/en-us/dotnet/standard/library-guidance/strong-naming -->
16+
<SignAssembly>true</SignAssembly>
17+
<AssemblyOriginatorKeyFile>../Identity.snk</AssemblyOriginatorKeyFile>
18+
<AssemblyVersion>1.0.0.0</AssemblyVersion> <!-- Frozen -->
19+
<FileVersion>1.3.0.0</FileVersion> <!-- Same version as the package version -->
20+
<DocumentationFile>Mastercard.Developer.OAuth1Signer.RestSharpV2.xml</DocumentationFile>
21+
<IncludeSymbols>true</IncludeSymbols>
22+
<SymbolPackageFormat>snupkg</SymbolPackageFormat>
23+
</PropertyGroup>
24+
25+
<ItemGroup>
26+
<None Include="../LICENSE" Pack="true" PackagePath="" />
27+
<None Include="../README.md" Pack="true" PackagePath="" />
28+
</ItemGroup>
29+
30+
<ItemGroup>
31+
<PackageReference Include="RestSharp" Version="106.11.4" /> <!-- Minimum version, inclusive -->
32+
</ItemGroup>
33+
34+
<ItemGroup>
35+
<ProjectReference Include="..\Mastercard.Developer.OAuth1Signer.Core\Mastercard.Developer.OAuth1Signer.Core.csproj" />
36+
</ItemGroup>
37+
38+
</Project>
Lines changed: 78 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,78 @@
1+
using System;
2+
using System.Linq;
3+
using System.Security.Cryptography;
4+
using System.Text;
5+
using Mastercard.Developer.OAuth1Signer.Core;
6+
using Mastercard.Developer.OAuth1Signer.Core.Signers;
7+
using RestSharp;
8+
9+
#pragma warning disable 1591
10+
11+
namespace Mastercard.Developer.OAuth1Signer.RestSharpV2.Signers
12+
{
13+
/// <summary>
14+
/// Utility class for signing RestSharp request objects.
15+
/// </summary>
16+
public sealed class RestSharpSigner : BaseSigner
17+
{
18+
public RestSharpSigner(string consumerKey, RSA signingKey) : base(consumerKey, signingKey)
19+
{
20+
}
21+
22+
public RestSharpSigner(string consumerKey, RSA signingKey, Encoding encoding) : base(consumerKey, signingKey, encoding)
23+
{
24+
}
25+
26+
public void Sign(Uri baseUri, IRestRequest request)
27+
{
28+
if (baseUri == null) throw new ArgumentNullException(nameof(baseUri));
29+
if (request == null) throw new ArgumentNullException(nameof(request));
30+
31+
// Build the full request URI
32+
var fullUri = new StringBuilder();
33+
fullUri.Append(baseUri.ToString().TrimEnd('/'));
34+
var resource = request.Resource;
35+
if (!string.IsNullOrEmpty(resource))
36+
{
37+
resource = resource.TrimStart('.');
38+
resource = resource.TrimStart('/');
39+
fullUri.Append("/").Append(resource);
40+
}
41+
42+
// Add query params
43+
var parameterString = new StringBuilder();
44+
foreach (var requestParameter in request.Parameters.Where(p => p.Type == ParameterType.QueryString))
45+
{
46+
parameterString
47+
.Append(parameterString.Length > 0 ? "&" : string.Empty)
48+
.Append(Uri.EscapeDataString(requestParameter.Name ?? throw new InvalidOperationException("Parameter name cannot be null")))
49+
.Append("=")
50+
.Append(Uri.EscapeDataString(requestParameter.Value as string ?? throw new InvalidOperationException("Parameter Value cannot be null")));
51+
}
52+
if (parameterString.Length > 0)
53+
{
54+
fullUri.Append("?").Append(parameterString);
55+
}
56+
57+
// Fix URL segments
58+
fullUri = request.Parameters
59+
.Where(p => p.Type == ParameterType.UrlSegment)
60+
.Aggregate(fullUri, (current, requestParameter) => current.Replace($"{{{requestParameter.Name}}}", requestParameter.Value?.ToString() ?? string.Empty));
61+
62+
// Read the body
63+
var bodyParam = request.Parameters.FirstOrDefault(param => param.Type == ParameterType.RequestBody);
64+
65+
// Serialize the body if required
66+
var payload = bodyParam?.Value ?? string.Empty;
67+
if (!(payload is string))
68+
{
69+
payload = request.JsonSerializer.Serialize(payload);
70+
}
71+
72+
// Generate the header and add it to the request
73+
var methodString = request.Method.ToString();
74+
var header = OAuth.GetAuthorizationHeader(fullUri.ToString(), methodString, payload.ToString(), Encoding, ConsumerKey, SigningKey);
75+
request.AddHeader(OAuth.AuthorizationHeaderName, header);
76+
}
77+
}
78+
}
Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
using System;
2+
using Mastercard.Developer.OAuth1Signer.RestSharpV2.Authenticators;
3+
using Mastercard.Developer.OAuth1Signer.Tests.NetCore.Test;
4+
using Microsoft.VisualStudio.TestTools.UnitTesting;
5+
using RestSharp;
6+
7+
namespace Mastercard.Developer.OAuth1Signer.Tests.NetCore.Authenticators
8+
{
9+
[TestClass]
10+
public class RestSharpV2OAuth1AuthenticatorTest
11+
{
12+
[TestMethod]
13+
public void TestPreAuthenticate_ShouldSignRequest()
14+
{
15+
// GIVEN
16+
var signingKey = TestUtils.GetTestSigningKey();
17+
const string consumerKey = "Some key";
18+
var baseUri = new Uri("https://api.mastercard.com/");
19+
var request = new RestRequest
20+
{
21+
Method = Method.GET,
22+
Resource = "/service"
23+
};
24+
25+
// WHEN
26+
var instanceUnderTest = new RestSharpOAuth1Authenticator(consumerKey, signingKey, baseUri);
27+
var task = instanceUnderTest.PreAuthenticate(null, request, null);
28+
task.Wait();
29+
30+
// THEN
31+
var authorizationHeaders = request.Parameters.FindAll(param => param.Name == "Authorization" && param.Type == ParameterType.HttpHeader);
32+
Assert.AreEqual(1, authorizationHeaders.Count);
33+
}
34+
}
35+
}

Mastercard.Developer.OAuth1Signer.Tests/NetCore2/Mastercard.Developer.OAuth1Signer.Tests.NetCore2.csproj

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@
2424

2525
<ItemGroup>
2626
<ProjectReference Include="..\..\Mastercard.Developer.OAuth1Signer.RestSharp\Mastercard.Developer.OAuth1Signer.RestSharp.csproj" />
27+
<ProjectReference Include="..\..\Mastercard.Developer.OAuth1Signer.RestSharpV2\Mastercard.Developer.OAuth1Signer.RestSharpV2.csproj" />
2728
<ProjectReference Include="..\..\Mastercard.Developer.OAuth1Signer.Core\Mastercard.Developer.OAuth1Signer.Core.csproj" />
2829
</ItemGroup>
2930

Lines changed: 113 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,113 @@
1+
using System;
2+
using Mastercard.Developer.OAuth1Signer.RestSharpV2.Signers;
3+
using Mastercard.Developer.OAuth1Signer.Tests.NetCore.Test;
4+
using Microsoft.VisualStudio.TestTools.UnitTesting;
5+
using RestSharp;
6+
7+
namespace Mastercard.Developer.OAuth1Signer.Tests.NetCore.Signers
8+
{
9+
[TestClass]
10+
public class RestSharpV2SignerTest
11+
{
12+
[TestMethod]
13+
public void TestSign_ShouldAddOAuth1HeaderToPostRequest()
14+
{
15+
// GIVEN
16+
var signingKey = TestUtils.GetTestSigningKey();
17+
const string consumerKey = "Some key";
18+
var baseUri = new Uri("https://api.mastercard.com/");
19+
var request = new RestRequest
20+
{
21+
Method = Method.POST,
22+
Resource = "/service/{param1}",
23+
Parameters =
24+
{
25+
new Parameter("param1", "value", ParameterType.UrlSegment),
26+
new Parameter("param2", "with spaces", ParameterType.QueryString),
27+
new Parameter("param3", "encoded#symbol", ParameterType.QueryString),
28+
new Parameter("param4", "{\"foo\":\"bår\"}", ParameterType.RequestBody)
29+
}
30+
};
31+
32+
// WHEN
33+
var instanceUnderTest = new RestSharpSigner(consumerKey, signingKey);
34+
instanceUnderTest.Sign(baseUri, request);
35+
36+
// THEN
37+
var authorizationHeaders = request.Parameters.FindAll(param => param.Name == "Authorization" && param.Type == ParameterType.HttpHeader);
38+
var authorizationHeaderValue = authorizationHeaders[0].Value as string;
39+
Assert.IsNotNull(authorizationHeaderValue);
40+
}
41+
42+
[TestMethod]
43+
public void TestSign_ShouldAddOAuth1HeaderToGetRequest_WhenParameterNameIsNull()
44+
{
45+
// GIVEN
46+
var signingKey = TestUtils.GetTestSigningKey();
47+
const string consumerKey = "Some key";
48+
var baseUri = new Uri("https://api.mastercard.com/");
49+
var param1 = new Parameter("name", "value", ParameterType.QueryString);
50+
param1.Name = null;
51+
var request = new RestRequest
52+
{
53+
Method = Method.GET,
54+
Resource = "/service/{param1}",
55+
Parameters =
56+
{
57+
param1
58+
}
59+
};
60+
61+
// WHEN
62+
var instanceUnderTest = new RestSharpSigner(consumerKey, signingKey);
63+
Assert.ThrowsException<InvalidOperationException>(() => instanceUnderTest.Sign(baseUri, request));
64+
}
65+
66+
[TestMethod]
67+
public void TestSign_ShouldAddOAuth1HeaderToGetRequest_WhenParameterValueIsNull()
68+
{
69+
// GIVEN
70+
var signingKey = TestUtils.GetTestSigningKey();
71+
const string consumerKey = "Some key";
72+
var baseUri = new Uri("https://api.mastercard.com/");
73+
var param1 = new Parameter("name", "value", ParameterType.QueryString);
74+
param1.Value = null;
75+
var request = new RestRequest
76+
{
77+
Method = Method.GET,
78+
Resource = "/service/{param1}",
79+
Parameters =
80+
{
81+
param1
82+
}
83+
};
84+
85+
// WHEN
86+
var instanceUnderTest = new RestSharpSigner(consumerKey, signingKey);
87+
Assert.ThrowsException<InvalidOperationException>(() => instanceUnderTest.Sign(baseUri, request));
88+
}
89+
90+
[TestMethod]
91+
public void TestSign_ShouldAddOAuth1HeaderToGetRequest()
92+
{
93+
// GIVEN
94+
var signingKey = TestUtils.GetTestSigningKey();
95+
const string consumerKey = "Some key";
96+
var baseUri = new Uri("https://api.mastercard.com/");
97+
var request = new RestRequest
98+
{
99+
Method = Method.GET,
100+
Resource = "/service"
101+
};
102+
103+
// WHEN
104+
var instanceUnderTest = new RestSharpSigner(consumerKey, signingKey);
105+
instanceUnderTest.Sign(baseUri, request);
106+
107+
// THEN
108+
var authorizationHeaders = request.Parameters.FindAll(param => param.Name == "Authorization" && param.Type == ParameterType.HttpHeader);
109+
var authorizationHeaderValue = authorizationHeaders[0].Value as string;
110+
Assert.IsNotNull(authorizationHeaderValue);
111+
}
112+
}
113+
}

0 commit comments

Comments
 (0)