Skip to content

Commit b43a42b

Browse files
authored
Merge pull request #56 from coderpatros/fxcop
Perform FxCopy analysis
2 parents a70aa21 + 0ae0dbe commit b43a42b

File tree

22 files changed

+320
-231
lines changed

22 files changed

+320
-231
lines changed

CoderPatros.AuthenticatedHttpClient.AuthorizationHeader.Tests/AuthorizationHeaderAuthenticatedHttpClientTests.cs

Lines changed: 12 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -15,19 +15,21 @@ public class AuthorizationHeaderAuthenticatedHttpClientTests
1515
[Fact]
1616
public async Task TestRequestAddsAuthenticationHeader()
1717
{
18-
var mockHttp = new MockHttpMessageHandler();
19-
mockHttp
20-
.Expect("https://www.example.com")
21-
.WithHeaders("Authorization", "test-value")
22-
.Respond(HttpStatusCode.OK);
23-
var client = AuthorizationHeaderAuthenticatedHttpClient.GetClient(new AuthorizationHeaderAuthenticatedHttpClientOptions
18+
using (var mockHttp = new MockHttpMessageHandler())
2419
{
25-
Value = "test-value"
26-
}, mockHttp);
20+
mockHttp
21+
.Expect("https://www.example.com")
22+
.WithHeaders("Authorization", "test-value")
23+
.Respond(HttpStatusCode.OK);
24+
var client = AuthorizationHeaderAuthenticatedHttpClient.GetClient(new AuthorizationHeaderAuthenticatedHttpClientOptions
25+
{
26+
Value = "test-value"
27+
}, mockHttp);
2728

28-
await client.GetStringAsync("https://www.example.com");
29+
await client.GetStringAsync(new Uri("https://www.example.com")).ConfigureAwait(false);
2930

30-
mockHttp.VerifyNoOutstandingExpectation();
31+
mockHttp.VerifyNoOutstandingExpectation();
32+
}
3133
}
3234
}
3335
}

CoderPatros.AuthenticatedHttpClient.AuthorizationHeader.Tests/CoderPatros.AuthenticatedHttpClient.AuthorizationHeader.Tests.csproj

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,10 @@
77
</PropertyGroup>
88

99
<ItemGroup>
10+
<PackageReference Include="Microsoft.CodeAnalysis.FxCopAnalyzers" Version="2.9.8">
11+
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
12+
<PrivateAssets>all</PrivateAssets>
13+
</PackageReference>
1014
<PackageReference Include="coverlet.msbuild" Version="2.6.1">
1115
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
1216
<PrivateAssets>all</PrivateAssets>

CoderPatros.AuthenticatedHttpClient.AuthorizationHeader/AuthorizationHeaderAuthenticatedHttpMessageHandler.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ public AuthorizationHeaderAuthenticatedHttpMessageHandler(
2424
protected override async Task<HttpResponseMessage> SendAsync(HttpRequestMessage request, CancellationToken cancellationToken)
2525
{
2626
request.Headers.Authorization = _authorizationHeader;
27-
return await base.SendAsync(request, cancellationToken);
27+
return await base.SendAsync(request, cancellationToken).ConfigureAwait(false);
2828
}
2929
}
3030
}

CoderPatros.AuthenticatedHttpClient.AzureAd.Tests/AzureAdAuthenticatedHttpClientTests.cs

Lines changed: 71 additions & 57 deletions
Original file line numberDiff line numberDiff line change
@@ -19,80 +19,94 @@ public class AzureAdAuthenticatedHttpClientTests
1919
[Fact]
2020
public async Task TestRequestHasAuthorizationHeader()
2121
{
22-
var mockHttp = new MockHttpMessageHandler();
23-
mockHttp
24-
.Expect("https://www.example.com")
25-
.WithHeaders("Authorization", "Bearer test-access-token")
26-
.Respond(HttpStatusCode.OK);
27-
var mockMsgHandler = new Mock<AzureAdAuthenticatedHttpMessageHandler>(new AzureAdAuthenticatedHttpClientOptions
22+
using (var mockHttp = new MockHttpMessageHandler())
2823
{
29-
Tenant = "test-tenant",
30-
ClientId = "test-client-id",
31-
AppKey = "test-client-app-key",
32-
ResourceId = "test-resource-id"
33-
}, mockHttp);
34-
mockMsgHandler
35-
.Setup(handler => handler.AcquireAccessTokenAsync())
36-
.Returns(Task.FromResult("test-access-token"));
37-
mockMsgHandler.CallBase = true;
38-
var client = new HttpClient(mockMsgHandler.Object);
24+
mockHttp
25+
.Expect("https://www.example.com")
26+
.WithHeaders("Authorization", "Bearer test-access-token")
27+
.Respond(HttpStatusCode.OK);
28+
var mockMsgHandler = new Mock<AzureAdAuthenticatedHttpMessageHandler>(new AzureAdAuthenticatedHttpClientOptions
29+
{
30+
Tenant = "test-tenant",
31+
ClientId = "test-client-id",
32+
AppKey = "test-client-app-key",
33+
ResourceId = "test-resource-id"
34+
}, mockHttp);
35+
mockMsgHandler
36+
.Setup(handler => handler.AcquireAccessTokenAsync())
37+
.Returns(Task.FromResult("test-access-token"));
38+
mockMsgHandler.CallBase = true;
3939

40-
await client.GetStringAsync("https://www.example.com");
40+
using (var client = new HttpClient(mockMsgHandler.Object))
41+
{
42+
await client.GetStringAsync(new Uri("https://www.example.com")).ConfigureAwait(false);
4143

42-
mockHttp.VerifyNoOutstandingExpectation();
44+
mockHttp.VerifyNoOutstandingExpectation();
45+
}
46+
}
4347
}
4448

4549
[Fact]
4650
public async Task TestRequestRetriesThreeTimesToAcquireAccessToken()
4751
{
48-
var mockHttp = new MockHttpMessageHandler();
49-
mockHttp
50-
.Expect("https://www.example.com")
51-
.WithHeaders("Authorization", "Bearer test-access-token")
52-
.Respond(HttpStatusCode.OK);
53-
var mockMsgHandler = new Mock<AzureAdAuthenticatedHttpMessageHandler>(new AzureAdAuthenticatedHttpClientOptions
52+
using (var mockHttp = new MockHttpMessageHandler())
5453
{
55-
Tenant = "test-tenant",
56-
ClientId = "test-client-id",
57-
AppKey = "test-client-app-key",
58-
ResourceId = "test-resource-id"
59-
}, mockHttp);
60-
mockMsgHandler
61-
.SetupSequence(handler => handler.AcquireAccessTokenAsync())
62-
.Throws(new AdalException("temporarily_unavailable"))
63-
.Throws(new AdalException("temporarily_unavailable"))
64-
.Returns(Task.FromResult("test-access-token"));
65-
mockMsgHandler.CallBase = true;
66-
var client = new HttpClient(mockMsgHandler.Object);
54+
mockHttp
55+
.Expect("https://www.example.com")
56+
.WithHeaders("Authorization", "Bearer test-access-token")
57+
.Respond(HttpStatusCode.OK);
58+
var mockMsgHandler = new Mock<AzureAdAuthenticatedHttpMessageHandler>(new AzureAdAuthenticatedHttpClientOptions
59+
{
60+
Tenant = "test-tenant",
61+
ClientId = "test-client-id",
62+
AppKey = "test-client-app-key",
63+
ResourceId = "test-resource-id"
64+
}, mockHttp);
65+
mockMsgHandler
66+
.SetupSequence(handler => handler.AcquireAccessTokenAsync())
67+
.Throws(new AdalException("temporarily_unavailable"))
68+
.Throws(new AdalException("temporarily_unavailable"))
69+
.Returns(Task.FromResult("test-access-token"));
70+
mockMsgHandler.CallBase = true;
6771

68-
await client.GetStringAsync("https://www.example.com");
72+
using (var client = new HttpClient(mockMsgHandler.Object))
73+
{
74+
await client.GetStringAsync(new Uri("https://www.example.com")).ConfigureAwait(false);
6975

70-
mockHttp.VerifyNoOutstandingExpectation();
71-
}
76+
mockHttp.VerifyNoOutstandingExpectation();
77+
}
78+
}
79+
}
7280

7381
[Fact]
7482
public async Task TestRequestFailsOnRepeatedFailuresToAcquireAccessTokenFailure()
7583
{
76-
var mockHttp = new MockHttpMessageHandler();
77-
mockHttp.Fallback.Respond(req => new HttpResponseMessage(HttpStatusCode.Unauthorized));
78-
var mockMsgHandler = new Mock<AzureAdAuthenticatedHttpMessageHandler>(new AzureAdAuthenticatedHttpClientOptions
84+
using (var mockHttp = new MockHttpMessageHandler())
7985
{
80-
Tenant = "test-tenant",
81-
ClientId = "test-client-id",
82-
AppKey = "test-client-app-key",
83-
ResourceId = "test-resource-id"
84-
}, mockHttp);
85-
mockMsgHandler
86-
.SetupSequence(handler => handler.AcquireAccessTokenAsync())
87-
.Throws(new AdalException("temporarily_unavailable"))
88-
.Throws(new AdalException("temporarily_unavailable"))
89-
.Throws(new AdalException("temporarily_unavailable"));
90-
mockMsgHandler.CallBase = true;
91-
var client = new HttpClient(mockMsgHandler.Object);
86+
mockHttp.Fallback.Respond(req => new HttpResponseMessage(HttpStatusCode.Unauthorized));
87+
var mockMsgHandler = new Mock<AzureAdAuthenticatedHttpMessageHandler>(new AzureAdAuthenticatedHttpClientOptions
88+
{
89+
Tenant = "test-tenant",
90+
ClientId = "test-client-id",
91+
AppKey = "test-client-app-key",
92+
ResourceId = "test-resource-id"
93+
}, mockHttp);
94+
mockMsgHandler
95+
.SetupSequence(handler => handler.AcquireAccessTokenAsync())
96+
.Throws(new AdalException("temporarily_unavailable"))
97+
.Throws(new AdalException("temporarily_unavailable"))
98+
.Throws(new AdalException("temporarily_unavailable"));
99+
mockMsgHandler.CallBase = true;
92100

93-
var exc = await Record.ExceptionAsync(async () => await client.GetStringAsync("https://www.example.com"));
101+
using (var client = new HttpClient(mockMsgHandler.Object))
102+
{
103+
var exc = await Record.ExceptionAsync(
104+
async () => await client.GetStringAsync(new Uri("https://www.example.com")).ConfigureAwait(false)
105+
).ConfigureAwait(false);
94106

95-
Assert.IsType<HttpRequestException>(exc);
96-
}
107+
Assert.IsType<HttpRequestException>(exc);
108+
}
109+
}
110+
}
97111
}
98112
}

CoderPatros.AuthenticatedHttpClient.AzureAd.Tests/CoderPatros.AuthenticatedHttpClient.AzureAd.Tests.csproj

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,10 @@
77
</PropertyGroup>
88

99
<ItemGroup>
10+
<PackageReference Include="Microsoft.CodeAnalysis.FxCopAnalyzers" Version="2.9.8">
11+
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
12+
<PrivateAssets>all</PrivateAssets>
13+
</PackageReference>
1014
<PackageReference Include="coverlet.msbuild" Version="2.8.0">
1115
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
1216
<PrivateAssets>all</PrivateAssets>

CoderPatros.AuthenticatedHttpClient.AzureAd/AzureAdAuthenticatedHttpClient.cs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,12 +6,14 @@ namespace CoderPatros.AuthenticatedHttpClient
66
// https://github.com/Azure-Samples/active-directory-dotnet-daemon/blob/master/TodoListDaemon/Program.cs
77
public static class AzureAdAuthenticatedHttpClient
88
{
9+
[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Reliability", "CA2000:DisposeObjectsBeforeLosingScope")]
910
public static HttpClient GetClient(AzureAdAuthenticatedHttpClientOptions options)
1011
{
1112
var msgHandler = new AzureAdAuthenticatedHttpMessageHandler(options);
1213
return new HttpClient(msgHandler);
1314
}
1415

16+
[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Reliability", "CA2000:DisposeObjectsBeforeLosingScope")]
1517
public static HttpClient GetClient(AzureAdAuthenticatedHttpClientOptions options, HttpMessageHandler innerHandler)
1618
{
1719
var msgHandler = new AzureAdAuthenticatedHttpMessageHandler(options, innerHandler);

CoderPatros.AuthenticatedHttpClient.AzureAd/AzureAdAuthenticatedHttpMessageHandler.cs

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
using System;
2+
using System.Diagnostics.Contracts;
23
using System.Net.Http;
34
using System.Net.Http.Headers;
45
using System.Globalization;
@@ -18,6 +19,8 @@ public class AzureAdAuthenticatedHttpMessageHandler : DelegatingHandler
1819

1920
public AzureAdAuthenticatedHttpMessageHandler(AzureAdAuthenticatedHttpClientOptions options)
2021
{
22+
Contract.Requires(options != null);
23+
2124
_resourceId = options.ResourceId;
2225

2326
var authority = String.Format(CultureInfo.InvariantCulture, options.AadInstance, options.Tenant);
@@ -35,7 +38,7 @@ public AzureAdAuthenticatedHttpMessageHandler(
3538

3639
internal virtual async Task<string> AcquireAccessTokenAsync()
3740
{
38-
var result = await _authContext.AcquireTokenAsync(_resourceId, _clientCredential);
41+
var result = await _authContext.AcquireTokenAsync(_resourceId, _clientCredential).ConfigureAwait(false);
3942
return result?.AccessToken;
4043
}
4144

@@ -55,7 +58,7 @@ private async Task<string> AcquireTokenWithRetriesAsync(CancellationToken cancel
5558
try
5659
{
5760
// ADAL includes an in memory cache, so this call will only send a message to the server if the cached token is expired.
58-
token = await AcquireAccessTokenAsync();
61+
token = await AcquireAccessTokenAsync().ConfigureAwait(false);
5962
}
6063
catch (AdalException ex)
6164
{
@@ -80,7 +83,9 @@ private async Task<string> AcquireTokenWithRetriesAsync(CancellationToken cancel
8083

8184
protected override async Task<HttpResponseMessage> SendAsync(HttpRequestMessage request, CancellationToken cancellationToken)
8285
{
83-
var accessToken = await AcquireTokenWithRetriesAsync(cancellationToken);
86+
Contract.Requires(request != null);
87+
88+
var accessToken = await AcquireTokenWithRetriesAsync(cancellationToken).ConfigureAwait(false);
8489
if (cancellationToken.IsCancellationRequested)
8590
{
8691
return null;
@@ -90,7 +95,7 @@ protected override async Task<HttpResponseMessage> SendAsync(HttpRequestMessage
9095
"Bearer",
9196
accessToken);
9297

93-
return await base.SendAsync(request, cancellationToken);
98+
return await base.SendAsync(request, cancellationToken).ConfigureAwait(false);
9499
}
95100
}
96101
}

CoderPatros.AuthenticatedHttpClient.AzureAd/CoderPatros.AuthenticatedHttpClient.AzureAd.csproj

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,10 @@
1313
</PropertyGroup>
1414

1515
<ItemGroup>
16+
<PackageReference Include="Microsoft.CodeAnalysis.FxCopAnalyzers" Version="2.9.8">
17+
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
18+
<PrivateAssets>all</PrivateAssets>
19+
</PackageReference>
1620
<PackageReference Include="Microsoft.IdentityModel.Clients.ActiveDirectory" Version="5.2.6" />
1721
</ItemGroup>
1822

CoderPatros.AuthenticatedHttpClient.AzureAppServiceManagedIdentity.Tests/AzureAppSericeManagedIdentityAuthenticatedHttpClientTests.cs

Lines changed: 19 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -18,24 +18,28 @@ public class AzureAppServiceManagedIdentityAuthenticatedHttpClientTests
1818
[Fact]
1919
public async Task TestRequestHasAuthorizationHeader()
2020
{
21-
var mockHttp = new MockHttpMessageHandler();
22-
mockHttp
23-
.Expect("https://www.example.com")
24-
.WithHeaders("Authorization", "Bearer test-access-token")
25-
.Respond(HttpStatusCode.OK);
26-
var mockMsgHandler = new Mock<AzureAppServiceManagedIdentityAuthenticatedHttpMessageHandler>(new AzureAppServiceManagedIdentityAuthenticatedHttpClientOptions
21+
using (var mockHttp = new MockHttpMessageHandler())
2722
{
28-
ResourceId = "test-resource-id"
29-
}, mockHttp);
30-
mockMsgHandler
31-
.Setup(handler => handler.GetAccessTokenAsync())
32-
.Returns(Task.FromResult("test-access-token"));
33-
mockMsgHandler.CallBase = true;
34-
var client = new HttpClient(mockMsgHandler.Object);
23+
mockHttp
24+
.Expect("https://www.example.com")
25+
.WithHeaders("Authorization", "Bearer test-access-token")
26+
.Respond(HttpStatusCode.OK);
27+
var mockMsgHandler = new Mock<AzureAppServiceManagedIdentityAuthenticatedHttpMessageHandler>(new AzureAppServiceManagedIdentityAuthenticatedHttpClientOptions
28+
{
29+
ResourceId = "test-resource-id"
30+
}, mockHttp);
31+
mockMsgHandler
32+
.Setup(handler => handler.GetAccessTokenAsync())
33+
.Returns(Task.FromResult("test-access-token"));
34+
mockMsgHandler.CallBase = true;
3535

36-
await client.GetStringAsync("https://www.example.com");
36+
using (var client = new HttpClient(mockMsgHandler.Object))
37+
{
38+
await client.GetStringAsync(new Uri("https://www.example.com")).ConfigureAwait(false);
3739

38-
mockHttp.VerifyNoOutstandingExpectation();
40+
mockHttp.VerifyNoOutstandingExpectation();
41+
}
42+
}
3943
}
4044
}
4145
}

CoderPatros.AuthenticatedHttpClient.AzureAppServiceManagedIdentity.Tests/CoderPatros.AuthenticatedHttpClient.AzureAppServiceManagedIdentity.Tests.csproj

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,10 @@
77
</PropertyGroup>
88

99
<ItemGroup>
10+
<PackageReference Include="Microsoft.CodeAnalysis.FxCopAnalyzers" Version="2.9.8">
11+
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
12+
<PrivateAssets>all</PrivateAssets>
13+
</PackageReference>
1014
<PackageReference Include="coverlet.msbuild" Version="2.8.0">
1115
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
1216
<PrivateAssets>all</PrivateAssets>

0 commit comments

Comments
 (0)