-
Notifications
You must be signed in to change notification settings - Fork 464
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Added ctor accepting inner factory (#437)
* Added ctor accepting inner factory * Added tests * Bumped version to 10.0.0-beta9
- Loading branch information
1 parent
0381094
commit e59150f
Showing
6 changed files
with
251 additions
and
102 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,34 +1,56 @@ | ||
using System; | ||
|
||
namespace JWT.Algorithms | ||
{ | ||
/// <summary> | ||
/// Implements <see href="IAlgorithmFactory" /> by returning the supplied <see href="IJwtAlgorithm" /> while ignoring parameters. | ||
/// </summary> | ||
public sealed class DelegateAlgorithmFactory : IAlgorithmFactory | ||
{ | ||
private readonly Func<IJwtAlgorithm> _algFactory; | ||
|
||
/// <summary> | ||
/// Creates an instance of <see cref="DelegateAlgorithmFactory" /> with supplied delegate to an algorithm. | ||
/// </summary> | ||
/// <exception cref="ArgumentNullException" /> | ||
public DelegateAlgorithmFactory(Func<IJwtAlgorithm> algFactory) => | ||
_algFactory = algFactory ?? throw new ArgumentNullException(nameof(algFactory)); | ||
|
||
/// <summary> | ||
/// Creates an instance of <see cref="DelegateAlgorithmFactory" /> with supplied algorithm. | ||
/// </summary> | ||
/// <exception cref="ArgumentNullException" /> | ||
public DelegateAlgorithmFactory(IJwtAlgorithm algorithm) : | ||
this(() => algorithm) | ||
{ | ||
if (algorithm is null) | ||
throw new ArgumentNullException(nameof(algorithm)); | ||
} | ||
|
||
/// <inheritdoc /> | ||
public IJwtAlgorithm Create(JwtDecoderContext context) => | ||
_algFactory(); | ||
} | ||
} | ||
using System; | ||
|
||
namespace JWT.Algorithms | ||
{ | ||
/// <summary> | ||
/// Implements <see href="IAlgorithmFactory" /> by returning the supplied <see href="IJwtAlgorithm" /> while ignoring parameters. | ||
/// </summary> | ||
public sealed class DelegateAlgorithmFactory : IAlgorithmFactory | ||
{ | ||
private readonly Func<JwtDecoderContext, IJwtAlgorithm> _algFactory; | ||
|
||
/// <summary> | ||
/// Creates an instance of <see cref="DelegateAlgorithmFactory" /> with supplied delegate to an algorithm with a context. | ||
/// </summary> | ||
/// <exception cref="ArgumentNullException" /> | ||
public DelegateAlgorithmFactory(Func<JwtDecoderContext, IJwtAlgorithm> algFactory) => | ||
_algFactory = algFactory ?? throw new ArgumentNullException(nameof(algFactory)); | ||
|
||
/// <summary> | ||
/// Creates an instance of <see cref="DelegateAlgorithmFactory" /> with supplied delegate to an algorithm. | ||
/// </summary> | ||
/// <exception cref="ArgumentNullException" /> | ||
public DelegateAlgorithmFactory(Func<IJwtAlgorithm> algFactory) | ||
: this(_ => algFactory()) | ||
{ | ||
if (algFactory is null) | ||
throw new ArgumentNullException(nameof(algFactory)); | ||
} | ||
|
||
/// <summary> | ||
/// Creates an instance of <see cref="DelegateAlgorithmFactory" /> with supplied algorithm factory. | ||
/// </summary> | ||
/// <exception cref="ArgumentNullException" /> | ||
public DelegateAlgorithmFactory(IAlgorithmFactory algFactory) : | ||
this(c => algFactory?.Create(c)) | ||
{ | ||
if (algFactory is null) | ||
throw new ArgumentNullException(nameof(algFactory)); | ||
} | ||
|
||
/// <summary> | ||
/// Creates an instance of <see cref="DelegateAlgorithmFactory" /> with supplied algorithm. | ||
/// </summary> | ||
/// <exception cref="ArgumentNullException" /> | ||
public DelegateAlgorithmFactory(IJwtAlgorithm algorithm) : | ||
this(() => algorithm) | ||
{ | ||
if (algorithm is null) | ||
throw new ArgumentNullException(nameof(algorithm)); | ||
} | ||
|
||
/// <inheritdoc /> | ||
public IJwtAlgorithm Create(JwtDecoderContext context) => | ||
_algFactory(context); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,70 +1,70 @@ | ||
using System.Security.Cryptography; | ||
using System.Security.Cryptography.X509Certificates; | ||
|
||
namespace JWT.Algorithms | ||
{ | ||
/// <summary> | ||
/// RSASSA-PKCS1-v1_5 using SHA-256 | ||
/// </summary> | ||
public abstract class RSAlgorithm : CertificateAlgorithm<RSA> | ||
{ | ||
/// <summary> | ||
/// Creates an instance of <see cref="RSAlgorithm" /> using the provided pair of public and private keys. | ||
/// </summary> | ||
/// <param name="publicKey">The public key for verifying the data.</param> | ||
/// <param name="privateKey">The private key for signing the data.</param> | ||
protected RSAlgorithm(RSA publicKey, RSA privateKey) | ||
: base(publicKey, privateKey) | ||
{ | ||
} | ||
|
||
/// <summary> | ||
/// Creates an instance of <see cref="RSAlgorithm" /> using the provided public key only. | ||
/// </summary> | ||
/// <remarks> | ||
/// An instance created using this constructor can only be used for verifying the data, not for signing it. | ||
/// </remarks> | ||
/// <param name="publicKey">The public key for verifying the data.</param> | ||
protected RSAlgorithm(RSA publicKey) | ||
: base(publicKey) | ||
{ | ||
} | ||
|
||
/// <summary> | ||
/// Creates an instance using the provided certificate. | ||
/// </summary> | ||
/// <param name="cert">The certificate having a public key and an optional private key.</param> | ||
protected RSAlgorithm(X509Certificate2 cert) | ||
: base(cert) | ||
{ | ||
using System.Security.Cryptography; | ||
using System.Security.Cryptography.X509Certificates; | ||
|
||
namespace JWT.Algorithms | ||
{ | ||
/// <summary> | ||
/// RSASSA-PKCS1-v1_5 using SHA-256 | ||
/// </summary> | ||
public abstract class RSAlgorithm : CertificateAlgorithm<RSA> | ||
{ | ||
/// <summary> | ||
/// Creates an instance of <see cref="RSAlgorithm" /> using the provided pair of public and private keys. | ||
/// </summary> | ||
/// <param name="publicKey">The public key for verifying the data.</param> | ||
/// <param name="privateKey">The private key for signing the data.</param> | ||
protected RSAlgorithm(RSA publicKey, RSA privateKey) | ||
: base(publicKey, privateKey) | ||
{ | ||
} | ||
|
||
/// <summary> | ||
/// Creates an instance of <see cref="RSAlgorithm" /> using the provided public key only. | ||
/// </summary> | ||
/// <remarks> | ||
/// An instance created using this constructor can only be used for verifying the data, not for signing it. | ||
/// </remarks> | ||
/// <param name="publicKey">The public key for verifying the data.</param> | ||
protected RSAlgorithm(RSA publicKey) | ||
: base(publicKey) | ||
{ | ||
} | ||
|
||
/// <summary> | ||
/// Creates an instance using the provided certificate. | ||
/// </summary> | ||
/// <param name="cert">The certificate having a public key and an optional private key.</param> | ||
protected RSAlgorithm(X509Certificate2 cert) | ||
: base(cert) | ||
{ | ||
} | ||
|
||
protected override RSA GetPublicKey(X509Certificate2 cert) => | ||
#if NETSTANDARD || NETCOREAPP || NET462 | ||
cert.GetRSAPublicKey(); | ||
#else | ||
(RSA)cert.PublicKey.Key; | ||
#endif | ||
|
||
protected override RSA GetPrivateKey(X509Certificate2 cert) => | ||
#if NETSTANDARD || NETCOREAPP || NET462 | ||
protected override RSA GetPublicKey(X509Certificate2 cert) => | ||
#if NETSTANDARD || NETCOREAPP || NET462 | ||
cert.GetRSAPublicKey(); | ||
#else | ||
(RSA)cert.PublicKey.Key; | ||
#endif | ||
|
||
protected override RSA GetPrivateKey(X509Certificate2 cert) => | ||
#if NETSTANDARD || NETCOREAPP || NET462 | ||
cert.GetRSAPrivateKey(); | ||
#else | ||
(RSA)cert.PrivateKey; | ||
#endif | ||
|
||
protected override byte[] SignData(byte[] bytesToSign) => | ||
#if NET35 || NET40 | ||
((RSACryptoServiceProvider)_privateKey).SignData(bytesToSign, this.HashAlgorithmName.Name); | ||
#else | ||
#else | ||
(RSA)cert.PrivateKey; | ||
#endif | ||
|
||
protected override byte[] SignData(byte[] bytesToSign) => | ||
#if NET35 || NET40 | ||
((RSACryptoServiceProvider)_privateKey).SignData(bytesToSign, this.HashAlgorithmName.Name); | ||
#else | ||
_privateKey.SignData(bytesToSign, this.HashAlgorithmName, RSASignaturePadding.Pkcs1); | ||
#endif | ||
|
||
protected override bool VerifyData(byte[] bytesToSign, byte[] signature) => | ||
#if NET35 || NET40 | ||
((RSACryptoServiceProvider)_publicKey).VerifyData(bytesToSign, this.HashAlgorithmName.Name, signature); | ||
#else | ||
_publicKey.VerifyData(bytesToSign, signature, this.HashAlgorithmName, RSASignaturePadding.Pkcs1); | ||
#endif | ||
} | ||
} | ||
#endif | ||
|
||
protected override bool VerifyData(byte[] bytesToSign, byte[] signature) => | ||
#if NET35 || NET40 | ||
((RSACryptoServiceProvider)_publicKey).VerifyData(bytesToSign, this.HashAlgorithmName.Name, signature); | ||
#else | ||
_publicKey.VerifyData(bytesToSign, signature, this.HashAlgorithmName, RSASignaturePadding.Pkcs1); | ||
#endif | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
65 changes: 65 additions & 0 deletions
65
tests/JWT.Tests.Common/Algorithms/DelegateAlgorithmFactoryTests.cs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,65 @@ | ||
using System; | ||
using FluentAssertions; | ||
using JWT.Algorithms; | ||
using Microsoft.VisualStudio.TestTools.UnitTesting; | ||
using Moq; | ||
|
||
namespace JWT.Tests.Algorithms | ||
{ | ||
[TestClass] | ||
public class DelegateAlgorithmFactoryTests | ||
{ | ||
[TestMethod] | ||
public void Ctor_Accepting_Func_IJwtAlgorithm_Should_Throw_When_Param_Is_Null() | ||
{ | ||
Action action = () => new DelegateAlgorithmFactory((Func<IJwtAlgorithm>)null); | ||
|
||
action.Should() | ||
.Throw<ArgumentNullException>(); | ||
} | ||
|
||
[TestMethod] | ||
public void Ctor_Accepting_Func_JwtDecoderContext_IJwtAlgorithm_Should_Throw_When_Param_Is_Null() | ||
{ | ||
Action action = () => new DelegateAlgorithmFactory((Func<JwtDecoderContext, IJwtAlgorithm>)null); | ||
|
||
action.Should() | ||
.Throw<ArgumentNullException>(); | ||
} | ||
|
||
[TestMethod] | ||
public void Ctor_Accepting_IAlgorithmFactory_Should_Throw_When_Param_Is_Null() | ||
{ | ||
Action action = () => new DelegateAlgorithmFactory((IAlgorithmFactory)null); | ||
|
||
action.Should() | ||
.Throw<ArgumentNullException>(); | ||
} | ||
|
||
[TestMethod] | ||
public void Ctor_Accepting_IAlgorithm_Should_Throw_When_Param_Is_Null() | ||
{ | ||
Action action = () => new DelegateAlgorithmFactory((IJwtAlgorithm)null); | ||
|
||
action.Should() | ||
.Throw<ArgumentNullException>(); | ||
} | ||
|
||
[TestMethod] | ||
public void Create_Should_Return_Algorithm_Returned_By_Inner_Factory() | ||
{ | ||
var expected = Mock.Of<IJwtAlgorithm>(); | ||
|
||
var context = new JwtDecoderContext(); | ||
var innerFactory = new Mock<IAlgorithmFactory>(); | ||
innerFactory.Setup(f => f.Create(context)).Returns(expected); | ||
|
||
var delFactory = new DelegateAlgorithmFactory(innerFactory.Object); | ||
var actual = delFactory.Create(context); | ||
|
||
actual.Should().Be(expected); | ||
|
||
innerFactory.VerifyAll(); | ||
} | ||
} | ||
} |
50 changes: 50 additions & 0 deletions
50
tests/JWT.Tests.Common/Serializers/DelegateJsonSerializerFactoryTests.cs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,50 @@ | ||
using System; | ||
using FluentAssertions; | ||
using JWT.Serializers; | ||
using Microsoft.VisualStudio.TestTools.UnitTesting; | ||
using Moq; | ||
|
||
namespace JWT.Tests.Algorithms | ||
{ | ||
[TestClass] | ||
public class DelegateJsonSerializerFactoryTests | ||
{ | ||
[TestMethod] | ||
public void Ctor_Accepting_JsonSerializer_Should_Throw_When_Param_Is_Null() | ||
{ | ||
Action action = () => new DelegateJsonSerializerFactory((IJsonSerializer)null); | ||
|
||
action.Should() | ||
.Throw<ArgumentNullException>(); | ||
} | ||
|
||
[TestMethod] | ||
public void Ctor_Accepting_Factory_Should_Throw_When_Param_Is_Null() | ||
{ | ||
Action action = () => new DelegateJsonSerializerFactory((IJsonSerializerFactory)null); | ||
|
||
action.Should() | ||
.Throw<ArgumentNullException>(); | ||
} | ||
|
||
[TestMethod] | ||
public void Ctor_Accepting_Func_Should_Throw_When_Param_Is_Null() | ||
{ | ||
Action action = () => new DelegateJsonSerializerFactory((Func<IJsonSerializer>)null); | ||
|
||
action.Should() | ||
.Throw<ArgumentNullException>(); | ||
} | ||
|
||
[TestMethod] | ||
public void Create_Should_Return_JsonSerializer_Returned_By_Inner_Factory() | ||
{ | ||
var expected = Mock.Of<IJsonSerializer>(); | ||
|
||
var delFactory = new DelegateJsonSerializerFactory(() => expected); | ||
var actual = delFactory.Create(); | ||
|
||
actual.Should().Be(expected); | ||
} | ||
} | ||
} |