From 4862eb62c957975376d85f1929f67ab563714aed Mon Sep 17 00:00:00 2001 From: AnaCoda Date: Fri, 7 Jul 2023 09:10:59 -0600 Subject: [PATCH 01/25] Add ID2LHttpClient, [GenerateSync], and other required --- .../Keys/Default/Data/IJwksProvider.cs | 7 +- .../Keys/Default/Data/JwksProvider.cs | 23 ++++-- .../Keys/Default/IPublicKeyProvider.cs | 7 +- .../Keys/Default/LocalPublicKeyProvider.cs | 5 +- .../Keys/Default/RemotePublicKeyProvider.cs | 5 +- .../Utilities/D2LHttpClient.cs | 77 +++++++++++++++++++ .../Utilities/ID2LHttpClient.cs | 32 ++++++++ .../AccessTokens/AccessTokenValidator.cs | 5 +- .../AccessTokens/IAccessTokenValidator.cs | 7 +- .../Request/IRequestAuthenticator.cs | 3 + .../Request/RequestAuthenticator.cs | 7 +- 11 files changed, 160 insertions(+), 18 deletions(-) create mode 100644 src/D2L.Security.OAuth2/Utilities/D2LHttpClient.cs create mode 100644 src/D2L.Security.OAuth2/Utilities/ID2LHttpClient.cs diff --git a/src/D2L.Security.OAuth2/Keys/Default/Data/IJwksProvider.cs b/src/D2L.Security.OAuth2/Keys/Default/Data/IJwksProvider.cs index 8a86dfbe..cb549d88 100644 --- a/src/D2L.Security.OAuth2/Keys/Default/Data/IJwksProvider.cs +++ b/src/D2L.Security.OAuth2/Keys/Default/Data/IJwksProvider.cs @@ -1,8 +1,11 @@ -using System.Threading.Tasks; +using D2L.CodeStyle.Annotations; +using System.Threading.Tasks; namespace D2L.Security.OAuth2.Keys.Default.Data { - internal interface IJwksProvider { + internal partial interface IJwksProvider { + [GenerateSync] Task RequestJwksAsync(); + [GenerateSync] Task RequestJwkAsync( string keyId ); string Namespace { get; } } diff --git a/src/D2L.Security.OAuth2/Keys/Default/Data/JwksProvider.cs b/src/D2L.Security.OAuth2/Keys/Default/Data/JwksProvider.cs index bb5e62b2..fd61d5ed 100644 --- a/src/D2L.Security.OAuth2/Keys/Default/Data/JwksProvider.cs +++ b/src/D2L.Security.OAuth2/Keys/Default/Data/JwksProvider.cs @@ -1,19 +1,22 @@ using System; +using System.IO; using System.Net; using System.Net.Http; using System.Threading.Tasks; using System.Web; +using D2L.CodeStyle.Annotations; +using D2L.Security.OAuth2.Utilities; using D2L.Security.OAuth2.Validation.Exceptions; using D2L.Services; namespace D2L.Security.OAuth2.Keys.Default.Data { - internal sealed class JwksProvider : IJwksProvider { - private readonly HttpClient m_httpClient; + internal sealed partial class JwksProvider : IJwksProvider { + private readonly D2LHttpClient m_httpClient; private readonly Uri m_jwksEndpoint; private readonly Uri m_jwkEndpoint; public JwksProvider( - HttpClient httpClient, + D2LHttpClient httpClient, Uri jwksEndpoint, Uri jwkEndpoint ) { @@ -22,11 +25,15 @@ Uri jwkEndpoint m_jwkEndpoint = jwkEndpoint; } + [GenerateSync] async Task IJwksProvider.RequestJwksAsync() { try { using( HttpResponseMessage response = await m_httpClient.GetAsync( m_jwksEndpoint ).ConfigureAwait( false ) ) { response.EnsureSuccessStatusCode(); - string jsonResponse = await response.Content.ReadAsStringAsync().ConfigureAwait( false ); + var reader = new StreamReader(await response.Content.ReadAsStreamAsync().ConfigureAwait(false)); + string jsonResponse = await reader + .ReadToEndAsync() + .ConfigureAwait(false); var jwks = new JsonWebKeySet( jsonResponse, m_jwksEndpoint ); return jwks; } @@ -37,6 +44,7 @@ async Task IJwksProvider.RequestJwksAsync() { } } + [GenerateSync] async Task IJwksProvider.RequestJwkAsync( string keyId ) { var url = GetJwkEndpoint( m_jwkEndpoint, keyId ); if( url == null ) { @@ -61,9 +69,10 @@ async Task IJwksProvider.RequestJwkAsync( string keyId ) { res.EnsureSuccessStatusCode(); - string json = await res.Content - .ReadAsStringAsync() - .ConfigureAwait( false ); + var reader = new StreamReader(await res.Content.ReadAsStreamAsync().ConfigureAwait(false)); + string json = await reader + .ReadToEndAsync() + .ConfigureAwait(false); JsonWebKey jwk = JsonWebKey.FromJson( json ); return new JsonWebKeySet( jwk, url ); diff --git a/src/D2L.Security.OAuth2/Keys/Default/IPublicKeyProvider.cs b/src/D2L.Security.OAuth2/Keys/Default/IPublicKeyProvider.cs index b507be28..fdc7294c 100644 --- a/src/D2L.Security.OAuth2/Keys/Default/IPublicKeyProvider.cs +++ b/src/D2L.Security.OAuth2/Keys/Default/IPublicKeyProvider.cs @@ -1,4 +1,5 @@ -using System; +using D2L.CodeStyle.Annotations; +using System; using System.Threading.Tasks; namespace D2L.Security.OAuth2.Keys.Default { @@ -6,18 +7,20 @@ namespace D2L.Security.OAuth2.Keys.Default { /// /// An abstraction for fetching public keys /// - internal interface IPublicKeyProvider { + internal partial interface IPublicKeyProvider { /// /// Gets an individual by its /// /// The key id (kid) /// The or null if the key doesn't exist or has expired + [GenerateSync] Task GetByIdAsync( string id ); /// /// Perform steps to potentially make future key fetches faster. /// + [GenerateSync] Task PrefetchAsync(); } diff --git a/src/D2L.Security.OAuth2/Keys/Default/LocalPublicKeyProvider.cs b/src/D2L.Security.OAuth2/Keys/Default/LocalPublicKeyProvider.cs index 2adecdaa..87c0cdb0 100644 --- a/src/D2L.Security.OAuth2/Keys/Default/LocalPublicKeyProvider.cs +++ b/src/D2L.Security.OAuth2/Keys/Default/LocalPublicKeyProvider.cs @@ -1,12 +1,13 @@ using System; using System.Collections.Generic; using System.Threading.Tasks; +using D2L.CodeStyle.Annotations; using D2L.Security.OAuth2.Keys.Caching; using D2L.Security.OAuth2.Validation.Exceptions; using D2L.Services; namespace D2L.Security.OAuth2.Keys.Default { - internal sealed class LocalPublicKeyProvider : IPublicKeyProvider { + internal sealed partial class LocalPublicKeyProvider : IPublicKeyProvider { private const string PUBLIC_KEY_SOURCE = "Local DB"; @@ -21,6 +22,7 @@ IInMemoryPublicKeyCache cache m_cache = cache ?? throw new ArgumentNullException( nameof( cache ) ); } + [GenerateSync] async Task IPublicKeyProvider.PrefetchAsync() { IEnumerable jwks = await m_publicKeyDataProvider .GetAllAsync() @@ -42,6 +44,7 @@ async Task IPublicKeyProvider.PrefetchAsync() { } } + [GenerateSync] async Task IPublicKeyProvider.GetByIdAsync( string id ) { D2LSecurityToken result = m_cache.Get( PUBLIC_KEY_SOURCE, id ); if( result != null ) { diff --git a/src/D2L.Security.OAuth2/Keys/Default/RemotePublicKeyProvider.cs b/src/D2L.Security.OAuth2/Keys/Default/RemotePublicKeyProvider.cs index fb818ed9..49ee1010 100644 --- a/src/D2L.Security.OAuth2/Keys/Default/RemotePublicKeyProvider.cs +++ b/src/D2L.Security.OAuth2/Keys/Default/RemotePublicKeyProvider.cs @@ -1,12 +1,13 @@ using System; using System.Threading.Tasks; +using D2L.CodeStyle.Annotations; using D2L.Security.OAuth2.Keys.Caching; using D2L.Security.OAuth2.Keys.Default.Data; using D2L.Security.OAuth2.Validation.Exceptions; using D2L.Services; namespace D2L.Security.OAuth2.Keys.Default { - internal sealed class RemotePublicKeyProvider : IPublicKeyProvider { + internal sealed partial class RemotePublicKeyProvider : IPublicKeyProvider { private readonly IJwksProvider m_jwksProvider; private readonly IInMemoryPublicKeyCache m_cache; @@ -18,6 +19,7 @@ IInMemoryPublicKeyCache cache m_cache = cache; } + [GenerateSync] async Task IPublicKeyProvider.GetByIdAsync( string id ) { D2LSecurityToken result = m_cache.Get( m_jwksProvider.Namespace, id ); if( result != null ) { @@ -38,6 +40,7 @@ async Task IPublicKeyProvider.GetByIdAsync( string id ) { throw new PublicKeyNotFoundException( id, jwks.Source.AbsoluteUri ); } + [GenerateSync] async Task IPublicKeyProvider.PrefetchAsync() { JsonWebKeySet jwks = await m_jwksProvider .RequestJwksAsync() diff --git a/src/D2L.Security.OAuth2/Utilities/D2LHttpClient.cs b/src/D2L.Security.OAuth2/Utilities/D2LHttpClient.cs new file mode 100644 index 00000000..d3303a1c --- /dev/null +++ b/src/D2L.Security.OAuth2/Utilities/D2LHttpClient.cs @@ -0,0 +1,77 @@ +using System; +using System.Net.Http; +using System.Threading; +using System.Threading.Tasks; + +namespace D2L.Security.OAuth2.Utilities +{ + internal class D2LHttpClient + { + /// + /// This class implements sync versions of HTTPClient methods. + /// TODO: Replace the sync methods which are currently using Task.Run(async verison); task.Wait(); + /// With (probably) HttpWebRequest + /// + private readonly HttpClient m_httpClient = new HttpClient(); + + public Task GetAsync(string requestUri, HttpCompletionOption completionOption, CancellationToken cancellationToken) + => m_httpClient.GetAsync(requestUri, completionOption, cancellationToken); + public Task GetAsync(Uri requestUri, CancellationToken cancellationToken) + => m_httpClient.GetAsync(requestUri, cancellationToken); + public Task GetAsync(Uri requestUri, HttpCompletionOption completionOption, CancellationToken cancellationToken) + => m_httpClient.GetAsync(requestUri, completionOption, cancellationToken); + public Task GetAsync(Uri requestUri, HttpCompletionOption completionOption) + => m_httpClient.GetAsync(requestUri, completionOption); + public Task GetAsync(string requestUri, HttpCompletionOption completionOption) + => m_httpClient.GetAsync(requestUri, completionOption); + public Task GetAsync(Uri requestUri) + => m_httpClient.GetAsync(requestUri); + public Task GetAsync(string requestUri) + => m_httpClient.GetAsync(requestUri); + public Task GetAsync(string requestUri, CancellationToken cancellationToken) + => m_httpClient.GetAsync(requestUri, cancellationToken); + +#pragma warning disable D2L0018 // Avoid using dangerous methods + public HttpResponseMessage Get(string requestUri, HttpCompletionOption completionOption, CancellationToken cancellationToken) { + var task = Task.Run(() => m_httpClient.GetAsync(requestUri, completionOption, cancellationToken)); + task.Wait(); + return task.Result; + } + public HttpResponseMessage Get(Uri requestUri, CancellationToken cancellationToken) { + var task = Task.Run(() => m_httpClient.GetAsync(requestUri, cancellationToken)); + task.Wait(); + return task.Result; + } + public HttpResponseMessage Get(Uri requestUri, HttpCompletionOption completionOption, CancellationToken cancellationToken) { + var task = Task.Run(() => m_httpClient.GetAsync(requestUri, completionOption, cancellationToken)); + task.Wait(); + return task.Result; + } + public HttpResponseMessage Get(Uri requestUri, HttpCompletionOption completionOption) { + var task = Task.Run(() => m_httpClient.GetAsync(requestUri, completionOption)); + task.Wait(); + return task.Result; + } + public HttpResponseMessage Get(string requestUri, HttpCompletionOption completionOption) { + var task = Task.Run(() => m_httpClient.GetAsync(requestUri, completionOption)); + task.Wait(); + return task.Result; + } + public HttpResponseMessage Get(Uri requestUri) { + var task = Task.Run(() => m_httpClient.GetAsync(requestUri)); + task.Wait(); + return task.Result; + } + public HttpResponseMessage Get(string requestUri) { + var task = Task.Run(() => m_httpClient.GetAsync(requestUri)); + task.Wait(); + return task.Result; + } + public HttpResponseMessage Get(string requestUri, CancellationToken cancellationToken) { + var task = Task.Run(() => m_httpClient.GetAsync(requestUri, cancellationToken)); + task.Wait(); + return task.Result; + } +#pragma warning restore D2L0018 // Avoid using dangerous methods + } +} diff --git a/src/D2L.Security.OAuth2/Utilities/ID2LHttpClient.cs b/src/D2L.Security.OAuth2/Utilities/ID2LHttpClient.cs new file mode 100644 index 00000000..0011c28c --- /dev/null +++ b/src/D2L.Security.OAuth2/Utilities/ID2LHttpClient.cs @@ -0,0 +1,32 @@ +using System; +using System.Net.Http; +using System.Threading; +using System.Threading.Tasks; + +namespace D2L.Security.OAuth2.Utilities +{ + internal interface ID2LHttpClient + { + /// + /// This interface was created to allow the sync generator in D2L.CodeStyle to strip the async suffix from HttpClient calls + /// when it tries to convert async code to sync code. + /// + public Task GetAsync(string requestUri, HttpCompletionOption completionOption, CancellationToken cancellationToken); + public Task GetAsync(Uri requestUri, CancellationToken cancellationToken); + public Task GetAsync(Uri requestUri, HttpCompletionOption completionOption, CancellationToken cancellationToken); + public Task GetAsync(Uri requestUri, HttpCompletionOption completionOption); + public Task GetAsync(string requestUri, HttpCompletionOption completionOption); + public Task GetAsync(Uri requestUri); + public Task GetAsync(string requestUri); + public Task GetAsync(string requestUri, CancellationToken cancellationToken); + + public Task Get(string requestUri, HttpCompletionOption completionOption, CancellationToken cancellationToken); + public Task Get(Uri requestUri, CancellationToken cancellationToken); + public Task Get(Uri requestUri, HttpCompletionOption completionOption, CancellationToken cancellationToken); + public Task Get(Uri requestUri, HttpCompletionOption completionOption); + public Task Get(string requestUri, HttpCompletionOption completionOption); + public Task Get(Uri requestUri); + public Task Get(string requestUri); + public Task Get(string requestUri, CancellationToken cancellationToken); + } +} diff --git a/src/D2L.Security.OAuth2/Validation/AccessTokens/AccessTokenValidator.cs b/src/D2L.Security.OAuth2/Validation/AccessTokens/AccessTokenValidator.cs index 22fb5b44..dcdf26f5 100644 --- a/src/D2L.Security.OAuth2/Validation/AccessTokens/AccessTokenValidator.cs +++ b/src/D2L.Security.OAuth2/Validation/AccessTokens/AccessTokenValidator.cs @@ -7,13 +7,14 @@ using D2L.Security.OAuth2.Keys.Default; using D2L.Security.OAuth2.Validation.Exceptions; using D2L.Services; +using D2L.CodeStyle.Annotations; #if DNXCORE50 using System.IdentityModel.Tokens.Jwt; #endif namespace D2L.Security.OAuth2.Validation.AccessTokens { - internal sealed class AccessTokenValidator : IAccessTokenValidator { + internal sealed partial class AccessTokenValidator : IAccessTokenValidator { internal static readonly ImmutableHashSet ALLOWED_SIGNATURE_ALGORITHMS = ImmutableHashSet.Create( SecurityAlgorithms.RsaSha256, SecurityAlgorithms.EcdsaSha256, @@ -33,8 +34,10 @@ IPublicKeyProvider publicKeyProvider m_publicKeyProvider = publicKeyProvider; } + [GenerateSync] Task IAccessTokenValidator.PrefetchAsync() => m_publicKeyProvider.PrefetchAsync(); + [GenerateSync] async Task IAccessTokenValidator.ValidateAsync( string token ) { diff --git a/src/D2L.Security.OAuth2/Validation/AccessTokens/IAccessTokenValidator.cs b/src/D2L.Security.OAuth2/Validation/AccessTokens/IAccessTokenValidator.cs index 3ff20247..4028be70 100644 --- a/src/D2L.Security.OAuth2/Validation/AccessTokens/IAccessTokenValidator.cs +++ b/src/D2L.Security.OAuth2/Validation/AccessTokens/IAccessTokenValidator.cs @@ -1,15 +1,17 @@ -using System.Threading.Tasks; +using D2L.CodeStyle.Annotations; +using System.Threading.Tasks; namespace D2L.Security.OAuth2.Validation.AccessTokens { /// /// An abstraction for validating access tokens /// - public interface IAccessTokenValidator { + public partial interface IAccessTokenValidator { /// /// Perform steps to potentially make future validations faster. /// + [GenerateSync] Task PrefetchAsync(); /// @@ -18,6 +20,7 @@ public interface IAccessTokenValidator { /// The raw token to validate /// A holding the decoded and validated access token /// Throws on error + [GenerateSync] Task ValidateAsync( string accessToken ); diff --git a/src/D2L.Security.OAuth2/Validation/Request/IRequestAuthenticator.cs b/src/D2L.Security.OAuth2/Validation/Request/IRequestAuthenticator.cs index bfce0d3f..866c292b 100644 --- a/src/D2L.Security.OAuth2/Validation/Request/IRequestAuthenticator.cs +++ b/src/D2L.Security.OAuth2/Validation/Request/IRequestAuthenticator.cs @@ -1,5 +1,6 @@ using System.Net.Http; using System.Threading.Tasks; +using D2L.CodeStyle.Annotations; using D2L.Security.OAuth2.Principal; namespace D2L.Security.OAuth2.Validation.Request { @@ -9,6 +10,7 @@ public partial interface IRequestAuthenticator { /// /// The web request object /// An for an authenticated user. + [GenerateSync] Task AuthenticateAsync( HttpRequestMessage request ); @@ -18,6 +20,7 @@ HttpRequestMessage request /// /// The bearer token. /// An for an authenticated user. + [GenerateSync] Task AuthenticateAsync( string bearerToken ); diff --git a/src/D2L.Security.OAuth2/Validation/Request/RequestAuthenticator.cs b/src/D2L.Security.OAuth2/Validation/Request/RequestAuthenticator.cs index 65676d03..1e7cb7d3 100644 --- a/src/D2L.Security.OAuth2/Validation/Request/RequestAuthenticator.cs +++ b/src/D2L.Security.OAuth2/Validation/Request/RequestAuthenticator.cs @@ -1,5 +1,6 @@ using System.Net.Http; using System.Threading.Tasks; +using D2L.CodeStyle.Annotations; using D2L.Security.OAuth2.Principal; using D2L.Security.OAuth2.Validation.AccessTokens; @@ -14,14 +15,16 @@ internal RequestAuthenticator( IAccessTokenValidator accessTokenValidator ) { m_accessTokenValidator = accessTokenValidator; } - Task IRequestAuthenticator.AuthenticateAsync( + [GenerateSync] + async Task IRequestAuthenticator.AuthenticateAsync( HttpRequestMessage request ) { string bearerToken = request.GetBearerTokenValue(); - return AuthenticateAsync( bearerToken ); + return await AuthenticateAsync( bearerToken ).ConfigureAwait(false); } + [GenerateSync] public async Task AuthenticateAsync( string bearerToken ) { From a657eb29fc9438916592c928629ed967197564be Mon Sep 17 00:00:00 2001 From: AnaCoda Date: Fri, 7 Jul 2023 10:28:51 -0600 Subject: [PATCH 02/25] Update Analyzers version --- Directory.Packages.props | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Directory.Packages.props b/Directory.Packages.props index a2ed1444..17894005 100644 --- a/Directory.Packages.props +++ b/Directory.Packages.props @@ -1,7 +1,7 @@  - + From c61ec63369904a1fd7a536778d807f3bc76df5e0 Mon Sep 17 00:00:00 2001 From: AnaCoda Date: Fri, 7 Jul 2023 13:06:01 -0600 Subject: [PATCH 03/25] More fixes and uses of D2LHttpClient --- .../TestAccessToken.cs | 3 +- .../TestAccessTokenProviderFactory.cs | 5 +- .../Default/ExpiringPublicKeyDataProvider.cs | 8 ++- .../InMemoryPublicKeyDataProvider.cs | 15 ++++-- .../Keys/IPublicKeyDataProvider.cs | 9 +++- .../AccessTokenProviderFactory.cs | 3 +- .../Provisioning/Default/AuthServiceClient.cs | 5 +- .../Utilities/D2LHttpClient.cs | 52 ++++++++++++++++++- .../Utilities/ID2LHttpClient.cs | 34 +++++++++--- .../AccessTokenValidatorFactory.cs | 3 +- .../Request/RequestAuthenticator.cs | 4 +- .../FullStackValidationBenchmark.cs | 5 +- .../Keys/Default/Data/JwksProviderTests.cs | 25 ++++----- .../TestAccessTokenProviderTests.cs | 7 +-- .../TestFramework/TestAccessTokenTests.cs | 7 +-- .../AccessTokenValidatorTests.EcDsa.cs | 5 +- .../AccessTokenValidatorTests.Rsa.cs | 3 +- .../AccessTokenProviderFactoryTests.cs | 5 +- .../Provisioning/AuthServiceClientTests.cs | 6 +-- .../Default/AuthServiceClientTests.cs | 7 +-- .../Utilities/MockHttpClient.cs | 8 +-- 21 files changed, 157 insertions(+), 62 deletions(-) diff --git a/src/D2L.Security.OAuth2.TestFramework/TestAccessToken.cs b/src/D2L.Security.OAuth2.TestFramework/TestAccessToken.cs index ab2dbb82..5b340e44 100644 --- a/src/D2L.Security.OAuth2.TestFramework/TestAccessToken.cs +++ b/src/D2L.Security.OAuth2.TestFramework/TestAccessToken.cs @@ -6,6 +6,7 @@ using System.Threading.Tasks; using D2L.Security.OAuth2.Provisioning; using D2L.Security.OAuth2.Scopes; +using D2L.Security.OAuth2.Utilities; using D2L.Services; using IAccessToken = D2L.Security.OAuth2.Provisioning.IAccessToken; @@ -31,7 +32,7 @@ public static async Task GetToken( string tokenProvisioningEndpoint, IEn claims.Add( new Claim( Constants.Claims.ISSUER, DEFAULT_ISSUER ) ); - using( var httpClient = new HttpClient() ) { + using( var httpClient = new D2LHttpClient() ) { IAccessTokenProvider provider = TestAccessTokenProviderFactory.Create( httpClient, tokenProvisioningEndpoint ); IAccessToken token = await provider.ProvisionAccessTokenAsync( claims, scopes ).ConfigureAwait( false ); return token.Token; diff --git a/src/D2L.Security.OAuth2.TestFramework/TestAccessTokenProviderFactory.cs b/src/D2L.Security.OAuth2.TestFramework/TestAccessTokenProviderFactory.cs index d23b8575..d8c94137 100644 --- a/src/D2L.Security.OAuth2.TestFramework/TestAccessTokenProviderFactory.cs +++ b/src/D2L.Security.OAuth2.TestFramework/TestAccessTokenProviderFactory.cs @@ -7,6 +7,7 @@ using D2L.Security.OAuth2.Keys.Development; using D2L.Security.OAuth2.Provisioning; using D2L.Security.OAuth2.Provisioning.Default; +using D2L.Security.OAuth2.Utilities; namespace D2L.Security.OAuth2.TestFramework { public static class TestAccessTokenProviderFactory { @@ -19,7 +20,7 @@ public static class TestAccessTokenProviderFactory { /// The httpClient that makes the request to the auth server /// The auth server /// An IAccessTokenProvider with test credentials - public static IAccessTokenProvider Create( HttpClient httpClient, String tokenProvisioningEndpoint ) { + public static IAccessTokenProvider Create( D2LHttpClient httpClient, String tokenProvisioningEndpoint ) { return Create( httpClient, tokenProvisioningEndpoint, TestKeyId, TestStaticKeyProvider.TestRSAParameters ); } @@ -31,7 +32,7 @@ public static IAccessTokenProvider Create( HttpClient httpClient, String tokenPr /// The id of the security token /// The public and private key for the supplied key id /// An IAccessTokenProvider with the supplied test credentials - public static IAccessTokenProvider Create( HttpClient httpClient, String tokenProvisioningEndpoint, string keyId, RSAParameters rsaParameters ) { + public static IAccessTokenProvider Create( D2LHttpClient httpClient, String tokenProvisioningEndpoint, string keyId, RSAParameters rsaParameters ) { #pragma warning disable 618 IPrivateKeyProvider privateKeyProvider = new StaticPrivateKeyProvider( keyId, rsaParameters ); #pragma warning restore 618 diff --git a/src/D2L.Security.OAuth2/Keys/Default/ExpiringPublicKeyDataProvider.cs b/src/D2L.Security.OAuth2/Keys/Default/ExpiringPublicKeyDataProvider.cs index 2051f34e..f86cedd5 100644 --- a/src/D2L.Security.OAuth2/Keys/Default/ExpiringPublicKeyDataProvider.cs +++ b/src/D2L.Security.OAuth2/Keys/Default/ExpiringPublicKeyDataProvider.cs @@ -2,11 +2,12 @@ using System.Collections.Generic; using System.Linq; using System.Threading.Tasks; +using D2L.CodeStyle.Annotations; using D2L.Security.OAuth2.Utilities; using D2L.Services; namespace D2L.Security.OAuth2.Keys.Default { - internal sealed class ExpiringPublicKeyDataProvider : ISanePublicKeyDataProvider { + internal sealed partial class ExpiringPublicKeyDataProvider : ISanePublicKeyDataProvider { private readonly IPublicKeyDataProvider m_inner; private readonly IDateTimeProvider m_dateTimeProvider; @@ -18,6 +19,7 @@ IDateTimeProvider dateTimeProvider m_dateTimeProvider = dateTimeProvider ?? throw new ArgumentException( nameof( dateTimeProvider ) ); } + [GenerateSync] async Task IPublicKeyDataProvider.GetByIdAsync( Guid id ) { // We are intentionally fetching *all* public keys from the database // here. This allows us to clean up all expired public keys even if @@ -44,6 +46,7 @@ async Task IPublicKeyDataProvider.GetByIdAsync( Guid id ) { return key; } + [GenerateSync] async Task> IPublicKeyDataProvider.GetAllAsync() { IEnumerable keys = await m_inner .GetAllAsync() @@ -62,14 +65,17 @@ async Task> IPublicKeyDataProvider.GetAllAsync() { return keys; } + [GenerateSync] Task IPublicKeyDataProvider.SaveAsync( Guid id, JsonWebKey key ) { return m_inner.SaveAsync( id, key ); } + [GenerateSync] Task IPublicKeyDataProvider.DeleteAsync( Guid id ) { return m_inner.DeleteAsync( id ); } + [GenerateSync] private async Task KeyExpirationHelper( JsonWebKey key ) { if( key == null ) { return null; diff --git a/src/D2L.Security.OAuth2/Keys/Development/InMemoryPublicKeyDataProvider.cs b/src/D2L.Security.OAuth2/Keys/Development/InMemoryPublicKeyDataProvider.cs index e38cd27d..7209e5ea 100644 --- a/src/D2L.Security.OAuth2/Keys/Development/InMemoryPublicKeyDataProvider.cs +++ b/src/D2L.Security.OAuth2/Keys/Development/InMemoryPublicKeyDataProvider.cs @@ -1,4 +1,5 @@ -using System; +using D2L.CodeStyle.Annotations; +using System; using System.Collections.Concurrent; using System.Collections.Generic; using System.Collections.ObjectModel; @@ -14,6 +15,7 @@ namespace D2L.Security.OAuth2.Keys.Development { public sealed class InMemoryPublicKeyDataProvider : IPublicKeyDataProvider { private readonly ConcurrentDictionary m_keys = new ConcurrentDictionary(); + [GenerateSync] Task IPublicKeyDataProvider.GetByIdAsync( Guid id ) { if( !m_keys.TryGetValue( id, out JsonWebKey key ) ) { return Task.FromResult( null ); @@ -21,6 +23,7 @@ Task IPublicKeyDataProvider.GetByIdAsync( Guid id ) { return Task.FromResult( key ); } + [GenerateSync] Task> IPublicKeyDataProvider.GetAllAsync() { IEnumerable result = new ReadOnlyCollection( m_keys.Values.ToList() ); @@ -28,16 +31,18 @@ Task> IPublicKeyDataProvider.GetAllAsync() { return Task.FromResult( result ); } - Task IPublicKeyDataProvider.SaveAsync( Guid id, JsonWebKey key ) { + [GenerateSync] + async Task IPublicKeyDataProvider.SaveAsync( Guid id, JsonWebKey key ) { if( !m_keys.TryAdd( id, key ) ) { throw new InvalidOperationException( "Attempted to add a key twice" ); } - return Task.CompletedTask; + await Task.CompletedTask.ConfigureAwait(false); } - Task IPublicKeyDataProvider.DeleteAsync( Guid id ) { + [GenerateSync] + async Task IPublicKeyDataProvider.DeleteAsync( Guid id ) { m_keys.TryRemove( id, out JsonWebKey removedKey ); - return Task.CompletedTask; + await Task.CompletedTask.ConfigureAwait(false); } } } diff --git a/src/D2L.Security.OAuth2/Keys/IPublicKeyDataProvider.cs b/src/D2L.Security.OAuth2/Keys/IPublicKeyDataProvider.cs index 90ea91be..a04c2eb2 100644 --- a/src/D2L.Security.OAuth2/Keys/IPublicKeyDataProvider.cs +++ b/src/D2L.Security.OAuth2/Keys/IPublicKeyDataProvider.cs @@ -1,4 +1,5 @@ -using System; +using D2L.CodeStyle.Annotations; +using System; using System.Collections.Generic; using System.Threading.Tasks; @@ -7,19 +8,21 @@ namespace D2L.Security.OAuth2.Keys { /// /// Data provider for public keys that belong to this service /// - public interface IPublicKeyDataProvider { + public partial interface IPublicKeyDataProvider { /// /// Gets an individual by its /// /// The key id (kid) /// The or null if the key doesn't exist or has expired + [GenerateSync] Task GetByIdAsync( Guid id ); /// /// Gets all the instances /// /// All keys which haven't expired + [GenerateSync] Task> GetAllAsync(); /// @@ -27,12 +30,14 @@ public interface IPublicKeyDataProvider { /// /// The key id (kid) of the key to save /// The key to save + [GenerateSync] Task SaveAsync( Guid id, JsonWebKey key ); /// /// Deletes a key by key (kid) /// /// The key id (kid) of the key to delete + [GenerateSync] Task DeleteAsync( Guid id ); } diff --git a/src/D2L.Security.OAuth2/Provisioning/AccessTokenProviderFactory.cs b/src/D2L.Security.OAuth2/Provisioning/AccessTokenProviderFactory.cs index 04aed488..dc62e3fd 100644 --- a/src/D2L.Security.OAuth2/Provisioning/AccessTokenProviderFactory.cs +++ b/src/D2L.Security.OAuth2/Provisioning/AccessTokenProviderFactory.cs @@ -2,6 +2,7 @@ using System.Net.Http; using D2L.Security.OAuth2.Keys; using D2L.Security.OAuth2.Provisioning.Default; +using D2L.Security.OAuth2.Utilities; namespace D2L.Security.OAuth2.Provisioning { @@ -16,7 +17,7 @@ public static class AccessTokenProviderFactory { /// A new public static IAccessTokenProvider Create( ITokenSigner tokenSigner, - HttpClient httpClient, + D2LHttpClient httpClient, Uri authEndpoint, TimeSpan tokenRefreshGracePeriod ) { diff --git a/src/D2L.Security.OAuth2/Provisioning/Default/AuthServiceClient.cs b/src/D2L.Security.OAuth2/Provisioning/Default/AuthServiceClient.cs index 8cf33be2..2ca912cf 100644 --- a/src/D2L.Security.OAuth2/Provisioning/Default/AuthServiceClient.cs +++ b/src/D2L.Security.OAuth2/Provisioning/Default/AuthServiceClient.cs @@ -6,6 +6,7 @@ using System.Text; using System.Threading.Tasks; using D2L.Security.OAuth2.Scopes; +using D2L.Security.OAuth2.Utilities; using D2L.Services.Core.Exceptions; #if NET6_0 @@ -39,7 +40,7 @@ internal sealed class AuthServiceClient : IAuthServiceClient { SERIALIZATION_ERROR_MESSAGE_PREFIX + "The Auth Service responded with: "; - private readonly HttpClient m_client; + private readonly D2LHttpClient m_client; private readonly Uri m_tokenProvisioningEndpoint; /// @@ -48,7 +49,7 @@ internal sealed class AuthServiceClient : IAuthServiceClient { /// An http client used to communicate with the auth service. /// The token provisioning endpoint on the auth service public AuthServiceClient( - HttpClient httpClient, + D2LHttpClient httpClient, Uri authEndpoint ) { if( httpClient == null ) { diff --git a/src/D2L.Security.OAuth2/Utilities/D2LHttpClient.cs b/src/D2L.Security.OAuth2/Utilities/D2LHttpClient.cs index d3303a1c..ad583a37 100644 --- a/src/D2L.Security.OAuth2/Utilities/D2LHttpClient.cs +++ b/src/D2L.Security.OAuth2/Utilities/D2LHttpClient.cs @@ -5,14 +5,24 @@ namespace D2L.Security.OAuth2.Utilities { - internal class D2LHttpClient + public class D2LHttpClient : ID2LHttpClient, IDisposable { /// /// This class implements sync versions of HTTPClient methods. /// TODO: Replace the sync methods which are currently using Task.Run(async verison); task.Wait(); /// With (probably) HttpWebRequest /// - private readonly HttpClient m_httpClient = new HttpClient(); + private readonly HttpClient m_httpClient; + + public D2LHttpClient() { + m_httpClient = new HttpClient(); + } + public D2LHttpClient(HttpMessageHandler handler) { + m_httpClient = new HttpClient(handler); + } + public D2LHttpClient(HttpMessageHandler handler, bool disposeHandler) { + m_httpClient = new HttpClient(handler, disposeHandler); + } public Task GetAsync(string requestUri, HttpCompletionOption completionOption, CancellationToken cancellationToken) => m_httpClient.GetAsync(requestUri, completionOption, cancellationToken); @@ -31,6 +41,18 @@ public Task GetAsync(string requestUri) public Task GetAsync(string requestUri, CancellationToken cancellationToken) => m_httpClient.GetAsync(requestUri, cancellationToken); + public Task SendAsync(HttpRequestMessage request) + => m_httpClient.SendAsync(request); + + public Task SendAsync(HttpRequestMessage request, CancellationToken cancellationToken) + => m_httpClient.SendAsync(request, cancellationToken); + + public Task SendAsync(HttpRequestMessage request, HttpCompletionOption completionOption) + => m_httpClient.SendAsync(request, completionOption); + + public Task SendAsync(HttpRequestMessage request, HttpCompletionOption completionOption, CancellationToken cancellationToken) + => m_httpClient.SendAsync(request, completionOption, cancellationToken); + #pragma warning disable D2L0018 // Avoid using dangerous methods public HttpResponseMessage Get(string requestUri, HttpCompletionOption completionOption, CancellationToken cancellationToken) { var task = Task.Run(() => m_httpClient.GetAsync(requestUri, completionOption, cancellationToken)); @@ -72,6 +94,32 @@ public HttpResponseMessage Get(string requestUri, CancellationToken cancellation task.Wait(); return task.Result; } + + public HttpResponseMessage Send(HttpRequestMessage request) { + var task = Task.Run(() => m_httpClient.SendAsync(request)); + task.Wait(); + return task.Result; + } + + public HttpResponseMessage Send(HttpRequestMessage request, CancellationToken cancellationToken) { + var task = Task.Run(() => m_httpClient.SendAsync(request, cancellationToken)); + task.Wait(); + return task.Result; + } + + public HttpResponseMessage Send(HttpRequestMessage request, HttpCompletionOption completionOption) { + var task = Task.Run(() => m_httpClient.SendAsync(request, completionOption)); + task.Wait(); + return task.Result; + } + + public HttpResponseMessage Send(HttpRequestMessage request, HttpCompletionOption completionOption, CancellationToken cancellationToken) { + var task = Task.Run(() => m_httpClient.SendAsync(request, completionOption, cancellationToken)); + task.Wait(); + return task.Result; + } #pragma warning restore D2L0018 // Avoid using dangerous methods + + public void Dispose() { m_httpClient.Dispose(); } } } diff --git a/src/D2L.Security.OAuth2/Utilities/ID2LHttpClient.cs b/src/D2L.Security.OAuth2/Utilities/ID2LHttpClient.cs index 0011c28c..7750a6ee 100644 --- a/src/D2L.Security.OAuth2/Utilities/ID2LHttpClient.cs +++ b/src/D2L.Security.OAuth2/Utilities/ID2LHttpClient.cs @@ -20,13 +20,31 @@ internal interface ID2LHttpClient public Task GetAsync(string requestUri); public Task GetAsync(string requestUri, CancellationToken cancellationToken); - public Task Get(string requestUri, HttpCompletionOption completionOption, CancellationToken cancellationToken); - public Task Get(Uri requestUri, CancellationToken cancellationToken); - public Task Get(Uri requestUri, HttpCompletionOption completionOption, CancellationToken cancellationToken); - public Task Get(Uri requestUri, HttpCompletionOption completionOption); - public Task Get(string requestUri, HttpCompletionOption completionOption); - public Task Get(Uri requestUri); - public Task Get(string requestUri); - public Task Get(string requestUri, CancellationToken cancellationToken); + public HttpResponseMessage Get(string requestUri, HttpCompletionOption completionOption, CancellationToken cancellationToken); + public HttpResponseMessage Get(Uri requestUri, CancellationToken cancellationToken); + public HttpResponseMessage Get(Uri requestUri, HttpCompletionOption completionOption, CancellationToken cancellationToken); + public HttpResponseMessage Get(Uri requestUri, HttpCompletionOption completionOption); + public HttpResponseMessage Get(string requestUri, HttpCompletionOption completionOption); + public HttpResponseMessage Get(Uri requestUri); + public HttpResponseMessage Get(string requestUri); + public HttpResponseMessage Get(string requestUri, CancellationToken cancellationToken); + + public Task SendAsync(HttpRequestMessage request); + + public Task SendAsync(HttpRequestMessage request, CancellationToken cancellationToken); + + public Task SendAsync(HttpRequestMessage request, HttpCompletionOption completionOption); + + public Task SendAsync(HttpRequestMessage request, HttpCompletionOption completionOption, CancellationToken cancellationToken); + + public HttpResponseMessage Send(HttpRequestMessage request); + + public HttpResponseMessage Send(HttpRequestMessage request, CancellationToken cancellationToken); + + public HttpResponseMessage Send(HttpRequestMessage request, HttpCompletionOption completionOption); + + public HttpResponseMessage Send(HttpRequestMessage request, HttpCompletionOption completionOption, CancellationToken cancellationToken); + + public void Dispose(); } } diff --git a/src/D2L.Security.OAuth2/Validation/AccessTokens/AccessTokenValidatorFactory.cs b/src/D2L.Security.OAuth2/Validation/AccessTokens/AccessTokenValidatorFactory.cs index 221b4b0f..28234804 100644 --- a/src/D2L.Security.OAuth2/Validation/AccessTokens/AccessTokenValidatorFactory.cs +++ b/src/D2L.Security.OAuth2/Validation/AccessTokens/AccessTokenValidatorFactory.cs @@ -4,6 +4,7 @@ using D2L.Security.OAuth2.Keys.Caching; using D2L.Security.OAuth2.Keys.Default; using D2L.Security.OAuth2.Keys.Default.Data; +using D2L.Security.OAuth2.Utilities; namespace D2L.Security.OAuth2.Validation.AccessTokens { @@ -37,7 +38,7 @@ IPublicKeyDataProvider publicKeyDataProvider /// The full URI of the remote JWK path /// A new public static IAccessTokenValidator CreateRemoteValidator( - HttpClient httpClient, + D2LHttpClient httpClient, Uri jwksEndpoint, Uri jwkEndpoint = null ) { diff --git a/src/D2L.Security.OAuth2/Validation/Request/RequestAuthenticator.cs b/src/D2L.Security.OAuth2/Validation/Request/RequestAuthenticator.cs index 1e7cb7d3..eb66bf91 100644 --- a/src/D2L.Security.OAuth2/Validation/Request/RequestAuthenticator.cs +++ b/src/D2L.Security.OAuth2/Validation/Request/RequestAuthenticator.cs @@ -16,12 +16,12 @@ internal RequestAuthenticator( IAccessTokenValidator accessTokenValidator ) { } [GenerateSync] - async Task IRequestAuthenticator.AuthenticateAsync( + Task IRequestAuthenticator.AuthenticateAsync( HttpRequestMessage request ) { string bearerToken = request.GetBearerTokenValue(); - return await AuthenticateAsync( bearerToken ).ConfigureAwait(false); + return AuthenticateAsync( bearerToken ); } [GenerateSync] diff --git a/test/D2L.Security.OAuth2.Benchmarks/FullStackValidation/FullStackValidationBenchmark.cs b/test/D2L.Security.OAuth2.Benchmarks/FullStackValidation/FullStackValidationBenchmark.cs index 03a128f7..551c10b2 100644 --- a/test/D2L.Security.OAuth2.Benchmarks/FullStackValidation/FullStackValidationBenchmark.cs +++ b/test/D2L.Security.OAuth2.Benchmarks/FullStackValidation/FullStackValidationBenchmark.cs @@ -4,6 +4,7 @@ using System.Net.Http; using D2L.Security.OAuth2.Keys; using D2L.Security.OAuth2.Keys.Development; +using D2L.Security.OAuth2.Utilities; using D2L.Security.OAuth2.Validation.AccessTokens; using Newtonsoft.Json; using RichardSzalay.MockHttp; @@ -11,7 +12,7 @@ namespace D2L.Security.OAuth2.Benchmarks.FullStackValidation { internal abstract class FullStackValidationBenchmark : IBenchmark { - private HttpClient m_httpClient; + private D2LHttpClient m_httpClient; void IDisposable.Dispose() { m_httpClient.Dispose(); @@ -36,7 +37,7 @@ Action IBenchmark.GetRunner() { private void SetUp( out Uri host, out string token, out string id ) { var mockHandler = new MockHttpMessageHandler(); - m_httpClient = new HttpClient( mockHandler ); + m_httpClient = new D2LHttpClient( mockHandler ); host = new Uri( "http://localhost/.well-known/jwks" ); diff --git a/test/D2L.Security.OAuth2.IntegrationTests/Keys/Default/Data/JwksProviderTests.cs b/test/D2L.Security.OAuth2.IntegrationTests/Keys/Default/Data/JwksProviderTests.cs index b2c9a9bf..e27daf61 100644 --- a/test/D2L.Security.OAuth2.IntegrationTests/Keys/Default/Data/JwksProviderTests.cs +++ b/test/D2L.Security.OAuth2.IntegrationTests/Keys/Default/Data/JwksProviderTests.cs @@ -2,6 +2,7 @@ using System.Net; using System.Net.Http; using System.Threading.Tasks; +using D2L.Security.OAuth2.Utilities; using D2L.Security.OAuth2.Validation.Exceptions; using NUnit.Framework; using RichardSzalay.MockHttp; @@ -71,7 +72,7 @@ private HttpMessageHandler SetupJwkServer( [TestCase( GOOD_PATH_ADDITIONAL_NUMBER )] public async Task RequestJwksAsync_SuccessCase( string goodPath ) { using( var handler = SetupJwkServer( out string host ) ) - using( HttpClient httpClient = new HttpClient( handler ) ) { + using( D2LHttpClient httpClient = new D2LHttpClient( handler ) ) { IJwksProvider publicKeyProvider = new JwksProvider( httpClient, jwksEndpoint: new Uri( host + goodPath + JWKS_PATH ), @@ -91,7 +92,7 @@ public async Task RequestJwksAsync_SuccessCase( string goodPath ) { [Test] public void RequestJwksAsync_HTML_Throws() { using( var handler = SetupJwkServer( out string host ) ) - using( HttpClient httpClient = new HttpClient( handler ) ) { + using( D2LHttpClient httpClient = new D2LHttpClient( handler ) ) { IJwksProvider publicKeyProvider = new JwksProvider( httpClient, jwksEndpoint: new Uri( host + HTML_PATH ), @@ -111,7 +112,7 @@ public void RequestJwksAsync_HTML_Throws() { [Test] public void RequestJwksAsync_404_Throws() { using( var handler = SetupJwkServer( out string host ) ) - using( HttpClient httpClient = new HttpClient( handler ) ) { + using( D2LHttpClient httpClient = new D2LHttpClient( handler ) ) { IJwksProvider publicKeyProvider = new JwksProvider( httpClient, jwksEndpoint: new Uri( host + BAD_PATH ), @@ -129,7 +130,7 @@ public void RequestJwksAsync_404_Throws() { [Test] public void RequestJwksAsync_CantReachServer_Throws() { using( var handler = SetupJwkServer( out string host ) ) - using( HttpClient httpClient = new HttpClient( handler ) ) { + using( D2LHttpClient httpClient = new D2LHttpClient( handler ) ) { IJwksProvider publicKeyProvider = new JwksProvider( httpClient, jwksEndpoint: new Uri( "http://foo.bar.fakesite.isurehopethisisneveravalidTLD" ), @@ -147,7 +148,7 @@ public void RequestJwksAsync_CantReachServer_Throws() { [Test] public async Task RequestJwkAsync_Success() { using( var handler = SetupJwkServer( out string host, hasJwk: true, jwkStatusCode: HttpStatusCode.OK ) ) - using( HttpClient httpClient = new HttpClient( handler ) ) { + using( D2LHttpClient httpClient = new D2LHttpClient( handler ) ) { IJwksProvider jwksProvider = new JwksProvider( httpClient, jwksEndpoint: new Uri( host + GOOD_PATH + JWKS_PATH ), @@ -170,7 +171,7 @@ public async Task RequestJwkAsync_Success() { [Test] public async Task RequestJwkAsync_NullJwkEndpoint_Fallback_Success() { using( var handler = SetupJwkServer( out string host, hasJwk: true, jwkStatusCode: HttpStatusCode.OK ) ) - using( HttpClient httpClient = new HttpClient( handler ) ) { + using( D2LHttpClient httpClient = new D2LHttpClient( handler ) ) { IJwksProvider jwksProvider = new JwksProvider( httpClient, jwksEndpoint: new Uri( host + GOOD_PATH + JWKS_PATH ), @@ -193,7 +194,7 @@ public async Task RequestJwkAsync_NullJwkEndpoint_Fallback_Success() { [Test] public async Task RequestJwkAsync_StringKeyId_Success() { using( var handler = SetupJwkServer( out string host, hasJwk: true, jwkStatusCode: HttpStatusCode.OK ) ) - using( HttpClient httpClient = new HttpClient( handler ) ) { + using( D2LHttpClient httpClient = new D2LHttpClient( handler ) ) { IJwksProvider jwksProvider = new JwksProvider( httpClient, jwksEndpoint: new Uri( host + GOOD_PATH + JWKS_PATH ), @@ -216,7 +217,7 @@ public async Task RequestJwkAsync_StringKeyId_Success() { [Test] public async Task RequestJwkAsync_StringKeyId_InvalidKeyId_Fallback_DoesNotReturnKey() { using( var handler = SetupJwkServer( out string host, hasJwk: true, jwkStatusCode: HttpStatusCode.OK ) ) - using( HttpClient httpClient = new HttpClient( handler ) ) { + using( D2LHttpClient httpClient = new D2LHttpClient( handler ) ) { IJwksProvider jwksProvider = new JwksProvider( httpClient, jwksEndpoint: new Uri( host + GOOD_PATH + JWKS_PATH ), @@ -238,7 +239,7 @@ public async Task RequestJwkAsync_StringKeyId_InvalidKeyId_Fallback_DoesNotRetur [Test] public async Task RequestJwkAsync_404_Fallback_Success() { using( var handler = SetupJwkServer( out string host, hasJwk: false, jwkStatusCode: HttpStatusCode.NotFound ) ) - using( HttpClient httpClient = new HttpClient( handler ) ) { + using( D2LHttpClient httpClient = new D2LHttpClient( handler ) ) { IJwksProvider jwksProvider = new JwksProvider( httpClient, jwksEndpoint: new Uri( host + GOOD_PATH + JWKS_PATH ), @@ -261,7 +262,7 @@ public async Task RequestJwkAsync_404_Fallback_Success() { [Test] public async Task RequestJwkAsync_StringKeyId_404_Fallback_Success() { using( var handler = SetupJwkServer( out string host, hasJwk: false, jwkStatusCode: HttpStatusCode.NotFound ) ) - using( HttpClient httpClient = new HttpClient( handler ) ) { + using( D2LHttpClient httpClient = new D2LHttpClient( handler ) ) { IJwksProvider jwksProvider = new JwksProvider( httpClient, jwksEndpoint: new Uri( host + GOOD_PATH + JWKS_PATH ), @@ -284,7 +285,7 @@ public async Task RequestJwkAsync_StringKeyId_404_Fallback_Success() { [Test] public async Task RequestJwkAsync_500_Fallback_Success() { using( var handler = SetupJwkServer( out string host, hasJwk: false, jwkStatusCode: HttpStatusCode.InternalServerError ) ) - using( HttpClient httpClient = new HttpClient( handler ) ) { + using( D2LHttpClient httpClient = new D2LHttpClient( handler ) ) { IJwksProvider jwksProvider = new JwksProvider( httpClient, jwksEndpoint: new Uri( host + GOOD_PATH + JWKS_PATH ), @@ -307,7 +308,7 @@ public async Task RequestJwkAsync_500_Fallback_Success() { [Test] public async Task RequestJwkAsync_StringKeyId_500_Fallback_Success() { using( var handler = SetupJwkServer( out string host, hasJwk: false, jwkStatusCode: HttpStatusCode.InternalServerError ) ) - using( HttpClient httpClient = new HttpClient( handler ) ) { + using( D2LHttpClient httpClient = new D2LHttpClient( handler ) ) { IJwksProvider jwksProvider = new JwksProvider( httpClient, jwksEndpoint: new Uri( host + GOOD_PATH + JWKS_PATH ), diff --git a/test/D2L.Security.OAuth2.IntegrationTests/TestFramework/TestAccessTokenProviderTests.cs b/test/D2L.Security.OAuth2.IntegrationTests/TestFramework/TestAccessTokenProviderTests.cs index 9b9377b7..2fd62cd6 100644 --- a/test/D2L.Security.OAuth2.IntegrationTests/TestFramework/TestAccessTokenProviderTests.cs +++ b/test/D2L.Security.OAuth2.IntegrationTests/TestFramework/TestAccessTokenProviderTests.cs @@ -4,6 +4,7 @@ using System.Threading.Tasks; using D2L.Security.OAuth2.Provisioning; using D2L.Security.OAuth2.Scopes; +using D2L.Security.OAuth2.Utilities; using D2L.Security.OAuth2.Validation.AccessTokens; using NUnit.Framework; using IAccessToken = D2L.Security.OAuth2.Provisioning.IAccessToken; @@ -22,7 +23,7 @@ internal sealed class TestAccessTokenProviderTests { [Test] public async Task TestAccessTokenProvider_TokenIsValid() { - using( var httpClient = new HttpClient() ) { + using( var httpClient = new D2LHttpClient() ) { IAccessTokenProvider provider = TestAccessTokenProviderFactory.Create( httpClient, DEV_AUTH_URL ); IAccessToken token = await provider.ProvisionAccessTokenAsync( testClaimSet, testScopes ).ConfigureAwait( false ); @@ -33,7 +34,7 @@ public async Task TestAccessTokenProvider_TokenIsValid() { [Test] public async Task TestAccessTokenProvider_SuppliedRSAParameters_TokenIsValid() { - using( var httpClient = new HttpClient() ) { + using( var httpClient = new D2LHttpClient() ) { IAccessTokenProvider provider = TestAccessTokenProviderFactory.Create( httpClient, DEV_AUTH_URL, TestStaticKeyProvider.TestKeyId, TestStaticKeyProvider.TestRSAParameters ); IAccessToken token = await provider.ProvisionAccessTokenAsync( testClaimSet, testScopes ).ConfigureAwait( false ); @@ -46,7 +47,7 @@ public async Task TestAccessTokenProvider_SuppliedRSAParameters_TokenIsValid() { public void TestAccessTokenProvider_InvalidRSAParameters_TokenIsInvalid() { var randomRsaParameters = new RSACryptoServiceProvider( OAuth2.Keys.Constants.GENERATED_RSA_KEY_SIZE ) { PersistKeyInCsp = false }.ExportParameters( true ); - using( var httpClient = new HttpClient() ) { + using( var httpClient = new D2LHttpClient() ) { IAccessTokenProvider provider = TestAccessTokenProviderFactory.Create( httpClient, DEV_AUTH_URL, Guid.NewGuid().ToString(), randomRsaParameters ); Assert.ThrowsAsync( async () => await provider.ProvisionAccessTokenAsync( testClaimSet, testScopes ).ConfigureAwait( false ) ); } diff --git a/test/D2L.Security.OAuth2.IntegrationTests/TestFramework/TestAccessTokenTests.cs b/test/D2L.Security.OAuth2.IntegrationTests/TestFramework/TestAccessTokenTests.cs index a5604e8e..85bde0a7 100644 --- a/test/D2L.Security.OAuth2.IntegrationTests/TestFramework/TestAccessTokenTests.cs +++ b/test/D2L.Security.OAuth2.IntegrationTests/TestFramework/TestAccessTokenTests.cs @@ -3,6 +3,7 @@ using System.Security.Claims; using System.Threading.Tasks; using D2L.Security.OAuth2.Scopes; +using D2L.Security.OAuth2.Utilities; using D2L.Security.OAuth2.Validation.AccessTokens; using NUnit.Framework; @@ -17,7 +18,7 @@ internal sealed class TestAccessTokenTests { public async Task TestGetToken_WithTenantID_IsValid() { string token = await TestAccessToken.GetToken( DEV_AUTH_URL, Guid.NewGuid().ToString() ).ConfigureAwait( false ); - using( var httpClient = new HttpClient() ) { + using( var httpClient = new D2LHttpClient() ) { IAccessTokenValidator validator = AccessTokenValidatorFactory.CreateRemoteValidator( httpClient, new Uri( DEV_AUTH_URL ), new Uri( DEV_AUTH_JWK_URL ) ); Assert.DoesNotThrowAsync( async () => await validator.ValidateAsync( token ).ConfigureAwait( false ) ); } @@ -27,7 +28,7 @@ public async Task TestGetToken_WithTenantID_IsValid() { public async Task TestGetToken_WithTenantAndUserIdAndXsrf_IsValid() { string token = await TestAccessToken.GetToken( DEV_AUTH_URL, Guid.NewGuid().ToString(), "user", "xsrf" ).ConfigureAwait( false ); - using( var httpClient = new HttpClient() ) { + using( var httpClient = new D2LHttpClient() ) { IAccessTokenValidator validator = AccessTokenValidatorFactory.CreateRemoteValidator( httpClient, new Uri( DEV_AUTH_URL ), new Uri( DEV_AUTH_JWK_URL ) ); Assert.DoesNotThrowAsync( async () => await validator.ValidateAsync( token ).ConfigureAwait( false ) ); } @@ -40,7 +41,7 @@ public async Task TestGetToken_WithClaimAndScope_IsValid() { Scope[] scopes = { new Scope( "group", "resource", "permission" ) }; string token = await TestAccessToken.GetToken( DEV_AUTH_URL, claims, scopes ).ConfigureAwait( false ); - using( var httpClient = new HttpClient() ) { + using( var httpClient = new D2LHttpClient() ) { IAccessTokenValidator validator = AccessTokenValidatorFactory.CreateRemoteValidator( httpClient, new Uri( DEV_AUTH_URL ), new Uri( DEV_AUTH_JWK_URL ) ); Assert.DoesNotThrowAsync( async () => await validator.ValidateAsync( token ).ConfigureAwait( false ) ); } diff --git a/test/D2L.Security.OAuth2.IntegrationTests/Validation/AccessTokens/AccessTokenValidatorTests.EcDsa.cs b/test/D2L.Security.OAuth2.IntegrationTests/Validation/AccessTokens/AccessTokenValidatorTests.EcDsa.cs index 38dacb72..c1213f64 100644 --- a/test/D2L.Security.OAuth2.IntegrationTests/Validation/AccessTokens/AccessTokenValidatorTests.EcDsa.cs +++ b/test/D2L.Security.OAuth2.IntegrationTests/Validation/AccessTokens/AccessTokenValidatorTests.EcDsa.cs @@ -5,6 +5,7 @@ using System.Threading.Tasks; using D2L.Security.OAuth2.Keys; using D2L.Security.OAuth2.TestFramework; +using D2L.Security.OAuth2.Utilities; using D2L.Security.OAuth2.Validation.Exceptions; using NUnit.Framework; using RichardSzalay.MockHttp; @@ -20,7 +21,7 @@ internal sealed class EcDsa { public void TestFixtureSetUp() { m_authService = new AuthServiceMock( AuthServiceMock.KeyType.ECDSA_P256 ); m_accessTokenValidator = AccessTokenValidatorFactory.CreateRemoteValidator( - new HttpClient( m_authService.MockHandler ), + new D2LHttpClient( m_authService.MockHandler ), new Uri( m_authService.Host, ".well-known/jwks" ) ); @@ -119,7 +120,7 @@ public void ValidateAsync_GoodSignature_Succeeds_WebCrypto( string jwk, string t // The rest of the validation should have otherwise proceeded swimmingly Assert.Throws( () => AccessTokenValidatorFactory - .CreateRemoteValidator( new HttpClient( mockHandler ), new Uri( "http://localhost/.well-known/jwks" ) ) + .CreateRemoteValidator( new D2LHttpClient( mockHandler ), new Uri( "http://localhost/.well-known/jwks" ) ) .ValidateAsync( token ) .ConfigureAwait( false ).GetAwaiter().GetResult() ); diff --git a/test/D2L.Security.OAuth2.IntegrationTests/Validation/AccessTokens/AccessTokenValidatorTests.Rsa.cs b/test/D2L.Security.OAuth2.IntegrationTests/Validation/AccessTokens/AccessTokenValidatorTests.Rsa.cs index 7c03b846..7e24da1a 100644 --- a/test/D2L.Security.OAuth2.IntegrationTests/Validation/AccessTokens/AccessTokenValidatorTests.Rsa.cs +++ b/test/D2L.Security.OAuth2.IntegrationTests/Validation/AccessTokens/AccessTokenValidatorTests.Rsa.cs @@ -5,6 +5,7 @@ using System.Threading.Tasks; using D2L.Security.OAuth2.Keys; using D2L.Security.OAuth2.TestFramework; +using D2L.Security.OAuth2.Utilities; using D2L.Security.OAuth2.Validation.Exceptions; using NUnit.Framework; @@ -20,7 +21,7 @@ internal sealed class Rsa { public void TestFixtureSetUp() { m_authService = new AuthServiceMock(); m_accessTokenValidator = AccessTokenValidatorFactory.CreateRemoteValidator( - new HttpClient( m_authService.MockHandler ), + new D2LHttpClient( m_authService.MockHandler ), new Uri( m_authService.Host, ".well-known/jwks" ) ); diff --git a/test/D2L.Security.OAuth2.UnitTests/Provisioning/AccessTokenProviderFactoryTests.cs b/test/D2L.Security.OAuth2.UnitTests/Provisioning/AccessTokenProviderFactoryTests.cs index beeae241..41d44260 100644 --- a/test/D2L.Security.OAuth2.UnitTests/Provisioning/AccessTokenProviderFactoryTests.cs +++ b/test/D2L.Security.OAuth2.UnitTests/Provisioning/AccessTokenProviderFactoryTests.cs @@ -7,6 +7,7 @@ using D2L.Security.OAuth2.Keys; using D2L.Security.OAuth2.Provisioning.Default; using D2L.Security.OAuth2.Scopes; +using D2L.Security.OAuth2.Utilities; using Moq; using NUnit.Framework; @@ -29,7 +30,7 @@ public void Create_UserCacheProvided_UserCacheHit() { IAccessTokenProvider accessTokenProvider = AccessTokenProviderFactory.Create( tokenSigner: m_keyManagerMock.Object, - httpClient: new HttpClient(), + httpClient: new D2LHttpClient(), authEndpoint: new Uri( "http://foo.d2l" ), tokenRefreshGracePeriod: TimeSpan.FromMinutes( 2 ) ); @@ -50,7 +51,7 @@ public void Create_ServiceCacheProvided_ServiceCacheHit() { IAccessTokenProvider accessTokenProvider = AccessTokenProviderFactory.Create( tokenSigner: m_keyManagerMock.Object, - httpClient: new HttpClient(), + httpClient: new D2LHttpClient(), authEndpoint: new Uri( "http://foo.d2l" ), tokenRefreshGracePeriod: TimeSpan.FromMinutes( 2 ) ); diff --git a/test/D2L.Security.OAuth2.UnitTests/Provisioning/AuthServiceClientTests.cs b/test/D2L.Security.OAuth2.UnitTests/Provisioning/AuthServiceClientTests.cs index 415112af..ecf19ca5 100644 --- a/test/D2L.Security.OAuth2.UnitTests/Provisioning/AuthServiceClientTests.cs +++ b/test/D2L.Security.OAuth2.UnitTests/Provisioning/AuthServiceClientTests.cs @@ -122,7 +122,7 @@ await RunTest_ExpectSuccess( } private async Task RunTest_ExpectServiceException( - HttpClient mockClient, + D2LHttpClient mockClient, ServiceErrorType expectedErrorType, string expectedMessage = null ) { @@ -141,14 +141,14 @@ private async Task RunTest_ExpectServiceException( } private async Task RunTest_ExpectSuccess( - HttpClient mockClient, + D2LHttpClient mockClient, string expectedToken ) { IAccessToken token = await RunTestHelper( mockClient ); Assert.AreEqual( expectedToken, token.Token ); } - private async Task RunTestHelper( HttpClient mockClient ) { + private async Task RunTestHelper( D2LHttpClient mockClient ) { IAuthServiceClient client = new AuthServiceClient( httpClient: mockClient, authEndpoint: new Uri( TEST_URI ) diff --git a/test/D2L.Security.OAuth2.UnitTests/Provisioning/Default/AuthServiceClientTests.cs b/test/D2L.Security.OAuth2.UnitTests/Provisioning/Default/AuthServiceClientTests.cs index 8c7e1b6a..f20221e8 100644 --- a/test/D2L.Security.OAuth2.UnitTests/Provisioning/Default/AuthServiceClientTests.cs +++ b/test/D2L.Security.OAuth2.UnitTests/Provisioning/Default/AuthServiceClientTests.cs @@ -5,6 +5,7 @@ using System.Threading; using System.Threading.Tasks; using D2L.Security.OAuth2.Scopes; +using D2L.Security.OAuth2.Utilities; using D2L.Services; using Moq; using Moq.Protected; @@ -102,7 +103,7 @@ public async Task CorrectlyReadsResponse() { } } - private static HttpClient CreateMockedHttpClient( + private static D2LHttpClient CreateMockedHttpClient( Action requestBodyReceiver, HttpStatusCode responseStatus = HttpStatusCode.OK, string responseContent = TestData.ValidHttpResponseBody @@ -125,11 +126,11 @@ private static HttpClient CreateMockedHttpClient( } ); ; - var httpClient = new HttpClient( messageHandler.Object, true ); + var httpClient = new D2LHttpClient( messageHandler.Object, true ); return httpClient; } - private static IAuthServiceClient CreateClient( HttpClient httpClient ) { + private static IAuthServiceClient CreateClient( D2LHttpClient httpClient ) { var client = new AuthServiceClient( httpClient: httpClient, authEndpoint: new Uri( "http://foo.d2l" ) diff --git a/test/D2L.Security.OAuth2.UnitTests/Utilities/MockHttpClient.cs b/test/D2L.Security.OAuth2.UnitTests/Utilities/MockHttpClient.cs index cd3e7a0d..c8ad3630 100644 --- a/test/D2L.Security.OAuth2.UnitTests/Utilities/MockHttpClient.cs +++ b/test/D2L.Security.OAuth2.UnitTests/Utilities/MockHttpClient.cs @@ -24,7 +24,7 @@ internal static class MockHttpClient { /// The body of the response that the HttpClient should generate /// /// - public static HttpClient Create( + public static D2LHttpClient Create( HttpStatusCode responseStatus, string responseContent = null ) { @@ -33,7 +33,7 @@ public static HttpClient Create( response.Content = new StringContent( responseContent ); } - return new HttpClient( + return new D2LHttpClient( new MockResponseHandler( () => response ) ); } @@ -46,10 +46,10 @@ public static HttpClient Create( /// The exception the HttpClient should throw /// /// - public static HttpClient Create( + public static D2LHttpClient Create( Exception throwsException ) { - return new HttpClient( + return new D2LHttpClient( new MockResponseHandler( () => { throw throwsException; } ) ); } From f8007f425fac86369b33e3d7ad9bb9fb5f32051b Mon Sep 17 00:00:00 2001 From: AnaCoda Date: Fri, 7 Jul 2023 13:33:24 -0600 Subject: [PATCH 04/25] Edit test to match actual async SaveAsync --- .../Development/InMemoryPublicKeyDataProviderTests.cs | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/test/D2L.Security.OAuth2.UnitTests/Keys/Development/InMemoryPublicKeyDataProviderTests.cs b/test/D2L.Security.OAuth2.UnitTests/Keys/Development/InMemoryPublicKeyDataProviderTests.cs index 3313db57..c4ee55c4 100644 --- a/test/D2L.Security.OAuth2.UnitTests/Keys/Development/InMemoryPublicKeyDataProviderTests.cs +++ b/test/D2L.Security.OAuth2.UnitTests/Keys/Development/InMemoryPublicKeyDataProviderTests.cs @@ -94,7 +94,15 @@ public async Task SaveAsync_DoubleSave_ThrowsException() { var key = new JsonWebKeyStub( id.ToString() ); await m_publicKeyDataProvider.SaveAsync( id, key ).ConfigureAwait( false ); - Assert.Throws( () => m_publicKeyDataProvider.SaveAsync( id, key ).Wait() ); + try { + m_publicKeyDataProvider.SaveAsync(id, key).Wait(); + } + catch (AggregateException ae) { + Assert.AreEqual( + typeof(InvalidOperationException), ae.InnerException.GetType(), + "There was no InvalidOperationException." + ); + } } [Test] From 6b2e458e6c0b60e7522158332a6c6284f7f68b00 Mon Sep 17 00:00:00 2001 From: AnaCoda Date: Fri, 7 Jul 2023 13:38:16 -0600 Subject: [PATCH 05/25] asyncify uthenticateAsync(HttpRequestMessage) --- .../Validation/Request/RequestAuthenticator.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/D2L.Security.OAuth2/Validation/Request/RequestAuthenticator.cs b/src/D2L.Security.OAuth2/Validation/Request/RequestAuthenticator.cs index eb66bf91..1e7cb7d3 100644 --- a/src/D2L.Security.OAuth2/Validation/Request/RequestAuthenticator.cs +++ b/src/D2L.Security.OAuth2/Validation/Request/RequestAuthenticator.cs @@ -16,12 +16,12 @@ internal RequestAuthenticator( IAccessTokenValidator accessTokenValidator ) { } [GenerateSync] - Task IRequestAuthenticator.AuthenticateAsync( + async Task IRequestAuthenticator.AuthenticateAsync( HttpRequestMessage request ) { string bearerToken = request.GetBearerTokenValue(); - return AuthenticateAsync( bearerToken ); + return await AuthenticateAsync( bearerToken ).ConfigureAwait(false); } [GenerateSync] From 090ff7b00759967eb1df94529eab60252abb8d4b Mon Sep 17 00:00:00 2001 From: AnaCoda Date: Mon, 10 Jul 2023 09:02:36 -0600 Subject: [PATCH 06/25] Add using statements and asyncify InMemoryPublicKeyDataProvider --- .../Keys/Default/Data/JwksProvider.cs | 4 ++-- .../Development/InMemoryPublicKeyDataProvider.cs | 12 ++++++------ 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/src/D2L.Security.OAuth2/Keys/Default/Data/JwksProvider.cs b/src/D2L.Security.OAuth2/Keys/Default/Data/JwksProvider.cs index fd61d5ed..ca660ba5 100644 --- a/src/D2L.Security.OAuth2/Keys/Default/Data/JwksProvider.cs +++ b/src/D2L.Security.OAuth2/Keys/Default/Data/JwksProvider.cs @@ -30,7 +30,7 @@ async Task IJwksProvider.RequestJwksAsync() { try { using( HttpResponseMessage response = await m_httpClient.GetAsync( m_jwksEndpoint ).ConfigureAwait( false ) ) { response.EnsureSuccessStatusCode(); - var reader = new StreamReader(await response.Content.ReadAsStreamAsync().ConfigureAwait(false)); + using var reader = new StreamReader(await response.Content.ReadAsStreamAsync().ConfigureAwait(false)); string jsonResponse = await reader .ReadToEndAsync() .ConfigureAwait(false); @@ -69,7 +69,7 @@ async Task IJwksProvider.RequestJwkAsync( string keyId ) { res.EnsureSuccessStatusCode(); - var reader = new StreamReader(await res.Content.ReadAsStreamAsync().ConfigureAwait(false)); + using var reader = new StreamReader(await res.Content.ReadAsStreamAsync().ConfigureAwait(false)); string json = await reader .ReadToEndAsync() .ConfigureAwait(false); diff --git a/src/D2L.Security.OAuth2/Keys/Development/InMemoryPublicKeyDataProvider.cs b/src/D2L.Security.OAuth2/Keys/Development/InMemoryPublicKeyDataProvider.cs index 7209e5ea..a8decaaa 100644 --- a/src/D2L.Security.OAuth2/Keys/Development/InMemoryPublicKeyDataProvider.cs +++ b/src/D2L.Security.OAuth2/Keys/Development/InMemoryPublicKeyDataProvider.cs @@ -12,23 +12,23 @@ namespace D2L.Security.OAuth2.Keys.Development { /// A simple in-memory key data provider to be used only for testing and prototyping purposes. /// [Obsolete( "Only use this in tests and for prototyping without a db" )] - public sealed class InMemoryPublicKeyDataProvider : IPublicKeyDataProvider { + public sealed partial class InMemoryPublicKeyDataProvider : IPublicKeyDataProvider { private readonly ConcurrentDictionary m_keys = new ConcurrentDictionary(); [GenerateSync] - Task IPublicKeyDataProvider.GetByIdAsync( Guid id ) { + async Task IPublicKeyDataProvider.GetByIdAsync( Guid id ) { if( !m_keys.TryGetValue( id, out JsonWebKey key ) ) { - return Task.FromResult( null ); + return await Task.FromResult( null ).ConfigureAwait(false); } - return Task.FromResult( key ); + return await Task.FromResult(key).ConfigureAwait(false); } [GenerateSync] - Task> IPublicKeyDataProvider.GetAllAsync() { + async Task> IPublicKeyDataProvider.GetAllAsync() { IEnumerable result = new ReadOnlyCollection( m_keys.Values.ToList() ); - return Task.FromResult( result ); + return await Task.FromResult(result).ConfigureAwait(false); } [GenerateSync] From 417d8b881145df665fd8d3181eb0ee5e98844dd8 Mon Sep 17 00:00:00 2001 From: AnaCoda Date: Mon, 10 Jul 2023 09:23:17 -0600 Subject: [PATCH 07/25] Replace params and declaration ident with interface --- .../TestAccessTokenProviderFactory.cs | 4 ++-- .../Keys/Default/Data/JwksProvider.cs | 4 ++-- .../AccessTokenProviderFactory.cs | 2 +- .../Provisioning/Default/AuthServiceClient.cs | 4 ++-- .../Utilities/D2LHttpClient.cs | 2 +- .../Utilities/ID2LHttpClient.cs | 2 +- .../AccessTokenValidatorFactory.cs | 2 +- .../FullStackValidationBenchmark.cs | 2 +- .../Keys/Default/Data/JwksProviderTests.cs | 24 +++++++++---------- .../Provisioning/AuthServiceClientTests.cs | 6 ++--- .../Default/AuthServiceClientTests.cs | 4 ++-- .../Utilities/MockHttpClient.cs | 4 ++-- 12 files changed, 30 insertions(+), 30 deletions(-) diff --git a/src/D2L.Security.OAuth2.TestFramework/TestAccessTokenProviderFactory.cs b/src/D2L.Security.OAuth2.TestFramework/TestAccessTokenProviderFactory.cs index d8c94137..6da36128 100644 --- a/src/D2L.Security.OAuth2.TestFramework/TestAccessTokenProviderFactory.cs +++ b/src/D2L.Security.OAuth2.TestFramework/TestAccessTokenProviderFactory.cs @@ -20,7 +20,7 @@ public static class TestAccessTokenProviderFactory { /// The httpClient that makes the request to the auth server /// The auth server /// An IAccessTokenProvider with test credentials - public static IAccessTokenProvider Create( D2LHttpClient httpClient, String tokenProvisioningEndpoint ) { + public static IAccessTokenProvider Create( ID2LHttpClient httpClient, String tokenProvisioningEndpoint ) { return Create( httpClient, tokenProvisioningEndpoint, TestKeyId, TestStaticKeyProvider.TestRSAParameters ); } @@ -32,7 +32,7 @@ public static IAccessTokenProvider Create( D2LHttpClient httpClient, String toke /// The id of the security token /// The public and private key for the supplied key id /// An IAccessTokenProvider with the supplied test credentials - public static IAccessTokenProvider Create( D2LHttpClient httpClient, String tokenProvisioningEndpoint, string keyId, RSAParameters rsaParameters ) { + public static IAccessTokenProvider Create( ID2LHttpClient httpClient, String tokenProvisioningEndpoint, string keyId, RSAParameters rsaParameters ) { #pragma warning disable 618 IPrivateKeyProvider privateKeyProvider = new StaticPrivateKeyProvider( keyId, rsaParameters ); #pragma warning restore 618 diff --git a/src/D2L.Security.OAuth2/Keys/Default/Data/JwksProvider.cs b/src/D2L.Security.OAuth2/Keys/Default/Data/JwksProvider.cs index ca660ba5..6c48e436 100644 --- a/src/D2L.Security.OAuth2/Keys/Default/Data/JwksProvider.cs +++ b/src/D2L.Security.OAuth2/Keys/Default/Data/JwksProvider.cs @@ -11,12 +11,12 @@ namespace D2L.Security.OAuth2.Keys.Default.Data { internal sealed partial class JwksProvider : IJwksProvider { - private readonly D2LHttpClient m_httpClient; + private readonly ID2LHttpClient m_httpClient; private readonly Uri m_jwksEndpoint; private readonly Uri m_jwkEndpoint; public JwksProvider( - D2LHttpClient httpClient, + ID2LHttpClient httpClient, Uri jwksEndpoint, Uri jwkEndpoint ) { diff --git a/src/D2L.Security.OAuth2/Provisioning/AccessTokenProviderFactory.cs b/src/D2L.Security.OAuth2/Provisioning/AccessTokenProviderFactory.cs index dc62e3fd..e65c1622 100644 --- a/src/D2L.Security.OAuth2/Provisioning/AccessTokenProviderFactory.cs +++ b/src/D2L.Security.OAuth2/Provisioning/AccessTokenProviderFactory.cs @@ -17,7 +17,7 @@ public static class AccessTokenProviderFactory { /// A new public static IAccessTokenProvider Create( ITokenSigner tokenSigner, - D2LHttpClient httpClient, + ID2LHttpClient httpClient, Uri authEndpoint, TimeSpan tokenRefreshGracePeriod ) { diff --git a/src/D2L.Security.OAuth2/Provisioning/Default/AuthServiceClient.cs b/src/D2L.Security.OAuth2/Provisioning/Default/AuthServiceClient.cs index 2ca912cf..c74a8b7e 100644 --- a/src/D2L.Security.OAuth2/Provisioning/Default/AuthServiceClient.cs +++ b/src/D2L.Security.OAuth2/Provisioning/Default/AuthServiceClient.cs @@ -40,7 +40,7 @@ internal sealed class AuthServiceClient : IAuthServiceClient { SERIALIZATION_ERROR_MESSAGE_PREFIX + "The Auth Service responded with: "; - private readonly D2LHttpClient m_client; + private readonly ID2LHttpClient m_client; private readonly Uri m_tokenProvisioningEndpoint; /// @@ -49,7 +49,7 @@ internal sealed class AuthServiceClient : IAuthServiceClient { /// An http client used to communicate with the auth service. /// The token provisioning endpoint on the auth service public AuthServiceClient( - D2LHttpClient httpClient, + ID2LHttpClient httpClient, Uri authEndpoint ) { if( httpClient == null ) { diff --git a/src/D2L.Security.OAuth2/Utilities/D2LHttpClient.cs b/src/D2L.Security.OAuth2/Utilities/D2LHttpClient.cs index ad583a37..c207fe9e 100644 --- a/src/D2L.Security.OAuth2/Utilities/D2LHttpClient.cs +++ b/src/D2L.Security.OAuth2/Utilities/D2LHttpClient.cs @@ -5,7 +5,7 @@ namespace D2L.Security.OAuth2.Utilities { - public class D2LHttpClient : ID2LHttpClient, IDisposable + public class D2LHttpClient : ID2LHttpClient { /// /// This class implements sync versions of HTTPClient methods. diff --git a/src/D2L.Security.OAuth2/Utilities/ID2LHttpClient.cs b/src/D2L.Security.OAuth2/Utilities/ID2LHttpClient.cs index 7750a6ee..f4af5b72 100644 --- a/src/D2L.Security.OAuth2/Utilities/ID2LHttpClient.cs +++ b/src/D2L.Security.OAuth2/Utilities/ID2LHttpClient.cs @@ -5,7 +5,7 @@ namespace D2L.Security.OAuth2.Utilities { - internal interface ID2LHttpClient + public interface ID2LHttpClient : IDisposable { /// /// This interface was created to allow the sync generator in D2L.CodeStyle to strip the async suffix from HttpClient calls diff --git a/src/D2L.Security.OAuth2/Validation/AccessTokens/AccessTokenValidatorFactory.cs b/src/D2L.Security.OAuth2/Validation/AccessTokens/AccessTokenValidatorFactory.cs index 28234804..4d3a9fa9 100644 --- a/src/D2L.Security.OAuth2/Validation/AccessTokens/AccessTokenValidatorFactory.cs +++ b/src/D2L.Security.OAuth2/Validation/AccessTokens/AccessTokenValidatorFactory.cs @@ -38,7 +38,7 @@ IPublicKeyDataProvider publicKeyDataProvider /// The full URI of the remote JWK path /// A new public static IAccessTokenValidator CreateRemoteValidator( - D2LHttpClient httpClient, + ID2LHttpClient httpClient, Uri jwksEndpoint, Uri jwkEndpoint = null ) { diff --git a/test/D2L.Security.OAuth2.Benchmarks/FullStackValidation/FullStackValidationBenchmark.cs b/test/D2L.Security.OAuth2.Benchmarks/FullStackValidation/FullStackValidationBenchmark.cs index 551c10b2..b9919c94 100644 --- a/test/D2L.Security.OAuth2.Benchmarks/FullStackValidation/FullStackValidationBenchmark.cs +++ b/test/D2L.Security.OAuth2.Benchmarks/FullStackValidation/FullStackValidationBenchmark.cs @@ -12,7 +12,7 @@ namespace D2L.Security.OAuth2.Benchmarks.FullStackValidation { internal abstract class FullStackValidationBenchmark : IBenchmark { - private D2LHttpClient m_httpClient; + private ID2LHttpClient m_httpClient; void IDisposable.Dispose() { m_httpClient.Dispose(); diff --git a/test/D2L.Security.OAuth2.IntegrationTests/Keys/Default/Data/JwksProviderTests.cs b/test/D2L.Security.OAuth2.IntegrationTests/Keys/Default/Data/JwksProviderTests.cs index e27daf61..4d46c649 100644 --- a/test/D2L.Security.OAuth2.IntegrationTests/Keys/Default/Data/JwksProviderTests.cs +++ b/test/D2L.Security.OAuth2.IntegrationTests/Keys/Default/Data/JwksProviderTests.cs @@ -72,7 +72,7 @@ private HttpMessageHandler SetupJwkServer( [TestCase( GOOD_PATH_ADDITIONAL_NUMBER )] public async Task RequestJwksAsync_SuccessCase( string goodPath ) { using( var handler = SetupJwkServer( out string host ) ) - using( D2LHttpClient httpClient = new D2LHttpClient( handler ) ) { + using( ID2LHttpClient httpClient = new D2LHttpClient( handler ) ) { IJwksProvider publicKeyProvider = new JwksProvider( httpClient, jwksEndpoint: new Uri( host + goodPath + JWKS_PATH ), @@ -92,7 +92,7 @@ public async Task RequestJwksAsync_SuccessCase( string goodPath ) { [Test] public void RequestJwksAsync_HTML_Throws() { using( var handler = SetupJwkServer( out string host ) ) - using( D2LHttpClient httpClient = new D2LHttpClient( handler ) ) { + using( ID2LHttpClient httpClient = new D2LHttpClient( handler ) ) { IJwksProvider publicKeyProvider = new JwksProvider( httpClient, jwksEndpoint: new Uri( host + HTML_PATH ), @@ -112,7 +112,7 @@ public void RequestJwksAsync_HTML_Throws() { [Test] public void RequestJwksAsync_404_Throws() { using( var handler = SetupJwkServer( out string host ) ) - using( D2LHttpClient httpClient = new D2LHttpClient( handler ) ) { + using( ID2LHttpClient httpClient = new D2LHttpClient( handler ) ) { IJwksProvider publicKeyProvider = new JwksProvider( httpClient, jwksEndpoint: new Uri( host + BAD_PATH ), @@ -130,7 +130,7 @@ public void RequestJwksAsync_404_Throws() { [Test] public void RequestJwksAsync_CantReachServer_Throws() { using( var handler = SetupJwkServer( out string host ) ) - using( D2LHttpClient httpClient = new D2LHttpClient( handler ) ) { + using( ID2LHttpClient httpClient = new D2LHttpClient( handler ) ) { IJwksProvider publicKeyProvider = new JwksProvider( httpClient, jwksEndpoint: new Uri( "http://foo.bar.fakesite.isurehopethisisneveravalidTLD" ), @@ -148,7 +148,7 @@ public void RequestJwksAsync_CantReachServer_Throws() { [Test] public async Task RequestJwkAsync_Success() { using( var handler = SetupJwkServer( out string host, hasJwk: true, jwkStatusCode: HttpStatusCode.OK ) ) - using( D2LHttpClient httpClient = new D2LHttpClient( handler ) ) { + using( ID2LHttpClient httpClient = new D2LHttpClient( handler ) ) { IJwksProvider jwksProvider = new JwksProvider( httpClient, jwksEndpoint: new Uri( host + GOOD_PATH + JWKS_PATH ), @@ -171,7 +171,7 @@ public async Task RequestJwkAsync_Success() { [Test] public async Task RequestJwkAsync_NullJwkEndpoint_Fallback_Success() { using( var handler = SetupJwkServer( out string host, hasJwk: true, jwkStatusCode: HttpStatusCode.OK ) ) - using( D2LHttpClient httpClient = new D2LHttpClient( handler ) ) { + using( ID2LHttpClient httpClient = new D2LHttpClient( handler ) ) { IJwksProvider jwksProvider = new JwksProvider( httpClient, jwksEndpoint: new Uri( host + GOOD_PATH + JWKS_PATH ), @@ -194,7 +194,7 @@ public async Task RequestJwkAsync_NullJwkEndpoint_Fallback_Success() { [Test] public async Task RequestJwkAsync_StringKeyId_Success() { using( var handler = SetupJwkServer( out string host, hasJwk: true, jwkStatusCode: HttpStatusCode.OK ) ) - using( D2LHttpClient httpClient = new D2LHttpClient( handler ) ) { + using( ID2LHttpClient httpClient = new D2LHttpClient( handler ) ) { IJwksProvider jwksProvider = new JwksProvider( httpClient, jwksEndpoint: new Uri( host + GOOD_PATH + JWKS_PATH ), @@ -217,7 +217,7 @@ public async Task RequestJwkAsync_StringKeyId_Success() { [Test] public async Task RequestJwkAsync_StringKeyId_InvalidKeyId_Fallback_DoesNotReturnKey() { using( var handler = SetupJwkServer( out string host, hasJwk: true, jwkStatusCode: HttpStatusCode.OK ) ) - using( D2LHttpClient httpClient = new D2LHttpClient( handler ) ) { + using( ID2LHttpClient httpClient = new D2LHttpClient( handler ) ) { IJwksProvider jwksProvider = new JwksProvider( httpClient, jwksEndpoint: new Uri( host + GOOD_PATH + JWKS_PATH ), @@ -239,7 +239,7 @@ public async Task RequestJwkAsync_StringKeyId_InvalidKeyId_Fallback_DoesNotRetur [Test] public async Task RequestJwkAsync_404_Fallback_Success() { using( var handler = SetupJwkServer( out string host, hasJwk: false, jwkStatusCode: HttpStatusCode.NotFound ) ) - using( D2LHttpClient httpClient = new D2LHttpClient( handler ) ) { + using( ID2LHttpClient httpClient = new D2LHttpClient( handler ) ) { IJwksProvider jwksProvider = new JwksProvider( httpClient, jwksEndpoint: new Uri( host + GOOD_PATH + JWKS_PATH ), @@ -262,7 +262,7 @@ public async Task RequestJwkAsync_404_Fallback_Success() { [Test] public async Task RequestJwkAsync_StringKeyId_404_Fallback_Success() { using( var handler = SetupJwkServer( out string host, hasJwk: false, jwkStatusCode: HttpStatusCode.NotFound ) ) - using( D2LHttpClient httpClient = new D2LHttpClient( handler ) ) { + using( ID2LHttpClient httpClient = new D2LHttpClient( handler ) ) { IJwksProvider jwksProvider = new JwksProvider( httpClient, jwksEndpoint: new Uri( host + GOOD_PATH + JWKS_PATH ), @@ -285,7 +285,7 @@ public async Task RequestJwkAsync_StringKeyId_404_Fallback_Success() { [Test] public async Task RequestJwkAsync_500_Fallback_Success() { using( var handler = SetupJwkServer( out string host, hasJwk: false, jwkStatusCode: HttpStatusCode.InternalServerError ) ) - using( D2LHttpClient httpClient = new D2LHttpClient( handler ) ) { + using( ID2LHttpClient httpClient = new D2LHttpClient( handler ) ) { IJwksProvider jwksProvider = new JwksProvider( httpClient, jwksEndpoint: new Uri( host + GOOD_PATH + JWKS_PATH ), @@ -308,7 +308,7 @@ public async Task RequestJwkAsync_500_Fallback_Success() { [Test] public async Task RequestJwkAsync_StringKeyId_500_Fallback_Success() { using( var handler = SetupJwkServer( out string host, hasJwk: false, jwkStatusCode: HttpStatusCode.InternalServerError ) ) - using( D2LHttpClient httpClient = new D2LHttpClient( handler ) ) { + using( ID2LHttpClient httpClient = new D2LHttpClient( handler ) ) { IJwksProvider jwksProvider = new JwksProvider( httpClient, jwksEndpoint: new Uri( host + GOOD_PATH + JWKS_PATH ), diff --git a/test/D2L.Security.OAuth2.UnitTests/Provisioning/AuthServiceClientTests.cs b/test/D2L.Security.OAuth2.UnitTests/Provisioning/AuthServiceClientTests.cs index ecf19ca5..1e551a2b 100644 --- a/test/D2L.Security.OAuth2.UnitTests/Provisioning/AuthServiceClientTests.cs +++ b/test/D2L.Security.OAuth2.UnitTests/Provisioning/AuthServiceClientTests.cs @@ -122,7 +122,7 @@ await RunTest_ExpectSuccess( } private async Task RunTest_ExpectServiceException( - D2LHttpClient mockClient, + ID2LHttpClient mockClient, ServiceErrorType expectedErrorType, string expectedMessage = null ) { @@ -141,14 +141,14 @@ private async Task RunTest_ExpectServiceException( } private async Task RunTest_ExpectSuccess( - D2LHttpClient mockClient, + ID2LHttpClient mockClient, string expectedToken ) { IAccessToken token = await RunTestHelper( mockClient ); Assert.AreEqual( expectedToken, token.Token ); } - private async Task RunTestHelper( D2LHttpClient mockClient ) { + private async Task RunTestHelper( ID2LHttpClient mockClient ) { IAuthServiceClient client = new AuthServiceClient( httpClient: mockClient, authEndpoint: new Uri( TEST_URI ) diff --git a/test/D2L.Security.OAuth2.UnitTests/Provisioning/Default/AuthServiceClientTests.cs b/test/D2L.Security.OAuth2.UnitTests/Provisioning/Default/AuthServiceClientTests.cs index f20221e8..9bd9b662 100644 --- a/test/D2L.Security.OAuth2.UnitTests/Provisioning/Default/AuthServiceClientTests.cs +++ b/test/D2L.Security.OAuth2.UnitTests/Provisioning/Default/AuthServiceClientTests.cs @@ -103,7 +103,7 @@ public async Task CorrectlyReadsResponse() { } } - private static D2LHttpClient CreateMockedHttpClient( + private static ID2LHttpClient CreateMockedHttpClient( Action requestBodyReceiver, HttpStatusCode responseStatus = HttpStatusCode.OK, string responseContent = TestData.ValidHttpResponseBody @@ -130,7 +130,7 @@ private static D2LHttpClient CreateMockedHttpClient( return httpClient; } - private static IAuthServiceClient CreateClient( D2LHttpClient httpClient ) { + private static IAuthServiceClient CreateClient( ID2LHttpClient httpClient ) { var client = new AuthServiceClient( httpClient: httpClient, authEndpoint: new Uri( "http://foo.d2l" ) diff --git a/test/D2L.Security.OAuth2.UnitTests/Utilities/MockHttpClient.cs b/test/D2L.Security.OAuth2.UnitTests/Utilities/MockHttpClient.cs index c8ad3630..f4d6a1cd 100644 --- a/test/D2L.Security.OAuth2.UnitTests/Utilities/MockHttpClient.cs +++ b/test/D2L.Security.OAuth2.UnitTests/Utilities/MockHttpClient.cs @@ -24,7 +24,7 @@ internal static class MockHttpClient { /// The body of the response that the HttpClient should generate /// /// - public static D2LHttpClient Create( + public static ID2LHttpClient Create( HttpStatusCode responseStatus, string responseContent = null ) { @@ -46,7 +46,7 @@ public static D2LHttpClient Create( /// The exception the HttpClient should throw /// /// - public static D2LHttpClient Create( + public static ID2LHttpClient Create( Exception throwsException ) { return new D2LHttpClient( From a861d75269ae445a2c78ad9ec091a90da5909e70 Mon Sep 17 00:00:00 2001 From: AnaCoda Date: Tue, 11 Jul 2023 11:18:26 -0600 Subject: [PATCH 08/25] Revert some previous changes --- .../Keys/Default/Data/JwksProvider.cs | 12 ++++-------- .../InMemoryPublicKeyDataProvider.cs | 18 +++++++++--------- 2 files changed, 13 insertions(+), 17 deletions(-) diff --git a/src/D2L.Security.OAuth2/Keys/Default/Data/JwksProvider.cs b/src/D2L.Security.OAuth2/Keys/Default/Data/JwksProvider.cs index 6c48e436..54e7f3ee 100644 --- a/src/D2L.Security.OAuth2/Keys/Default/Data/JwksProvider.cs +++ b/src/D2L.Security.OAuth2/Keys/Default/Data/JwksProvider.cs @@ -30,10 +30,7 @@ async Task IJwksProvider.RequestJwksAsync() { try { using( HttpResponseMessage response = await m_httpClient.GetAsync( m_jwksEndpoint ).ConfigureAwait( false ) ) { response.EnsureSuccessStatusCode(); - using var reader = new StreamReader(await response.Content.ReadAsStreamAsync().ConfigureAwait(false)); - string jsonResponse = await reader - .ReadToEndAsync() - .ConfigureAwait(false); + string jsonResponse = await response.Content.ReadAsStringAsync().ConfigureAwait(false); var jwks = new JsonWebKeySet( jsonResponse, m_jwksEndpoint ); return jwks; } @@ -69,10 +66,9 @@ async Task IJwksProvider.RequestJwkAsync( string keyId ) { res.EnsureSuccessStatusCode(); - using var reader = new StreamReader(await res.Content.ReadAsStreamAsync().ConfigureAwait(false)); - string json = await reader - .ReadToEndAsync() - .ConfigureAwait(false); + string json = await res.Content + .ReadAsStringAsync() + .ConfigureAwait( false ); JsonWebKey jwk = JsonWebKey.FromJson( json ); return new JsonWebKeySet( jwk, url ); diff --git a/src/D2L.Security.OAuth2/Keys/Development/InMemoryPublicKeyDataProvider.cs b/src/D2L.Security.OAuth2/Keys/Development/InMemoryPublicKeyDataProvider.cs index a8decaaa..e453cf0e 100644 --- a/src/D2L.Security.OAuth2/Keys/Development/InMemoryPublicKeyDataProvider.cs +++ b/src/D2L.Security.OAuth2/Keys/Development/InMemoryPublicKeyDataProvider.cs @@ -16,33 +16,33 @@ public sealed partial class InMemoryPublicKeyDataProvider : IPublicKeyDataProvid private readonly ConcurrentDictionary m_keys = new ConcurrentDictionary(); [GenerateSync] - async Task IPublicKeyDataProvider.GetByIdAsync( Guid id ) { + Task IPublicKeyDataProvider.GetByIdAsync( Guid id ) { if( !m_keys.TryGetValue( id, out JsonWebKey key ) ) { - return await Task.FromResult( null ).ConfigureAwait(false); + return Task.FromResult( null ); } - return await Task.FromResult(key).ConfigureAwait(false); + return Task.FromResult(key); } [GenerateSync] - async Task> IPublicKeyDataProvider.GetAllAsync() { + Task> IPublicKeyDataProvider.GetAllAsync() { IEnumerable result = new ReadOnlyCollection( m_keys.Values.ToList() ); - return await Task.FromResult(result).ConfigureAwait(false); + return Task.FromResult(result); } [GenerateSync] - async Task IPublicKeyDataProvider.SaveAsync( Guid id, JsonWebKey key ) { + Task IPublicKeyDataProvider.SaveAsync( Guid id, JsonWebKey key ) { if( !m_keys.TryAdd( id, key ) ) { throw new InvalidOperationException( "Attempted to add a key twice" ); } - await Task.CompletedTask.ConfigureAwait(false); + return Task.CompletedTask; } [GenerateSync] - async Task IPublicKeyDataProvider.DeleteAsync( Guid id ) { + Task IPublicKeyDataProvider.DeleteAsync( Guid id ) { m_keys.TryRemove( id, out JsonWebKey removedKey ); - await Task.CompletedTask.ConfigureAwait(false); + return Task.CompletedTask; } } } From 102d6e3a62175d6d49a7429ecc9744d8ad9cc437 Mon Sep 17 00:00:00 2001 From: AnaCoda Date: Tue, 11 Jul 2023 13:24:46 -0600 Subject: [PATCH 09/25] Discard changes to Directory.Packages.props --- Directory.Packages.props | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Directory.Packages.props b/Directory.Packages.props index 17894005..a2ed1444 100644 --- a/Directory.Packages.props +++ b/Directory.Packages.props @@ -1,7 +1,7 @@  - + From 0e0e4decb431df9c88c20c4ce4e9839fabca3d19 Mon Sep 17 00:00:00 2001 From: AnaCoda Date: Wed, 12 Jul 2023 11:26:32 -0600 Subject: [PATCH 10/25] Discard changes to test/D2L.Security.OAuth2.UnitTests/Keys/Development/InMemoryPublicKeyDataProviderTests.cs --- .../Development/InMemoryPublicKeyDataProviderTests.cs | 10 +--------- 1 file changed, 1 insertion(+), 9 deletions(-) diff --git a/test/D2L.Security.OAuth2.UnitTests/Keys/Development/InMemoryPublicKeyDataProviderTests.cs b/test/D2L.Security.OAuth2.UnitTests/Keys/Development/InMemoryPublicKeyDataProviderTests.cs index c4ee55c4..3313db57 100644 --- a/test/D2L.Security.OAuth2.UnitTests/Keys/Development/InMemoryPublicKeyDataProviderTests.cs +++ b/test/D2L.Security.OAuth2.UnitTests/Keys/Development/InMemoryPublicKeyDataProviderTests.cs @@ -94,15 +94,7 @@ public async Task SaveAsync_DoubleSave_ThrowsException() { var key = new JsonWebKeyStub( id.ToString() ); await m_publicKeyDataProvider.SaveAsync( id, key ).ConfigureAwait( false ); - try { - m_publicKeyDataProvider.SaveAsync(id, key).Wait(); - } - catch (AggregateException ae) { - Assert.AreEqual( - typeof(InvalidOperationException), ae.InnerException.GetType(), - "There was no InvalidOperationException." - ); - } + Assert.Throws( () => m_publicKeyDataProvider.SaveAsync( id, key ).Wait() ); } [Test] From e85fceb03c3e64e51fb9c8c2c6b716d0d347187d Mon Sep 17 00:00:00 2001 From: AnaCoda Date: Wed, 12 Jul 2023 11:28:04 -0600 Subject: [PATCH 11/25] Spacing fix --- .../Keys/Development/InMemoryPublicKeyDataProvider.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/D2L.Security.OAuth2/Keys/Development/InMemoryPublicKeyDataProvider.cs b/src/D2L.Security.OAuth2/Keys/Development/InMemoryPublicKeyDataProvider.cs index e453cf0e..8b80b6f9 100644 --- a/src/D2L.Security.OAuth2/Keys/Development/InMemoryPublicKeyDataProvider.cs +++ b/src/D2L.Security.OAuth2/Keys/Development/InMemoryPublicKeyDataProvider.cs @@ -20,7 +20,7 @@ Task IPublicKeyDataProvider.GetByIdAsync( Guid id ) { if( !m_keys.TryGetValue( id, out JsonWebKey key ) ) { return Task.FromResult( null ); } - return Task.FromResult(key); + return Task.FromResult( key ); } [GenerateSync] @@ -28,7 +28,7 @@ Task> IPublicKeyDataProvider.GetAllAsync() { IEnumerable result = new ReadOnlyCollection( m_keys.Values.ToList() ); - return Task.FromResult(result); + return Task.FromResult( result ); } [GenerateSync] From b048026a096307899de0dee513047fb92f2eea3d Mon Sep 17 00:00:00 2001 From: AnaCoda Date: Wed, 12 Jul 2023 11:49:37 -0600 Subject: [PATCH 12/25] Discard changes to Directory.Packages.props From e0f1c6aec1d255bc80d57ea1599f66e51d3e5b2d Mon Sep 17 00:00:00 2001 From: AnaCoda Date: Wed, 12 Jul 2023 11:50:27 -0600 Subject: [PATCH 13/25] Update Directory.Packages.props --- Directory.Packages.props | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Directory.Packages.props b/Directory.Packages.props index a2ed1444..17894005 100644 --- a/Directory.Packages.props +++ b/Directory.Packages.props @@ -1,7 +1,7 @@  - + From b4566df63a0c2f7539c7ef06ab89e878eab6134e Mon Sep 17 00:00:00 2001 From: AnaCoda Date: Fri, 14 Jul 2023 09:02:15 -0600 Subject: [PATCH 14/25] Add generators to ExpiringPublicKeyDataProvider --- Directory.Build.props | 1 + .../Keys/Default/ExpiringPublicKeyDataProvider.cs | 8 +++++++- 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/Directory.Build.props b/Directory.Build.props index 6d41e536..75dc08ed 100644 --- a/Directory.Build.props +++ b/Directory.Build.props @@ -24,5 +24,6 @@ 11.0 true + CS8785 diff --git a/src/D2L.Security.OAuth2/Keys/Default/ExpiringPublicKeyDataProvider.cs b/src/D2L.Security.OAuth2/Keys/Default/ExpiringPublicKeyDataProvider.cs index 40fcf57d..48fe117f 100644 --- a/src/D2L.Security.OAuth2/Keys/Default/ExpiringPublicKeyDataProvider.cs +++ b/src/D2L.Security.OAuth2/Keys/Default/ExpiringPublicKeyDataProvider.cs @@ -2,11 +2,12 @@ using System.Collections.Generic; using System.Linq; using System.Threading.Tasks; +using D2L.CodeStyle.Annotations; using D2L.Security.OAuth2.Utilities; using D2L.Services; namespace D2L.Security.OAuth2.Keys.Default { - internal sealed class ExpiringPublicKeyDataProvider : ISanePublicKeyDataProvider { + internal sealed partial class ExpiringPublicKeyDataProvider : ISanePublicKeyDataProvider { private readonly IPublicKeyDataProvider m_inner; private readonly IDateTimeProvider m_dateTimeProvider; @@ -18,6 +19,7 @@ IDateTimeProvider dateTimeProvider m_dateTimeProvider = dateTimeProvider ?? throw new ArgumentException( nameof( dateTimeProvider ) ); } + [GenerateSync] async Task IPublicKeyDataProvider.GetByIdAsync( Guid id ) { // We are intentionally fetching *all* public keys from the database // here. This allows us to clean up all expired public keys even if @@ -44,6 +46,7 @@ async Task IPublicKeyDataProvider.GetByIdAsync( Guid id ) { return key; } + [GenerateSync] async Task> IPublicKeyDataProvider.GetAllAsync() { IEnumerable keys = await m_inner .GetAllAsync() @@ -62,14 +65,17 @@ async Task> IPublicKeyDataProvider.GetAllAsync() { return result; } + [GenerateSync] Task IPublicKeyDataProvider.SaveAsync( Guid id, JsonWebKey key ) { return m_inner.SaveAsync( id, key ); } + [GenerateSync] Task IPublicKeyDataProvider.DeleteAsync( Guid id ) { return m_inner.DeleteAsync( id ); } + [GenerateSync] private async Task KeyExpiryHelperAsync( JsonWebKey key ) { if( key == null ) { return true; From c6fb9ebd8b2fe87c9e33338d9f637c5f2927bc49 Mon Sep 17 00:00:00 2001 From: AnaCoda Date: Fri, 14 Jul 2023 09:02:39 -0600 Subject: [PATCH 15/25] Analyzer version 195 --- Directory.Packages.props | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Directory.Packages.props b/Directory.Packages.props index 17894005..0cd97b69 100644 --- a/Directory.Packages.props +++ b/Directory.Packages.props @@ -1,7 +1,7 @@  - + From 2d3d2d21bc950c253906daf9e84a843f1d5b175d Mon Sep 17 00:00:00 2001 From: AnaCoda Date: Thu, 20 Jul 2023 11:52:48 -0600 Subject: [PATCH 16/25] D2L.CodeStyle.Analyzers to 0.196.0 --- Directory.Packages.props | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Directory.Packages.props b/Directory.Packages.props index 0cd97b69..36ac2ed5 100644 --- a/Directory.Packages.props +++ b/Directory.Packages.props @@ -1,7 +1,7 @@  - + From 553583a8de15d076cd7712ffaa5c6572d275417f Mon Sep 17 00:00:00 2001 From: AnaCoda Date: Thu, 20 Jul 2023 12:02:44 -0600 Subject: [PATCH 17/25] Remove Dispose from ID2LHttpClient since already extends IDisposable --- src/D2L.Security.OAuth2/Utilities/ID2LHttpClient.cs | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/D2L.Security.OAuth2/Utilities/ID2LHttpClient.cs b/src/D2L.Security.OAuth2/Utilities/ID2LHttpClient.cs index f4af5b72..42deeeaf 100644 --- a/src/D2L.Security.OAuth2/Utilities/ID2LHttpClient.cs +++ b/src/D2L.Security.OAuth2/Utilities/ID2LHttpClient.cs @@ -44,7 +44,5 @@ public interface ID2LHttpClient : IDisposable public HttpResponseMessage Send(HttpRequestMessage request, HttpCompletionOption completionOption); public HttpResponseMessage Send(HttpRequestMessage request, HttpCompletionOption completionOption, CancellationToken cancellationToken); - - public void Dispose(); } } From c0a3371707d721de95878600c3c77c3a08316b1a Mon Sep 17 00:00:00 2001 From: AnaCoda Date: Thu, 20 Jul 2023 12:17:46 -0600 Subject: [PATCH 18/25] Weird styling revert Co-authored-by: Jacob Parker --- src/D2L.Security.OAuth2/Keys/Default/Data/JwksProvider.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/D2L.Security.OAuth2/Keys/Default/Data/JwksProvider.cs b/src/D2L.Security.OAuth2/Keys/Default/Data/JwksProvider.cs index 54e7f3ee..19ad80d8 100644 --- a/src/D2L.Security.OAuth2/Keys/Default/Data/JwksProvider.cs +++ b/src/D2L.Security.OAuth2/Keys/Default/Data/JwksProvider.cs @@ -30,7 +30,7 @@ async Task IJwksProvider.RequestJwksAsync() { try { using( HttpResponseMessage response = await m_httpClient.GetAsync( m_jwksEndpoint ).ConfigureAwait( false ) ) { response.EnsureSuccessStatusCode(); - string jsonResponse = await response.Content.ReadAsStringAsync().ConfigureAwait(false); + string jsonResponse = await response.Content.ReadAsStringAsync().ConfigureAwait( false ); var jwks = new JsonWebKeySet( jsonResponse, m_jwksEndpoint ); return jwks; } From fe815e1bbea6a0dbd4eae8e0c82f5f5abf24a68d Mon Sep 17 00:00:00 2001 From: AnaCoda Date: Fri, 21 Jul 2023 12:42:11 -0600 Subject: [PATCH 19/25] Styling and spacing for (I)D2LHttpClient --- .../Utilities/D2LHttpClient.cs | 126 ++++++++---------- .../Utilities/ID2LHttpClient.cs | 80 ++++++----- 2 files changed, 98 insertions(+), 108 deletions(-) diff --git a/src/D2L.Security.OAuth2/Utilities/D2LHttpClient.cs b/src/D2L.Security.OAuth2/Utilities/D2LHttpClient.cs index c207fe9e..e3a7fea9 100644 --- a/src/D2L.Security.OAuth2/Utilities/D2LHttpClient.cs +++ b/src/D2L.Security.OAuth2/Utilities/D2LHttpClient.cs @@ -3,118 +3,110 @@ using System.Threading; using System.Threading.Tasks; -namespace D2L.Security.OAuth2.Utilities -{ - public class D2LHttpClient : ID2LHttpClient - { - /// - /// This class implements sync versions of HTTPClient methods. - /// TODO: Replace the sync methods which are currently using Task.Run(async verison); task.Wait(); - /// With (probably) HttpWebRequest - /// +namespace D2L.Security.OAuth2.Utilities { + /// + /// This class implements sync versions of HTTPClient methods. + /// TODO: Replace the sync methods which are currently using Task.Run(async verison); task.Wait(); + /// With (probably) HttpWebRequest + /// + public class D2LHttpClient : ID2LHttpClient { private readonly HttpClient m_httpClient; public D2LHttpClient() { m_httpClient = new HttpClient(); } - public D2LHttpClient(HttpMessageHandler handler) { - m_httpClient = new HttpClient(handler); + public D2LHttpClient( HttpMessageHandler handler ) { + m_httpClient = new HttpClient( handler ); } - public D2LHttpClient(HttpMessageHandler handler, bool disposeHandler) { - m_httpClient = new HttpClient(handler, disposeHandler); + public D2LHttpClient( HttpMessageHandler handler, bool disposeHandler ) { + m_httpClient = new HttpClient( handler, disposeHandler ); } - public Task GetAsync(string requestUri, HttpCompletionOption completionOption, CancellationToken cancellationToken) - => m_httpClient.GetAsync(requestUri, completionOption, cancellationToken); - public Task GetAsync(Uri requestUri, CancellationToken cancellationToken) - => m_httpClient.GetAsync(requestUri, cancellationToken); - public Task GetAsync(Uri requestUri, HttpCompletionOption completionOption, CancellationToken cancellationToken) - => m_httpClient.GetAsync(requestUri, completionOption, cancellationToken); - public Task GetAsync(Uri requestUri, HttpCompletionOption completionOption) - => m_httpClient.GetAsync(requestUri, completionOption); - public Task GetAsync(string requestUri, HttpCompletionOption completionOption) - => m_httpClient.GetAsync(requestUri, completionOption); - public Task GetAsync(Uri requestUri) - => m_httpClient.GetAsync(requestUri); - public Task GetAsync(string requestUri) - => m_httpClient.GetAsync(requestUri); - public Task GetAsync(string requestUri, CancellationToken cancellationToken) - => m_httpClient.GetAsync(requestUri, cancellationToken); + public Task GetAsync( string requestUri, HttpCompletionOption completionOption, CancellationToken cancellationToken ) + => m_httpClient.GetAsync( requestUri, completionOption, cancellationToken ); + public Task GetAsync( Uri requestUri, CancellationToken cancellationToken ) + => m_httpClient.GetAsync( requestUri, cancellationToken ); + public Task GetAsync( Uri requestUri, HttpCompletionOption completionOption, CancellationToken cancellationToken ) + => m_httpClient.GetAsync( requestUri, completionOption, cancellationToken ); + public Task GetAsync( Uri requestUri, HttpCompletionOption completionOption ) + => m_httpClient.GetAsync( requestUri, completionOption ); + public Task GetAsync( string requestUri, HttpCompletionOption completionOption ) + => m_httpClient.GetAsync( requestUri, completionOption ); + public Task GetAsync( Uri requestUri ) + => m_httpClient.GetAsync( requestUri ); + public Task GetAsync( string requestUri ) + => m_httpClient.GetAsync( requestUri ); + public Task GetAsync( string requestUri, CancellationToken cancellationToken ) + => m_httpClient.GetAsync( requestUri, cancellationToken ); - public Task SendAsync(HttpRequestMessage request) - => m_httpClient.SendAsync(request); - - public Task SendAsync(HttpRequestMessage request, CancellationToken cancellationToken) - => m_httpClient.SendAsync(request, cancellationToken); - - public Task SendAsync(HttpRequestMessage request, HttpCompletionOption completionOption) - => m_httpClient.SendAsync(request, completionOption); - - public Task SendAsync(HttpRequestMessage request, HttpCompletionOption completionOption, CancellationToken cancellationToken) - => m_httpClient.SendAsync(request, completionOption, cancellationToken); + public Task SendAsync( HttpRequestMessage request ) + => m_httpClient.SendAsync( request ); + public Task SendAsync( HttpRequestMessage request, CancellationToken cancellationToken ) + => m_httpClient.SendAsync( request, cancellationToken ); + public Task SendAsync( HttpRequestMessage request, HttpCompletionOption completionOption ) + => m_httpClient.SendAsync( request, completionOption ); + public Task SendAsync( HttpRequestMessage request, HttpCompletionOption completionOption, CancellationToken cancellationToken ) + => m_httpClient.SendAsync( request, completionOption, cancellationToken ); #pragma warning disable D2L0018 // Avoid using dangerous methods - public HttpResponseMessage Get(string requestUri, HttpCompletionOption completionOption, CancellationToken cancellationToken) { - var task = Task.Run(() => m_httpClient.GetAsync(requestUri, completionOption, cancellationToken)); + public HttpResponseMessage Get( string requestUri, HttpCompletionOption completionOption, CancellationToken cancellationToken ) { + var task = Task.Run( () => m_httpClient.GetAsync( requestUri, completionOption, cancellationToken ) ); task.Wait(); return task.Result; } - public HttpResponseMessage Get(Uri requestUri, CancellationToken cancellationToken) { - var task = Task.Run(() => m_httpClient.GetAsync(requestUri, cancellationToken)); + public HttpResponseMessage Get( Uri requestUri, CancellationToken cancellationToken ) { + var task = Task.Run( () => m_httpClient.GetAsync( requestUri, cancellationToken ) ); task.Wait(); return task.Result; } - public HttpResponseMessage Get(Uri requestUri, HttpCompletionOption completionOption, CancellationToken cancellationToken) { - var task = Task.Run(() => m_httpClient.GetAsync(requestUri, completionOption, cancellationToken)); + public HttpResponseMessage Get( Uri requestUri, HttpCompletionOption completionOption, CancellationToken cancellationToken ) { + var task = Task.Run( () => m_httpClient.GetAsync( requestUri, completionOption, cancellationToken ) ); task.Wait(); return task.Result; } - public HttpResponseMessage Get(Uri requestUri, HttpCompletionOption completionOption) { - var task = Task.Run(() => m_httpClient.GetAsync(requestUri, completionOption)); + public HttpResponseMessage Get( Uri requestUri, HttpCompletionOption completionOption ) { + var task = Task.Run( () => m_httpClient.GetAsync( requestUri, completionOption ) ); task.Wait(); return task.Result; } - public HttpResponseMessage Get(string requestUri, HttpCompletionOption completionOption) { - var task = Task.Run(() => m_httpClient.GetAsync(requestUri, completionOption)); + public HttpResponseMessage Get( string requestUri, HttpCompletionOption completionOption ) { + var task = Task.Run( () => m_httpClient.GetAsync( requestUri, completionOption ) ); task.Wait(); return task.Result; } - public HttpResponseMessage Get(Uri requestUri) { - var task = Task.Run(() => m_httpClient.GetAsync(requestUri)); + public HttpResponseMessage Get( Uri requestUri ) { + var task = Task.Run( () => m_httpClient.GetAsync( requestUri ) ); task.Wait(); return task.Result; } - public HttpResponseMessage Get(string requestUri) { - var task = Task.Run(() => m_httpClient.GetAsync(requestUri)); + public HttpResponseMessage Get( string requestUri ) { + var task = Task.Run( () => m_httpClient.GetAsync( requestUri ) ); task.Wait(); return task.Result; } - public HttpResponseMessage Get(string requestUri, CancellationToken cancellationToken) { - var task = Task.Run(() => m_httpClient.GetAsync(requestUri, cancellationToken)); + public HttpResponseMessage Get( string requestUri, CancellationToken cancellationToken ) { + var task = Task.Run( () => m_httpClient.GetAsync( requestUri, cancellationToken ) ); task.Wait(); return task.Result; } - public HttpResponseMessage Send(HttpRequestMessage request) { - var task = Task.Run(() => m_httpClient.SendAsync(request)); + public HttpResponseMessage Send( HttpRequestMessage request ) { + var task = Task.Run( () => m_httpClient.SendAsync( request ) ); task.Wait(); return task.Result; } - - public HttpResponseMessage Send(HttpRequestMessage request, CancellationToken cancellationToken) { - var task = Task.Run(() => m_httpClient.SendAsync(request, cancellationToken)); + public HttpResponseMessage Send( HttpRequestMessage request, CancellationToken cancellationToken ) { + var task = Task.Run( () => m_httpClient.SendAsync( request, cancellationToken ) ); task.Wait(); return task.Result; } - - public HttpResponseMessage Send(HttpRequestMessage request, HttpCompletionOption completionOption) { - var task = Task.Run(() => m_httpClient.SendAsync(request, completionOption)); + public HttpResponseMessage Send( HttpRequestMessage request, HttpCompletionOption completionOption ) { + var task = Task.Run( () => m_httpClient.SendAsync( request, completionOption ) ); task.Wait(); return task.Result; } - - public HttpResponseMessage Send(HttpRequestMessage request, HttpCompletionOption completionOption, CancellationToken cancellationToken) { - var task = Task.Run(() => m_httpClient.SendAsync(request, completionOption, cancellationToken)); + public HttpResponseMessage Send( HttpRequestMessage request, HttpCompletionOption completionOption, CancellationToken cancellationToken ) { + var task = Task.Run( () => m_httpClient.SendAsync( request, completionOption, cancellationToken ) ); task.Wait(); return task.Result; } diff --git a/src/D2L.Security.OAuth2/Utilities/ID2LHttpClient.cs b/src/D2L.Security.OAuth2/Utilities/ID2LHttpClient.cs index 42deeeaf..16cd82ca 100644 --- a/src/D2L.Security.OAuth2/Utilities/ID2LHttpClient.cs +++ b/src/D2L.Security.OAuth2/Utilities/ID2LHttpClient.cs @@ -3,46 +3,44 @@ using System.Threading; using System.Threading.Tasks; -namespace D2L.Security.OAuth2.Utilities -{ - public interface ID2LHttpClient : IDisposable - { - /// - /// This interface was created to allow the sync generator in D2L.CodeStyle to strip the async suffix from HttpClient calls - /// when it tries to convert async code to sync code. - /// - public Task GetAsync(string requestUri, HttpCompletionOption completionOption, CancellationToken cancellationToken); - public Task GetAsync(Uri requestUri, CancellationToken cancellationToken); - public Task GetAsync(Uri requestUri, HttpCompletionOption completionOption, CancellationToken cancellationToken); - public Task GetAsync(Uri requestUri, HttpCompletionOption completionOption); - public Task GetAsync(string requestUri, HttpCompletionOption completionOption); - public Task GetAsync(Uri requestUri); - public Task GetAsync(string requestUri); - public Task GetAsync(string requestUri, CancellationToken cancellationToken); - - public HttpResponseMessage Get(string requestUri, HttpCompletionOption completionOption, CancellationToken cancellationToken); - public HttpResponseMessage Get(Uri requestUri, CancellationToken cancellationToken); - public HttpResponseMessage Get(Uri requestUri, HttpCompletionOption completionOption, CancellationToken cancellationToken); - public HttpResponseMessage Get(Uri requestUri, HttpCompletionOption completionOption); - public HttpResponseMessage Get(string requestUri, HttpCompletionOption completionOption); - public HttpResponseMessage Get(Uri requestUri); - public HttpResponseMessage Get(string requestUri); - public HttpResponseMessage Get(string requestUri, CancellationToken cancellationToken); - - public Task SendAsync(HttpRequestMessage request); - - public Task SendAsync(HttpRequestMessage request, CancellationToken cancellationToken); - - public Task SendAsync(HttpRequestMessage request, HttpCompletionOption completionOption); - - public Task SendAsync(HttpRequestMessage request, HttpCompletionOption completionOption, CancellationToken cancellationToken); - - public HttpResponseMessage Send(HttpRequestMessage request); - - public HttpResponseMessage Send(HttpRequestMessage request, CancellationToken cancellationToken); - - public HttpResponseMessage Send(HttpRequestMessage request, HttpCompletionOption completionOption); - - public HttpResponseMessage Send(HttpRequestMessage request, HttpCompletionOption completionOption, CancellationToken cancellationToken); +namespace D2L.Security.OAuth2.Utilities { + /// + /// This interface was created to allow the sync generator in D2L.CodeStyle to strip the async suffix from HttpClient calls + /// when it tries to convert async code to sync code. + /// + public interface ID2LHttpClient : IDisposable { + public Task GetAsync( string requestUri, HttpCompletionOption completionOption, CancellationToken cancellationToken ); + public Task GetAsync( Uri requestUri, CancellationToken cancellationToken ); + public Task GetAsync( Uri requestUri, HttpCompletionOption completionOption, CancellationToken cancellationToken ); + public Task GetAsync( Uri requestUri, HttpCompletionOption completionOption ); + public Task GetAsync( string requestUri, HttpCompletionOption completionOption ); + public Task GetAsync( Uri requestUri ); + public Task GetAsync( string requestUri ); + public Task GetAsync( string requestUri, CancellationToken cancellationToken ); + + public HttpResponseMessage Get( string requestUri, HttpCompletionOption completionOption, CancellationToken cancellationToken ); + public HttpResponseMessage Get( Uri requestUri, CancellationToken cancellationToken ); + public HttpResponseMessage Get( Uri requestUri, HttpCompletionOption completionOption, CancellationToken cancellationToken ); + public HttpResponseMessage Get( Uri requestUri, HttpCompletionOption completionOption ); + public HttpResponseMessage Get( string requestUri, HttpCompletionOption completionOption ); + public HttpResponseMessage Get( Uri requestUri ); + public HttpResponseMessage Get( string requestUri ); + public HttpResponseMessage Get( string requestUri, CancellationToken cancellationToken ); + + public Task SendAsync( HttpRequestMessage request ); + + public Task SendAsync( HttpRequestMessage request, CancellationToken cancellationToken ); + + public Task SendAsync( HttpRequestMessage request, HttpCompletionOption completionOption ); + + public Task SendAsync( HttpRequestMessage request, HttpCompletionOption completionOption, CancellationToken cancellationToken ); + + public HttpResponseMessage Send( HttpRequestMessage request ); + + public HttpResponseMessage Send( HttpRequestMessage request, CancellationToken cancellationToken ); + + public HttpResponseMessage Send( HttpRequestMessage request, HttpCompletionOption completionOption ); + + public HttpResponseMessage Send( HttpRequestMessage request, HttpCompletionOption completionOption, CancellationToken cancellationToken ); } } From f8a32e8da8bb75fbf447afefb0038909cb36d8d6 Mon Sep 17 00:00:00 2001 From: AnaCoda Date: Fri, 21 Jul 2023 13:03:35 -0600 Subject: [PATCH 20/25] Refactor D2LHttpClient as a wrapper --- .../TestAccessToken.cs | 2 +- .../TestAccessTokenProviderFactory.cs | 4 ++-- .../Keys/Default/Data/JwksProvider.cs | 4 ++-- .../AccessTokenProviderFactory.cs | 2 +- .../Provisioning/Default/AuthServiceClient.cs | 4 ++-- .../Utilities/D2LHttpClient.cs | 12 +++------- .../Utilities/ID2LHttpClient.cs | 2 +- .../AccessTokenValidatorFactory.cs | 2 +- .../FullStackValidationBenchmark.cs | 5 ++-- .../Keys/Default/Data/JwksProviderTests.cs | 24 +++++++++---------- .../TestAccessTokenProviderTests.cs | 6 ++--- .../TestFramework/TestAccessTokenTests.cs | 6 ++--- .../AccessTokenValidatorTests.EcDsa.cs | 4 ++-- .../AccessTokenValidatorTests.Rsa.cs | 2 +- .../AccessTokenProviderFactoryTests.cs | 4 ++-- .../Provisioning/AuthServiceClientTests.cs | 6 ++--- .../Default/AuthServiceClientTests.cs | 6 ++--- .../Utilities/MockHttpClient.cs | 8 +++---- 18 files changed, 49 insertions(+), 54 deletions(-) diff --git a/src/D2L.Security.OAuth2.TestFramework/TestAccessToken.cs b/src/D2L.Security.OAuth2.TestFramework/TestAccessToken.cs index 5b340e44..57914440 100644 --- a/src/D2L.Security.OAuth2.TestFramework/TestAccessToken.cs +++ b/src/D2L.Security.OAuth2.TestFramework/TestAccessToken.cs @@ -32,7 +32,7 @@ public static async Task GetToken( string tokenProvisioningEndpoint, IEn claims.Add( new Claim( Constants.Claims.ISSUER, DEFAULT_ISSUER ) ); - using( var httpClient = new D2LHttpClient() ) { + using( var httpClient = new HttpClient() ) { IAccessTokenProvider provider = TestAccessTokenProviderFactory.Create( httpClient, tokenProvisioningEndpoint ); IAccessToken token = await provider.ProvisionAccessTokenAsync( claims, scopes ).ConfigureAwait( false ); return token.Token; diff --git a/src/D2L.Security.OAuth2.TestFramework/TestAccessTokenProviderFactory.cs b/src/D2L.Security.OAuth2.TestFramework/TestAccessTokenProviderFactory.cs index 6da36128..31ab0ef9 100644 --- a/src/D2L.Security.OAuth2.TestFramework/TestAccessTokenProviderFactory.cs +++ b/src/D2L.Security.OAuth2.TestFramework/TestAccessTokenProviderFactory.cs @@ -20,7 +20,7 @@ public static class TestAccessTokenProviderFactory { /// The httpClient that makes the request to the auth server /// The auth server /// An IAccessTokenProvider with test credentials - public static IAccessTokenProvider Create( ID2LHttpClient httpClient, String tokenProvisioningEndpoint ) { + public static IAccessTokenProvider Create( HttpClient httpClient, String tokenProvisioningEndpoint ) { return Create( httpClient, tokenProvisioningEndpoint, TestKeyId, TestStaticKeyProvider.TestRSAParameters ); } @@ -32,7 +32,7 @@ public static IAccessTokenProvider Create( ID2LHttpClient httpClient, String tok /// The id of the security token /// The public and private key for the supplied key id /// An IAccessTokenProvider with the supplied test credentials - public static IAccessTokenProvider Create( ID2LHttpClient httpClient, String tokenProvisioningEndpoint, string keyId, RSAParameters rsaParameters ) { + public static IAccessTokenProvider Create( HttpClient httpClient, String tokenProvisioningEndpoint, string keyId, RSAParameters rsaParameters ) { #pragma warning disable 618 IPrivateKeyProvider privateKeyProvider = new StaticPrivateKeyProvider( keyId, rsaParameters ); #pragma warning restore 618 diff --git a/src/D2L.Security.OAuth2/Keys/Default/Data/JwksProvider.cs b/src/D2L.Security.OAuth2/Keys/Default/Data/JwksProvider.cs index 19ad80d8..33893870 100644 --- a/src/D2L.Security.OAuth2/Keys/Default/Data/JwksProvider.cs +++ b/src/D2L.Security.OAuth2/Keys/Default/Data/JwksProvider.cs @@ -16,11 +16,11 @@ internal sealed partial class JwksProvider : IJwksProvider { private readonly Uri m_jwkEndpoint; public JwksProvider( - ID2LHttpClient httpClient, + HttpClient httpClient, Uri jwksEndpoint, Uri jwkEndpoint ) { - m_httpClient = httpClient; + m_httpClient = new D2LHttpClient( httpClient ); m_jwksEndpoint = jwksEndpoint; m_jwkEndpoint = jwkEndpoint; } diff --git a/src/D2L.Security.OAuth2/Provisioning/AccessTokenProviderFactory.cs b/src/D2L.Security.OAuth2/Provisioning/AccessTokenProviderFactory.cs index e65c1622..f2518752 100644 --- a/src/D2L.Security.OAuth2/Provisioning/AccessTokenProviderFactory.cs +++ b/src/D2L.Security.OAuth2/Provisioning/AccessTokenProviderFactory.cs @@ -17,7 +17,7 @@ public static class AccessTokenProviderFactory { /// A new public static IAccessTokenProvider Create( ITokenSigner tokenSigner, - ID2LHttpClient httpClient, + HttpClient httpClient, Uri authEndpoint, TimeSpan tokenRefreshGracePeriod ) { diff --git a/src/D2L.Security.OAuth2/Provisioning/Default/AuthServiceClient.cs b/src/D2L.Security.OAuth2/Provisioning/Default/AuthServiceClient.cs index c74a8b7e..c56434d3 100644 --- a/src/D2L.Security.OAuth2/Provisioning/Default/AuthServiceClient.cs +++ b/src/D2L.Security.OAuth2/Provisioning/Default/AuthServiceClient.cs @@ -49,7 +49,7 @@ internal sealed class AuthServiceClient : IAuthServiceClient { /// An http client used to communicate with the auth service. /// The token provisioning endpoint on the auth service public AuthServiceClient( - ID2LHttpClient httpClient, + HttpClient httpClient, Uri authEndpoint ) { if( httpClient == null ) { @@ -60,7 +60,7 @@ Uri authEndpoint throw new ArgumentNullException( "authEndpoint" ); } - m_client = httpClient; + m_client = new D2LHttpClient( httpClient ); m_tokenProvisioningEndpoint = authEndpoint.RelativePathAsNonLeaf( TOKEN_PATH ); } diff --git a/src/D2L.Security.OAuth2/Utilities/D2LHttpClient.cs b/src/D2L.Security.OAuth2/Utilities/D2LHttpClient.cs index e3a7fea9..750ea9cf 100644 --- a/src/D2L.Security.OAuth2/Utilities/D2LHttpClient.cs +++ b/src/D2L.Security.OAuth2/Utilities/D2LHttpClient.cs @@ -9,17 +9,11 @@ namespace D2L.Security.OAuth2.Utilities { /// TODO: Replace the sync methods which are currently using Task.Run(async verison); task.Wait(); /// With (probably) HttpWebRequest /// - public class D2LHttpClient : ID2LHttpClient { + internal sealed class D2LHttpClient : ID2LHttpClient { private readonly HttpClient m_httpClient; - public D2LHttpClient() { - m_httpClient = new HttpClient(); - } - public D2LHttpClient( HttpMessageHandler handler ) { - m_httpClient = new HttpClient( handler ); - } - public D2LHttpClient( HttpMessageHandler handler, bool disposeHandler ) { - m_httpClient = new HttpClient( handler, disposeHandler ); + public D2LHttpClient( HttpClient httpClient ) { + m_httpClient = httpClient; } public Task GetAsync( string requestUri, HttpCompletionOption completionOption, CancellationToken cancellationToken ) diff --git a/src/D2L.Security.OAuth2/Utilities/ID2LHttpClient.cs b/src/D2L.Security.OAuth2/Utilities/ID2LHttpClient.cs index 16cd82ca..54971dd4 100644 --- a/src/D2L.Security.OAuth2/Utilities/ID2LHttpClient.cs +++ b/src/D2L.Security.OAuth2/Utilities/ID2LHttpClient.cs @@ -8,7 +8,7 @@ namespace D2L.Security.OAuth2.Utilities { /// This interface was created to allow the sync generator in D2L.CodeStyle to strip the async suffix from HttpClient calls /// when it tries to convert async code to sync code. /// - public interface ID2LHttpClient : IDisposable { + internal interface ID2LHttpClient : IDisposable { public Task GetAsync( string requestUri, HttpCompletionOption completionOption, CancellationToken cancellationToken ); public Task GetAsync( Uri requestUri, CancellationToken cancellationToken ); public Task GetAsync( Uri requestUri, HttpCompletionOption completionOption, CancellationToken cancellationToken ); diff --git a/src/D2L.Security.OAuth2/Validation/AccessTokens/AccessTokenValidatorFactory.cs b/src/D2L.Security.OAuth2/Validation/AccessTokens/AccessTokenValidatorFactory.cs index 4d3a9fa9..ab51139f 100644 --- a/src/D2L.Security.OAuth2/Validation/AccessTokens/AccessTokenValidatorFactory.cs +++ b/src/D2L.Security.OAuth2/Validation/AccessTokens/AccessTokenValidatorFactory.cs @@ -38,7 +38,7 @@ IPublicKeyDataProvider publicKeyDataProvider /// The full URI of the remote JWK path /// A new public static IAccessTokenValidator CreateRemoteValidator( - ID2LHttpClient httpClient, + HttpClient httpClient, Uri jwksEndpoint, Uri jwkEndpoint = null ) { diff --git a/test/D2L.Security.OAuth2.Benchmarks/FullStackValidation/FullStackValidationBenchmark.cs b/test/D2L.Security.OAuth2.Benchmarks/FullStackValidation/FullStackValidationBenchmark.cs index b9919c94..9ba682c5 100644 --- a/test/D2L.Security.OAuth2.Benchmarks/FullStackValidation/FullStackValidationBenchmark.cs +++ b/test/D2L.Security.OAuth2.Benchmarks/FullStackValidation/FullStackValidationBenchmark.cs @@ -12,7 +12,8 @@ namespace D2L.Security.OAuth2.Benchmarks.FullStackValidation { internal abstract class FullStackValidationBenchmark : IBenchmark { - private ID2LHttpClient m_httpClient; + private HttpClient m_httpClient; + private D2LHttpClient m_D2LHttpClient; void IDisposable.Dispose() { m_httpClient.Dispose(); @@ -37,7 +38,7 @@ Action IBenchmark.GetRunner() { private void SetUp( out Uri host, out string token, out string id ) { var mockHandler = new MockHttpMessageHandler(); - m_httpClient = new D2LHttpClient( mockHandler ); + m_httpClient = new HttpClient( mockHandler ); host = new Uri( "http://localhost/.well-known/jwks" ); diff --git a/test/D2L.Security.OAuth2.IntegrationTests/Keys/Default/Data/JwksProviderTests.cs b/test/D2L.Security.OAuth2.IntegrationTests/Keys/Default/Data/JwksProviderTests.cs index 4d46c649..78dfaec5 100644 --- a/test/D2L.Security.OAuth2.IntegrationTests/Keys/Default/Data/JwksProviderTests.cs +++ b/test/D2L.Security.OAuth2.IntegrationTests/Keys/Default/Data/JwksProviderTests.cs @@ -72,7 +72,7 @@ private HttpMessageHandler SetupJwkServer( [TestCase( GOOD_PATH_ADDITIONAL_NUMBER )] public async Task RequestJwksAsync_SuccessCase( string goodPath ) { using( var handler = SetupJwkServer( out string host ) ) - using( ID2LHttpClient httpClient = new D2LHttpClient( handler ) ) { + using( HttpClient httpClient = new HttpClient( handler ) ) { IJwksProvider publicKeyProvider = new JwksProvider( httpClient, jwksEndpoint: new Uri( host + goodPath + JWKS_PATH ), @@ -92,7 +92,7 @@ public async Task RequestJwksAsync_SuccessCase( string goodPath ) { [Test] public void RequestJwksAsync_HTML_Throws() { using( var handler = SetupJwkServer( out string host ) ) - using( ID2LHttpClient httpClient = new D2LHttpClient( handler ) ) { + using( HttpClient httpClient = new HttpClient( handler ) ) { IJwksProvider publicKeyProvider = new JwksProvider( httpClient, jwksEndpoint: new Uri( host + HTML_PATH ), @@ -112,7 +112,7 @@ public void RequestJwksAsync_HTML_Throws() { [Test] public void RequestJwksAsync_404_Throws() { using( var handler = SetupJwkServer( out string host ) ) - using( ID2LHttpClient httpClient = new D2LHttpClient( handler ) ) { + using( HttpClient httpClient = new HttpClient( handler ) ) { IJwksProvider publicKeyProvider = new JwksProvider( httpClient, jwksEndpoint: new Uri( host + BAD_PATH ), @@ -130,7 +130,7 @@ public void RequestJwksAsync_404_Throws() { [Test] public void RequestJwksAsync_CantReachServer_Throws() { using( var handler = SetupJwkServer( out string host ) ) - using( ID2LHttpClient httpClient = new D2LHttpClient( handler ) ) { + using( HttpClient httpClient = new HttpClient( handler ) ) { IJwksProvider publicKeyProvider = new JwksProvider( httpClient, jwksEndpoint: new Uri( "http://foo.bar.fakesite.isurehopethisisneveravalidTLD" ), @@ -148,7 +148,7 @@ public void RequestJwksAsync_CantReachServer_Throws() { [Test] public async Task RequestJwkAsync_Success() { using( var handler = SetupJwkServer( out string host, hasJwk: true, jwkStatusCode: HttpStatusCode.OK ) ) - using( ID2LHttpClient httpClient = new D2LHttpClient( handler ) ) { + using( HttpClient httpClient = new HttpClient( handler ) ) { IJwksProvider jwksProvider = new JwksProvider( httpClient, jwksEndpoint: new Uri( host + GOOD_PATH + JWKS_PATH ), @@ -171,7 +171,7 @@ public async Task RequestJwkAsync_Success() { [Test] public async Task RequestJwkAsync_NullJwkEndpoint_Fallback_Success() { using( var handler = SetupJwkServer( out string host, hasJwk: true, jwkStatusCode: HttpStatusCode.OK ) ) - using( ID2LHttpClient httpClient = new D2LHttpClient( handler ) ) { + using( HttpClient httpClient = new HttpClient( handler ) ) { IJwksProvider jwksProvider = new JwksProvider( httpClient, jwksEndpoint: new Uri( host + GOOD_PATH + JWKS_PATH ), @@ -194,7 +194,7 @@ public async Task RequestJwkAsync_NullJwkEndpoint_Fallback_Success() { [Test] public async Task RequestJwkAsync_StringKeyId_Success() { using( var handler = SetupJwkServer( out string host, hasJwk: true, jwkStatusCode: HttpStatusCode.OK ) ) - using( ID2LHttpClient httpClient = new D2LHttpClient( handler ) ) { + using( HttpClient httpClient = new HttpClient( handler ) ) { IJwksProvider jwksProvider = new JwksProvider( httpClient, jwksEndpoint: new Uri( host + GOOD_PATH + JWKS_PATH ), @@ -217,7 +217,7 @@ public async Task RequestJwkAsync_StringKeyId_Success() { [Test] public async Task RequestJwkAsync_StringKeyId_InvalidKeyId_Fallback_DoesNotReturnKey() { using( var handler = SetupJwkServer( out string host, hasJwk: true, jwkStatusCode: HttpStatusCode.OK ) ) - using( ID2LHttpClient httpClient = new D2LHttpClient( handler ) ) { + using( HttpClient httpClient = new HttpClient( handler ) ) { IJwksProvider jwksProvider = new JwksProvider( httpClient, jwksEndpoint: new Uri( host + GOOD_PATH + JWKS_PATH ), @@ -239,7 +239,7 @@ public async Task RequestJwkAsync_StringKeyId_InvalidKeyId_Fallback_DoesNotRetur [Test] public async Task RequestJwkAsync_404_Fallback_Success() { using( var handler = SetupJwkServer( out string host, hasJwk: false, jwkStatusCode: HttpStatusCode.NotFound ) ) - using( ID2LHttpClient httpClient = new D2LHttpClient( handler ) ) { + using( HttpClient httpClient = new HttpClient( handler ) ) { IJwksProvider jwksProvider = new JwksProvider( httpClient, jwksEndpoint: new Uri( host + GOOD_PATH + JWKS_PATH ), @@ -262,7 +262,7 @@ public async Task RequestJwkAsync_404_Fallback_Success() { [Test] public async Task RequestJwkAsync_StringKeyId_404_Fallback_Success() { using( var handler = SetupJwkServer( out string host, hasJwk: false, jwkStatusCode: HttpStatusCode.NotFound ) ) - using( ID2LHttpClient httpClient = new D2LHttpClient( handler ) ) { + using( HttpClient httpClient = new HttpClient( handler ) ) { IJwksProvider jwksProvider = new JwksProvider( httpClient, jwksEndpoint: new Uri( host + GOOD_PATH + JWKS_PATH ), @@ -285,7 +285,7 @@ public async Task RequestJwkAsync_StringKeyId_404_Fallback_Success() { [Test] public async Task RequestJwkAsync_500_Fallback_Success() { using( var handler = SetupJwkServer( out string host, hasJwk: false, jwkStatusCode: HttpStatusCode.InternalServerError ) ) - using( ID2LHttpClient httpClient = new D2LHttpClient( handler ) ) { + using( HttpClient httpClient = new HttpClient( handler ) ) { IJwksProvider jwksProvider = new JwksProvider( httpClient, jwksEndpoint: new Uri( host + GOOD_PATH + JWKS_PATH ), @@ -308,7 +308,7 @@ public async Task RequestJwkAsync_500_Fallback_Success() { [Test] public async Task RequestJwkAsync_StringKeyId_500_Fallback_Success() { using( var handler = SetupJwkServer( out string host, hasJwk: false, jwkStatusCode: HttpStatusCode.InternalServerError ) ) - using( ID2LHttpClient httpClient = new D2LHttpClient( handler ) ) { + using( HttpClient httpClient = new HttpClient( handler ) ) { IJwksProvider jwksProvider = new JwksProvider( httpClient, jwksEndpoint: new Uri( host + GOOD_PATH + JWKS_PATH ), diff --git a/test/D2L.Security.OAuth2.IntegrationTests/TestFramework/TestAccessTokenProviderTests.cs b/test/D2L.Security.OAuth2.IntegrationTests/TestFramework/TestAccessTokenProviderTests.cs index 2fd62cd6..d3e27336 100644 --- a/test/D2L.Security.OAuth2.IntegrationTests/TestFramework/TestAccessTokenProviderTests.cs +++ b/test/D2L.Security.OAuth2.IntegrationTests/TestFramework/TestAccessTokenProviderTests.cs @@ -23,7 +23,7 @@ internal sealed class TestAccessTokenProviderTests { [Test] public async Task TestAccessTokenProvider_TokenIsValid() { - using( var httpClient = new D2LHttpClient() ) { + using( var httpClient = new HttpClient() ) { IAccessTokenProvider provider = TestAccessTokenProviderFactory.Create( httpClient, DEV_AUTH_URL ); IAccessToken token = await provider.ProvisionAccessTokenAsync( testClaimSet, testScopes ).ConfigureAwait( false ); @@ -34,7 +34,7 @@ public async Task TestAccessTokenProvider_TokenIsValid() { [Test] public async Task TestAccessTokenProvider_SuppliedRSAParameters_TokenIsValid() { - using( var httpClient = new D2LHttpClient() ) { + using( var httpClient = new HttpClient() ) { IAccessTokenProvider provider = TestAccessTokenProviderFactory.Create( httpClient, DEV_AUTH_URL, TestStaticKeyProvider.TestKeyId, TestStaticKeyProvider.TestRSAParameters ); IAccessToken token = await provider.ProvisionAccessTokenAsync( testClaimSet, testScopes ).ConfigureAwait( false ); @@ -47,7 +47,7 @@ public async Task TestAccessTokenProvider_SuppliedRSAParameters_TokenIsValid() { public void TestAccessTokenProvider_InvalidRSAParameters_TokenIsInvalid() { var randomRsaParameters = new RSACryptoServiceProvider( OAuth2.Keys.Constants.GENERATED_RSA_KEY_SIZE ) { PersistKeyInCsp = false }.ExportParameters( true ); - using( var httpClient = new D2LHttpClient() ) { + using( var httpClient = new HttpClient() ) { IAccessTokenProvider provider = TestAccessTokenProviderFactory.Create( httpClient, DEV_AUTH_URL, Guid.NewGuid().ToString(), randomRsaParameters ); Assert.ThrowsAsync( async () => await provider.ProvisionAccessTokenAsync( testClaimSet, testScopes ).ConfigureAwait( false ) ); } diff --git a/test/D2L.Security.OAuth2.IntegrationTests/TestFramework/TestAccessTokenTests.cs b/test/D2L.Security.OAuth2.IntegrationTests/TestFramework/TestAccessTokenTests.cs index 85bde0a7..d01c9b1a 100644 --- a/test/D2L.Security.OAuth2.IntegrationTests/TestFramework/TestAccessTokenTests.cs +++ b/test/D2L.Security.OAuth2.IntegrationTests/TestFramework/TestAccessTokenTests.cs @@ -18,7 +18,7 @@ internal sealed class TestAccessTokenTests { public async Task TestGetToken_WithTenantID_IsValid() { string token = await TestAccessToken.GetToken( DEV_AUTH_URL, Guid.NewGuid().ToString() ).ConfigureAwait( false ); - using( var httpClient = new D2LHttpClient() ) { + using( var httpClient = new HttpClient() ) { IAccessTokenValidator validator = AccessTokenValidatorFactory.CreateRemoteValidator( httpClient, new Uri( DEV_AUTH_URL ), new Uri( DEV_AUTH_JWK_URL ) ); Assert.DoesNotThrowAsync( async () => await validator.ValidateAsync( token ).ConfigureAwait( false ) ); } @@ -28,7 +28,7 @@ public async Task TestGetToken_WithTenantID_IsValid() { public async Task TestGetToken_WithTenantAndUserIdAndXsrf_IsValid() { string token = await TestAccessToken.GetToken( DEV_AUTH_URL, Guid.NewGuid().ToString(), "user", "xsrf" ).ConfigureAwait( false ); - using( var httpClient = new D2LHttpClient() ) { + using( var httpClient = new HttpClient() ) { IAccessTokenValidator validator = AccessTokenValidatorFactory.CreateRemoteValidator( httpClient, new Uri( DEV_AUTH_URL ), new Uri( DEV_AUTH_JWK_URL ) ); Assert.DoesNotThrowAsync( async () => await validator.ValidateAsync( token ).ConfigureAwait( false ) ); } @@ -41,7 +41,7 @@ public async Task TestGetToken_WithClaimAndScope_IsValid() { Scope[] scopes = { new Scope( "group", "resource", "permission" ) }; string token = await TestAccessToken.GetToken( DEV_AUTH_URL, claims, scopes ).ConfigureAwait( false ); - using( var httpClient = new D2LHttpClient() ) { + using( var httpClient = new HttpClient() ) { IAccessTokenValidator validator = AccessTokenValidatorFactory.CreateRemoteValidator( httpClient, new Uri( DEV_AUTH_URL ), new Uri( DEV_AUTH_JWK_URL ) ); Assert.DoesNotThrowAsync( async () => await validator.ValidateAsync( token ).ConfigureAwait( false ) ); } diff --git a/test/D2L.Security.OAuth2.IntegrationTests/Validation/AccessTokens/AccessTokenValidatorTests.EcDsa.cs b/test/D2L.Security.OAuth2.IntegrationTests/Validation/AccessTokens/AccessTokenValidatorTests.EcDsa.cs index c1213f64..ce82a54f 100644 --- a/test/D2L.Security.OAuth2.IntegrationTests/Validation/AccessTokens/AccessTokenValidatorTests.EcDsa.cs +++ b/test/D2L.Security.OAuth2.IntegrationTests/Validation/AccessTokens/AccessTokenValidatorTests.EcDsa.cs @@ -21,7 +21,7 @@ internal sealed class EcDsa { public void TestFixtureSetUp() { m_authService = new AuthServiceMock( AuthServiceMock.KeyType.ECDSA_P256 ); m_accessTokenValidator = AccessTokenValidatorFactory.CreateRemoteValidator( - new D2LHttpClient( m_authService.MockHandler ), + new HttpClient( m_authService.MockHandler ), new Uri( m_authService.Host, ".well-known/jwks" ) ); @@ -120,7 +120,7 @@ public void ValidateAsync_GoodSignature_Succeeds_WebCrypto( string jwk, string t // The rest of the validation should have otherwise proceeded swimmingly Assert.Throws( () => AccessTokenValidatorFactory - .CreateRemoteValidator( new D2LHttpClient( mockHandler ), new Uri( "http://localhost/.well-known/jwks" ) ) + .CreateRemoteValidator( new HttpClient( mockHandler ), new Uri( "http://localhost/.well-known/jwks" ) ) .ValidateAsync( token ) .ConfigureAwait( false ).GetAwaiter().GetResult() ); diff --git a/test/D2L.Security.OAuth2.IntegrationTests/Validation/AccessTokens/AccessTokenValidatorTests.Rsa.cs b/test/D2L.Security.OAuth2.IntegrationTests/Validation/AccessTokens/AccessTokenValidatorTests.Rsa.cs index 7e24da1a..5c41bc8d 100644 --- a/test/D2L.Security.OAuth2.IntegrationTests/Validation/AccessTokens/AccessTokenValidatorTests.Rsa.cs +++ b/test/D2L.Security.OAuth2.IntegrationTests/Validation/AccessTokens/AccessTokenValidatorTests.Rsa.cs @@ -21,7 +21,7 @@ internal sealed class Rsa { public void TestFixtureSetUp() { m_authService = new AuthServiceMock(); m_accessTokenValidator = AccessTokenValidatorFactory.CreateRemoteValidator( - new D2LHttpClient( m_authService.MockHandler ), + new HttpClient( m_authService.MockHandler ), new Uri( m_authService.Host, ".well-known/jwks" ) ); diff --git a/test/D2L.Security.OAuth2.UnitTests/Provisioning/AccessTokenProviderFactoryTests.cs b/test/D2L.Security.OAuth2.UnitTests/Provisioning/AccessTokenProviderFactoryTests.cs index 41d44260..fa96e067 100644 --- a/test/D2L.Security.OAuth2.UnitTests/Provisioning/AccessTokenProviderFactoryTests.cs +++ b/test/D2L.Security.OAuth2.UnitTests/Provisioning/AccessTokenProviderFactoryTests.cs @@ -30,7 +30,7 @@ public void Create_UserCacheProvided_UserCacheHit() { IAccessTokenProvider accessTokenProvider = AccessTokenProviderFactory.Create( tokenSigner: m_keyManagerMock.Object, - httpClient: new D2LHttpClient(), + httpClient: new HttpClient(), authEndpoint: new Uri( "http://foo.d2l" ), tokenRefreshGracePeriod: TimeSpan.FromMinutes( 2 ) ); @@ -51,7 +51,7 @@ public void Create_ServiceCacheProvided_ServiceCacheHit() { IAccessTokenProvider accessTokenProvider = AccessTokenProviderFactory.Create( tokenSigner: m_keyManagerMock.Object, - httpClient: new D2LHttpClient(), + httpClient: new HttpClient(), authEndpoint: new Uri( "http://foo.d2l" ), tokenRefreshGracePeriod: TimeSpan.FromMinutes( 2 ) ); diff --git a/test/D2L.Security.OAuth2.UnitTests/Provisioning/AuthServiceClientTests.cs b/test/D2L.Security.OAuth2.UnitTests/Provisioning/AuthServiceClientTests.cs index 1e551a2b..415112af 100644 --- a/test/D2L.Security.OAuth2.UnitTests/Provisioning/AuthServiceClientTests.cs +++ b/test/D2L.Security.OAuth2.UnitTests/Provisioning/AuthServiceClientTests.cs @@ -122,7 +122,7 @@ await RunTest_ExpectSuccess( } private async Task RunTest_ExpectServiceException( - ID2LHttpClient mockClient, + HttpClient mockClient, ServiceErrorType expectedErrorType, string expectedMessage = null ) { @@ -141,14 +141,14 @@ private async Task RunTest_ExpectServiceException( } private async Task RunTest_ExpectSuccess( - ID2LHttpClient mockClient, + HttpClient mockClient, string expectedToken ) { IAccessToken token = await RunTestHelper( mockClient ); Assert.AreEqual( expectedToken, token.Token ); } - private async Task RunTestHelper( ID2LHttpClient mockClient ) { + private async Task RunTestHelper( HttpClient mockClient ) { IAuthServiceClient client = new AuthServiceClient( httpClient: mockClient, authEndpoint: new Uri( TEST_URI ) diff --git a/test/D2L.Security.OAuth2.UnitTests/Provisioning/Default/AuthServiceClientTests.cs b/test/D2L.Security.OAuth2.UnitTests/Provisioning/Default/AuthServiceClientTests.cs index 9bd9b662..bfba3c59 100644 --- a/test/D2L.Security.OAuth2.UnitTests/Provisioning/Default/AuthServiceClientTests.cs +++ b/test/D2L.Security.OAuth2.UnitTests/Provisioning/Default/AuthServiceClientTests.cs @@ -103,7 +103,7 @@ public async Task CorrectlyReadsResponse() { } } - private static ID2LHttpClient CreateMockedHttpClient( + private static HttpClient CreateMockedHttpClient( Action requestBodyReceiver, HttpStatusCode responseStatus = HttpStatusCode.OK, string responseContent = TestData.ValidHttpResponseBody @@ -126,11 +126,11 @@ private static ID2LHttpClient CreateMockedHttpClient( } ); ; - var httpClient = new D2LHttpClient( messageHandler.Object, true ); + var httpClient = new HttpClient( messageHandler.Object, true ); return httpClient; } - private static IAuthServiceClient CreateClient( ID2LHttpClient httpClient ) { + private static IAuthServiceClient CreateClient( HttpClient httpClient ) { var client = new AuthServiceClient( httpClient: httpClient, authEndpoint: new Uri( "http://foo.d2l" ) diff --git a/test/D2L.Security.OAuth2.UnitTests/Utilities/MockHttpClient.cs b/test/D2L.Security.OAuth2.UnitTests/Utilities/MockHttpClient.cs index f4d6a1cd..cd3e7a0d 100644 --- a/test/D2L.Security.OAuth2.UnitTests/Utilities/MockHttpClient.cs +++ b/test/D2L.Security.OAuth2.UnitTests/Utilities/MockHttpClient.cs @@ -24,7 +24,7 @@ internal static class MockHttpClient { /// The body of the response that the HttpClient should generate /// /// - public static ID2LHttpClient Create( + public static HttpClient Create( HttpStatusCode responseStatus, string responseContent = null ) { @@ -33,7 +33,7 @@ public static ID2LHttpClient Create( response.Content = new StringContent( responseContent ); } - return new D2LHttpClient( + return new HttpClient( new MockResponseHandler( () => response ) ); } @@ -46,10 +46,10 @@ public static ID2LHttpClient Create( /// The exception the HttpClient should throw /// /// - public static ID2LHttpClient Create( + public static HttpClient Create( Exception throwsException ) { - return new D2LHttpClient( + return new HttpClient( new MockResponseHandler( () => { throw throwsException; } ) ); } From a76de109438d9273f74a75d7e8ad4b8cde269898 Mon Sep 17 00:00:00 2001 From: AnaCoda Date: Fri, 21 Jul 2023 13:06:53 -0600 Subject: [PATCH 21/25] Remove stray Utilities imports --- .../TestFramework/TestAccessTokenProviderTests.cs | 1 - .../Validation/AccessTokens/AccessTokenValidatorTests.EcDsa.cs | 1 - .../Validation/AccessTokens/AccessTokenValidatorTests.Rsa.cs | 1 - .../Provisioning/AccessTokenProviderFactoryTests.cs | 1 - .../Provisioning/Default/AuthServiceClientTests.cs | 1 - 5 files changed, 5 deletions(-) diff --git a/test/D2L.Security.OAuth2.IntegrationTests/TestFramework/TestAccessTokenProviderTests.cs b/test/D2L.Security.OAuth2.IntegrationTests/TestFramework/TestAccessTokenProviderTests.cs index d3e27336..9b9377b7 100644 --- a/test/D2L.Security.OAuth2.IntegrationTests/TestFramework/TestAccessTokenProviderTests.cs +++ b/test/D2L.Security.OAuth2.IntegrationTests/TestFramework/TestAccessTokenProviderTests.cs @@ -4,7 +4,6 @@ using System.Threading.Tasks; using D2L.Security.OAuth2.Provisioning; using D2L.Security.OAuth2.Scopes; -using D2L.Security.OAuth2.Utilities; using D2L.Security.OAuth2.Validation.AccessTokens; using NUnit.Framework; using IAccessToken = D2L.Security.OAuth2.Provisioning.IAccessToken; diff --git a/test/D2L.Security.OAuth2.IntegrationTests/Validation/AccessTokens/AccessTokenValidatorTests.EcDsa.cs b/test/D2L.Security.OAuth2.IntegrationTests/Validation/AccessTokens/AccessTokenValidatorTests.EcDsa.cs index ce82a54f..38dacb72 100644 --- a/test/D2L.Security.OAuth2.IntegrationTests/Validation/AccessTokens/AccessTokenValidatorTests.EcDsa.cs +++ b/test/D2L.Security.OAuth2.IntegrationTests/Validation/AccessTokens/AccessTokenValidatorTests.EcDsa.cs @@ -5,7 +5,6 @@ using System.Threading.Tasks; using D2L.Security.OAuth2.Keys; using D2L.Security.OAuth2.TestFramework; -using D2L.Security.OAuth2.Utilities; using D2L.Security.OAuth2.Validation.Exceptions; using NUnit.Framework; using RichardSzalay.MockHttp; diff --git a/test/D2L.Security.OAuth2.IntegrationTests/Validation/AccessTokens/AccessTokenValidatorTests.Rsa.cs b/test/D2L.Security.OAuth2.IntegrationTests/Validation/AccessTokens/AccessTokenValidatorTests.Rsa.cs index 5c41bc8d..7c03b846 100644 --- a/test/D2L.Security.OAuth2.IntegrationTests/Validation/AccessTokens/AccessTokenValidatorTests.Rsa.cs +++ b/test/D2L.Security.OAuth2.IntegrationTests/Validation/AccessTokens/AccessTokenValidatorTests.Rsa.cs @@ -5,7 +5,6 @@ using System.Threading.Tasks; using D2L.Security.OAuth2.Keys; using D2L.Security.OAuth2.TestFramework; -using D2L.Security.OAuth2.Utilities; using D2L.Security.OAuth2.Validation.Exceptions; using NUnit.Framework; diff --git a/test/D2L.Security.OAuth2.UnitTests/Provisioning/AccessTokenProviderFactoryTests.cs b/test/D2L.Security.OAuth2.UnitTests/Provisioning/AccessTokenProviderFactoryTests.cs index fa96e067..beeae241 100644 --- a/test/D2L.Security.OAuth2.UnitTests/Provisioning/AccessTokenProviderFactoryTests.cs +++ b/test/D2L.Security.OAuth2.UnitTests/Provisioning/AccessTokenProviderFactoryTests.cs @@ -7,7 +7,6 @@ using D2L.Security.OAuth2.Keys; using D2L.Security.OAuth2.Provisioning.Default; using D2L.Security.OAuth2.Scopes; -using D2L.Security.OAuth2.Utilities; using Moq; using NUnit.Framework; diff --git a/test/D2L.Security.OAuth2.UnitTests/Provisioning/Default/AuthServiceClientTests.cs b/test/D2L.Security.OAuth2.UnitTests/Provisioning/Default/AuthServiceClientTests.cs index bfba3c59..8c7e1b6a 100644 --- a/test/D2L.Security.OAuth2.UnitTests/Provisioning/Default/AuthServiceClientTests.cs +++ b/test/D2L.Security.OAuth2.UnitTests/Provisioning/Default/AuthServiceClientTests.cs @@ -5,7 +5,6 @@ using System.Threading; using System.Threading.Tasks; using D2L.Security.OAuth2.Scopes; -using D2L.Security.OAuth2.Utilities; using D2L.Services; using Moq; using Moq.Protected; From dede84994ca4c497158951da301702adb6526e3a Mon Sep 17 00:00:00 2001 From: AnaCoda Date: Fri, 21 Jul 2023 13:11:25 -0600 Subject: [PATCH 22/25] Un-"real" asyncify AuthenticateAsync( HttpRequestMessage ) --- .../Validation/Request/RequestAuthenticator.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/D2L.Security.OAuth2/Validation/Request/RequestAuthenticator.cs b/src/D2L.Security.OAuth2/Validation/Request/RequestAuthenticator.cs index 1e7cb7d3..eb66bf91 100644 --- a/src/D2L.Security.OAuth2/Validation/Request/RequestAuthenticator.cs +++ b/src/D2L.Security.OAuth2/Validation/Request/RequestAuthenticator.cs @@ -16,12 +16,12 @@ internal RequestAuthenticator( IAccessTokenValidator accessTokenValidator ) { } [GenerateSync] - async Task IRequestAuthenticator.AuthenticateAsync( + Task IRequestAuthenticator.AuthenticateAsync( HttpRequestMessage request ) { string bearerToken = request.GetBearerTokenValue(); - return await AuthenticateAsync( bearerToken ).ConfigureAwait(false); + return AuthenticateAsync( bearerToken ); } [GenerateSync] From d30468ab340b44e587e426e1370d7e381348bfc2 Mon Sep 17 00:00:00 2001 From: AnaCoda Date: Fri, 21 Jul 2023 14:07:04 -0600 Subject: [PATCH 23/25] More remove Utilities import --- .../TestAccessTokenProviderFactory.cs | 1 - .../Provisioning/AccessTokenProviderFactory.cs | 1 - .../Keys/Default/Data/JwksProviderTests.cs | 1 - .../TestFramework/TestAccessTokenTests.cs | 1 - 4 files changed, 4 deletions(-) diff --git a/src/D2L.Security.OAuth2.TestFramework/TestAccessTokenProviderFactory.cs b/src/D2L.Security.OAuth2.TestFramework/TestAccessTokenProviderFactory.cs index 31ab0ef9..d23b8575 100644 --- a/src/D2L.Security.OAuth2.TestFramework/TestAccessTokenProviderFactory.cs +++ b/src/D2L.Security.OAuth2.TestFramework/TestAccessTokenProviderFactory.cs @@ -7,7 +7,6 @@ using D2L.Security.OAuth2.Keys.Development; using D2L.Security.OAuth2.Provisioning; using D2L.Security.OAuth2.Provisioning.Default; -using D2L.Security.OAuth2.Utilities; namespace D2L.Security.OAuth2.TestFramework { public static class TestAccessTokenProviderFactory { diff --git a/src/D2L.Security.OAuth2/Provisioning/AccessTokenProviderFactory.cs b/src/D2L.Security.OAuth2/Provisioning/AccessTokenProviderFactory.cs index f2518752..04aed488 100644 --- a/src/D2L.Security.OAuth2/Provisioning/AccessTokenProviderFactory.cs +++ b/src/D2L.Security.OAuth2/Provisioning/AccessTokenProviderFactory.cs @@ -2,7 +2,6 @@ using System.Net.Http; using D2L.Security.OAuth2.Keys; using D2L.Security.OAuth2.Provisioning.Default; -using D2L.Security.OAuth2.Utilities; namespace D2L.Security.OAuth2.Provisioning { diff --git a/test/D2L.Security.OAuth2.IntegrationTests/Keys/Default/Data/JwksProviderTests.cs b/test/D2L.Security.OAuth2.IntegrationTests/Keys/Default/Data/JwksProviderTests.cs index 78dfaec5..b2c9a9bf 100644 --- a/test/D2L.Security.OAuth2.IntegrationTests/Keys/Default/Data/JwksProviderTests.cs +++ b/test/D2L.Security.OAuth2.IntegrationTests/Keys/Default/Data/JwksProviderTests.cs @@ -2,7 +2,6 @@ using System.Net; using System.Net.Http; using System.Threading.Tasks; -using D2L.Security.OAuth2.Utilities; using D2L.Security.OAuth2.Validation.Exceptions; using NUnit.Framework; using RichardSzalay.MockHttp; diff --git a/test/D2L.Security.OAuth2.IntegrationTests/TestFramework/TestAccessTokenTests.cs b/test/D2L.Security.OAuth2.IntegrationTests/TestFramework/TestAccessTokenTests.cs index d01c9b1a..a5604e8e 100644 --- a/test/D2L.Security.OAuth2.IntegrationTests/TestFramework/TestAccessTokenTests.cs +++ b/test/D2L.Security.OAuth2.IntegrationTests/TestFramework/TestAccessTokenTests.cs @@ -3,7 +3,6 @@ using System.Security.Claims; using System.Threading.Tasks; using D2L.Security.OAuth2.Scopes; -using D2L.Security.OAuth2.Utilities; using D2L.Security.OAuth2.Validation.AccessTokens; using NUnit.Framework; From 95dff1568d4bbcf41df72cb97563867a97bfd256 Mon Sep 17 00:00:00 2001 From: AnaCoda Date: Fri, 21 Jul 2023 15:05:29 -0600 Subject: [PATCH 24/25] Unused or wrong order nits --- src/D2L.Security.OAuth2.TestFramework/TestAccessToken.cs | 2 -- src/D2L.Security.OAuth2/Keys/Default/Data/IJwksProvider.cs | 4 ++-- src/D2L.Security.OAuth2/Keys/Default/Data/JwksProvider.cs | 2 -- src/D2L.Security.OAuth2/Keys/Default/IPublicKeyProvider.cs | 5 ++--- .../Keys/Development/InMemoryPublicKeyDataProvider.cs | 4 ++-- src/D2L.Security.OAuth2/Keys/IPublicKeyDataProvider.cs | 4 ++-- .../Validation/AccessTokens/IAccessTokenValidator.cs | 4 ++-- .../FullStackValidation/FullStackValidationBenchmark.cs | 1 - 8 files changed, 10 insertions(+), 16 deletions(-) diff --git a/src/D2L.Security.OAuth2.TestFramework/TestAccessToken.cs b/src/D2L.Security.OAuth2.TestFramework/TestAccessToken.cs index 57914440..3651c1d7 100644 --- a/src/D2L.Security.OAuth2.TestFramework/TestAccessToken.cs +++ b/src/D2L.Security.OAuth2.TestFramework/TestAccessToken.cs @@ -6,8 +6,6 @@ using System.Threading.Tasks; using D2L.Security.OAuth2.Provisioning; using D2L.Security.OAuth2.Scopes; -using D2L.Security.OAuth2.Utilities; -using D2L.Services; using IAccessToken = D2L.Security.OAuth2.Provisioning.IAccessToken; namespace D2L.Security.OAuth2.TestFramework { diff --git a/src/D2L.Security.OAuth2/Keys/Default/Data/IJwksProvider.cs b/src/D2L.Security.OAuth2/Keys/Default/Data/IJwksProvider.cs index cb549d88..cb1a5767 100644 --- a/src/D2L.Security.OAuth2/Keys/Default/Data/IJwksProvider.cs +++ b/src/D2L.Security.OAuth2/Keys/Default/Data/IJwksProvider.cs @@ -1,5 +1,5 @@ -using D2L.CodeStyle.Annotations; -using System.Threading.Tasks; +using System.Threading.Tasks; +using D2L.CodeStyle.Annotations; namespace D2L.Security.OAuth2.Keys.Default.Data { internal partial interface IJwksProvider { diff --git a/src/D2L.Security.OAuth2/Keys/Default/Data/JwksProvider.cs b/src/D2L.Security.OAuth2/Keys/Default/Data/JwksProvider.cs index 33893870..5fab2a19 100644 --- a/src/D2L.Security.OAuth2/Keys/Default/Data/JwksProvider.cs +++ b/src/D2L.Security.OAuth2/Keys/Default/Data/JwksProvider.cs @@ -1,5 +1,4 @@ using System; -using System.IO; using System.Net; using System.Net.Http; using System.Threading.Tasks; @@ -7,7 +6,6 @@ using D2L.CodeStyle.Annotations; using D2L.Security.OAuth2.Utilities; using D2L.Security.OAuth2.Validation.Exceptions; -using D2L.Services; namespace D2L.Security.OAuth2.Keys.Default.Data { internal sealed partial class JwksProvider : IJwksProvider { diff --git a/src/D2L.Security.OAuth2/Keys/Default/IPublicKeyProvider.cs b/src/D2L.Security.OAuth2/Keys/Default/IPublicKeyProvider.cs index fdc7294c..ccd81aa7 100644 --- a/src/D2L.Security.OAuth2/Keys/Default/IPublicKeyProvider.cs +++ b/src/D2L.Security.OAuth2/Keys/Default/IPublicKeyProvider.cs @@ -1,6 +1,5 @@ -using D2L.CodeStyle.Annotations; -using System; -using System.Threading.Tasks; +using System.Threading.Tasks; +using D2L.CodeStyle.Annotations; namespace D2L.Security.OAuth2.Keys.Default { diff --git a/src/D2L.Security.OAuth2/Keys/Development/InMemoryPublicKeyDataProvider.cs b/src/D2L.Security.OAuth2/Keys/Development/InMemoryPublicKeyDataProvider.cs index 8b80b6f9..39c2dce3 100644 --- a/src/D2L.Security.OAuth2/Keys/Development/InMemoryPublicKeyDataProvider.cs +++ b/src/D2L.Security.OAuth2/Keys/Development/InMemoryPublicKeyDataProvider.cs @@ -1,10 +1,10 @@ -using D2L.CodeStyle.Annotations; -using System; +using System; using System.Collections.Concurrent; using System.Collections.Generic; using System.Collections.ObjectModel; using System.Linq; using System.Threading.Tasks; +using D2L.CodeStyle.Annotations; namespace D2L.Security.OAuth2.Keys.Development { diff --git a/src/D2L.Security.OAuth2/Keys/IPublicKeyDataProvider.cs b/src/D2L.Security.OAuth2/Keys/IPublicKeyDataProvider.cs index a04c2eb2..881d8d50 100644 --- a/src/D2L.Security.OAuth2/Keys/IPublicKeyDataProvider.cs +++ b/src/D2L.Security.OAuth2/Keys/IPublicKeyDataProvider.cs @@ -1,7 +1,7 @@ -using D2L.CodeStyle.Annotations; -using System; +using System; using System.Collections.Generic; using System.Threading.Tasks; +using D2L.CodeStyle.Annotations; namespace D2L.Security.OAuth2.Keys { diff --git a/src/D2L.Security.OAuth2/Validation/AccessTokens/IAccessTokenValidator.cs b/src/D2L.Security.OAuth2/Validation/AccessTokens/IAccessTokenValidator.cs index 4028be70..7c17e2d2 100644 --- a/src/D2L.Security.OAuth2/Validation/AccessTokens/IAccessTokenValidator.cs +++ b/src/D2L.Security.OAuth2/Validation/AccessTokens/IAccessTokenValidator.cs @@ -1,5 +1,5 @@ -using D2L.CodeStyle.Annotations; -using System.Threading.Tasks; +using System.Threading.Tasks; +using D2L.CodeStyle.Annotations; namespace D2L.Security.OAuth2.Validation.AccessTokens { diff --git a/test/D2L.Security.OAuth2.Benchmarks/FullStackValidation/FullStackValidationBenchmark.cs b/test/D2L.Security.OAuth2.Benchmarks/FullStackValidation/FullStackValidationBenchmark.cs index 9ba682c5..0791d614 100644 --- a/test/D2L.Security.OAuth2.Benchmarks/FullStackValidation/FullStackValidationBenchmark.cs +++ b/test/D2L.Security.OAuth2.Benchmarks/FullStackValidation/FullStackValidationBenchmark.cs @@ -13,7 +13,6 @@ namespace D2L.Security.OAuth2.Benchmarks.FullStackValidation { internal abstract class FullStackValidationBenchmark : IBenchmark { private HttpClient m_httpClient; - private D2LHttpClient m_D2LHttpClient; void IDisposable.Dispose() { m_httpClient.Dispose(); From a5654cbea205e386956d5bad6bd083ab1c0f547a Mon Sep 17 00:00:00 2001 From: AnaCoda Date: Fri, 21 Jul 2023 15:37:16 -0600 Subject: [PATCH 25/25] Replace pragma warning with [DangerousMethodUsage.Audited(...)] --- .../Utilities/D2LHttpClient.cs | 15 +++++++++++++-- .../Utilities/ID2LHttpClient.cs | 6 ------ 2 files changed, 13 insertions(+), 8 deletions(-) diff --git a/src/D2L.Security.OAuth2/Utilities/D2LHttpClient.cs b/src/D2L.Security.OAuth2/Utilities/D2LHttpClient.cs index 750ea9cf..d425f171 100644 --- a/src/D2L.Security.OAuth2/Utilities/D2LHttpClient.cs +++ b/src/D2L.Security.OAuth2/Utilities/D2LHttpClient.cs @@ -2,6 +2,7 @@ using System.Net.Http; using System.Threading; using System.Threading.Tasks; +using D2L.CodeStyle.Annotations; namespace D2L.Security.OAuth2.Utilities { /// @@ -42,69 +43,79 @@ public Task SendAsync( HttpRequestMessage request, HttpComp public Task SendAsync( HttpRequestMessage request, HttpCompletionOption completionOption, CancellationToken cancellationToken ) => m_httpClient.SendAsync( request, completionOption, cancellationToken ); -#pragma warning disable D2L0018 // Avoid using dangerous methods + [DangerousMethodUsage.Audited( typeof( Task ), "Run", "Ana DuCristea", "2023-07-23", "Temporary sync implementation of HttpClient for generated sync methods to be replaced later" )] public HttpResponseMessage Get( string requestUri, HttpCompletionOption completionOption, CancellationToken cancellationToken ) { var task = Task.Run( () => m_httpClient.GetAsync( requestUri, completionOption, cancellationToken ) ); task.Wait(); return task.Result; } + [DangerousMethodUsage.Audited( typeof( Task ), "Run", "Ana DuCristea", "2023-07-23", "Temporary sync implementation of HttpClient for generated sync methods to be replaced later" )] public HttpResponseMessage Get( Uri requestUri, CancellationToken cancellationToken ) { var task = Task.Run( () => m_httpClient.GetAsync( requestUri, cancellationToken ) ); task.Wait(); return task.Result; } + [DangerousMethodUsage.Audited( typeof( Task ), "Run", "Ana DuCristea", "2023-07-23", "Temporary sync implementation of HttpClient for generated sync methods to be replaced later" )] public HttpResponseMessage Get( Uri requestUri, HttpCompletionOption completionOption, CancellationToken cancellationToken ) { var task = Task.Run( () => m_httpClient.GetAsync( requestUri, completionOption, cancellationToken ) ); task.Wait(); return task.Result; } + [DangerousMethodUsage.Audited( typeof( Task ), "Run", "Ana DuCristea", "2023-07-23", "Temporary sync implementation of HttpClient for generated sync methods to be replaced later" )] public HttpResponseMessage Get( Uri requestUri, HttpCompletionOption completionOption ) { var task = Task.Run( () => m_httpClient.GetAsync( requestUri, completionOption ) ); task.Wait(); return task.Result; } + [DangerousMethodUsage.Audited( typeof( Task ), "Run", "Ana DuCristea", "2023-07-23", "Temporary sync implementation of HttpClient for generated sync methods to be replaced later" )] public HttpResponseMessage Get( string requestUri, HttpCompletionOption completionOption ) { var task = Task.Run( () => m_httpClient.GetAsync( requestUri, completionOption ) ); task.Wait(); return task.Result; } + [DangerousMethodUsage.Audited( typeof( Task ), "Run", "Ana DuCristea", "2023-07-23", "Temporary sync implementation of HttpClient for generated sync methods to be replaced later" )] public HttpResponseMessage Get( Uri requestUri ) { var task = Task.Run( () => m_httpClient.GetAsync( requestUri ) ); task.Wait(); return task.Result; } + [DangerousMethodUsage.Audited( typeof( Task ), "Run", "Ana DuCristea", "2023-07-23", "Temporary sync implementation of HttpClient for generated sync methods to be replaced later" )] public HttpResponseMessage Get( string requestUri ) { var task = Task.Run( () => m_httpClient.GetAsync( requestUri ) ); task.Wait(); return task.Result; } + [DangerousMethodUsage.Audited( typeof( Task ), "Run", "Ana DuCristea", "2023-07-23", "Temporary sync implementation of HttpClient for generated sync methods to be replaced later" )] public HttpResponseMessage Get( string requestUri, CancellationToken cancellationToken ) { var task = Task.Run( () => m_httpClient.GetAsync( requestUri, cancellationToken ) ); task.Wait(); return task.Result; } + [DangerousMethodUsage.Audited( typeof( Task ), "Run", "Ana DuCristea", "2023-07-23", "Temporary sync implementation of HttpClient for generated sync methods to be replaced later" )] public HttpResponseMessage Send( HttpRequestMessage request ) { var task = Task.Run( () => m_httpClient.SendAsync( request ) ); task.Wait(); return task.Result; } + [DangerousMethodUsage.Audited( typeof( Task ), "Run", "Ana DuCristea", "2023-07-23", "Temporary sync implementation of HttpClient for generated sync methods to be replaced later" )] public HttpResponseMessage Send( HttpRequestMessage request, CancellationToken cancellationToken ) { var task = Task.Run( () => m_httpClient.SendAsync( request, cancellationToken ) ); task.Wait(); return task.Result; } + [DangerousMethodUsage.Audited( typeof( Task ), "Run", "Ana DuCristea", "2023-07-23", "Temporary sync implementation of HttpClient for generated sync methods to be replaced later" )] public HttpResponseMessage Send( HttpRequestMessage request, HttpCompletionOption completionOption ) { var task = Task.Run( () => m_httpClient.SendAsync( request, completionOption ) ); task.Wait(); return task.Result; } + [DangerousMethodUsage.Audited( typeof( Task ), "Run", "Ana DuCristea", "2023-07-23", "Temporary sync implementation of HttpClient for generated sync methods to be replaced later" )] public HttpResponseMessage Send( HttpRequestMessage request, HttpCompletionOption completionOption, CancellationToken cancellationToken ) { var task = Task.Run( () => m_httpClient.SendAsync( request, completionOption, cancellationToken ) ); task.Wait(); return task.Result; } -#pragma warning restore D2L0018 // Avoid using dangerous methods public void Dispose() { m_httpClient.Dispose(); } } diff --git a/src/D2L.Security.OAuth2/Utilities/ID2LHttpClient.cs b/src/D2L.Security.OAuth2/Utilities/ID2LHttpClient.cs index 54971dd4..29c43762 100644 --- a/src/D2L.Security.OAuth2/Utilities/ID2LHttpClient.cs +++ b/src/D2L.Security.OAuth2/Utilities/ID2LHttpClient.cs @@ -28,19 +28,13 @@ internal interface ID2LHttpClient : IDisposable { public HttpResponseMessage Get( string requestUri, CancellationToken cancellationToken ); public Task SendAsync( HttpRequestMessage request ); - public Task SendAsync( HttpRequestMessage request, CancellationToken cancellationToken ); - public Task SendAsync( HttpRequestMessage request, HttpCompletionOption completionOption ); - public Task SendAsync( HttpRequestMessage request, HttpCompletionOption completionOption, CancellationToken cancellationToken ); public HttpResponseMessage Send( HttpRequestMessage request ); - public HttpResponseMessage Send( HttpRequestMessage request, CancellationToken cancellationToken ); - public HttpResponseMessage Send( HttpRequestMessage request, HttpCompletionOption completionOption ); - public HttpResponseMessage Send( HttpRequestMessage request, HttpCompletionOption completionOption, CancellationToken cancellationToken ); } }