Skip to content

Commit 990f1bb

Browse files
Use [LoggerMessage] for logging
Use [LoggerMessage] to generate all log messages. Fix some incorrect log messages. Remove some redundant using statements. Resolves #624.
1 parent 17ac366 commit 990f1bb

File tree

88 files changed

+2188
-804
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

88 files changed

+2188
-804
lines changed

Directory.Build.props

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,8 +6,6 @@
66
<DefaultNetCoreTargetFramework>net6.0</DefaultNetCoreTargetFramework>
77
<LangVersion>latest</LangVersion>
88
<NoWarn>$(NoWarn);CS1591</NoWarn>
9-
<!-- TODO Actually resolve this by using the logging source generator -->
10-
<NoWarn>$(NoWarn);CA1848</NoWarn>
119
<TreatWarningsAsErrors>true</TreatWarningsAsErrors>
1210
<DebugSymbols>true</DebugSymbols>
1311
<DebugType>portable</DebugType>

src/AspNet.Security.OAuth.AdobeIO/AdobeIOAuthenticationHandler.cs

Lines changed: 21 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@
1414

1515
namespace AspNet.Security.OAuth.AdobeIO;
1616

17-
public class AdobeIOAuthenticationHandler : OAuthHandler<AdobeIOAuthenticationOptions>
17+
public partial class AdobeIOAuthenticationHandler : OAuthHandler<AdobeIOAuthenticationOptions>
1818
{
1919
public AdobeIOAuthenticationHandler(
2020
[NotNull] IOptionsMonitor<AdobeIOAuthenticationOptions> options,
@@ -39,12 +39,7 @@ protected override async Task<AuthenticationTicket> CreateTicketAsync(
3939
using var response = await Backchannel.SendAsync(request, HttpCompletionOption.ResponseHeadersRead, Context.RequestAborted);
4040
if (!response.IsSuccessStatusCode)
4141
{
42-
Logger.LogError("An error occurred while retrieving the user profile: the remote server " +
43-
"returned a {Status} response with the following payload: {Headers} {Body}.",
44-
/* Status: */ response.StatusCode,
45-
/* Headers: */ response.Headers.ToString(),
46-
/* Body: */ await response.Content.ReadAsStringAsync(Context.RequestAborted));
47-
42+
await Log.UserProfileErrorAsync(Logger, response, Context.RequestAborted);
4843
throw new HttpRequestException("An error occurred while retrieving the user profile.");
4944
}
5045

@@ -61,4 +56,23 @@ protected override async Task<AuthenticationTicket> CreateTicketAsync(
6156
/// <inheritdoc/>
6257
protected override string FormatScope([NotNull] IEnumerable<string> scopes)
6358
=> string.Join(',', scopes);
59+
60+
private static partial class Log
61+
{
62+
internal static async Task UserProfileErrorAsync(ILogger logger, HttpResponseMessage response, CancellationToken cancellationToken)
63+
{
64+
UserProfileError(
65+
logger,
66+
response.StatusCode,
67+
response.Headers.ToString(),
68+
await response.Content.ReadAsStringAsync(cancellationToken));
69+
}
70+
71+
[LoggerMessage(1, LogLevel.Error, "An error occurred while retrieving the user profile: the remote server returned a {Status} response with the following payload: {Headers} {Body}.")]
72+
private static partial void UserProfileError(
73+
ILogger logger,
74+
System.Net.HttpStatusCode status,
75+
string headers,
76+
string body);
77+
}
6478
}

src/AspNet.Security.OAuth.Alipay/AlipayAuthenticationHandler.cs

Lines changed: 39 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
*/
66

77
using System.Globalization;
8+
using System.Net;
89
using System.Security.Claims;
910
using System.Security.Cryptography;
1011
using System.Text;
@@ -20,7 +21,7 @@ namespace AspNet.Security.OAuth.Alipay;
2021
/// <summary>
2122
/// Defines a handler for authentication using Alipay.
2223
/// </summary>
23-
public class AlipayAuthenticationHandler : OAuthHandler<AlipayAuthenticationOptions>
24+
public partial class AlipayAuthenticationHandler : OAuthHandler<AlipayAuthenticationOptions>
2425
{
2526
public AlipayAuthenticationHandler(
2627
[NotNull] IOptionsMonitor<AlipayAuthenticationOptions> options,
@@ -69,12 +70,7 @@ protected override async Task<OAuthTokenResponse> ExchangeCodeAsync([NotNull] OA
6970
using var response = await Backchannel.GetAsync(address, HttpCompletionOption.ResponseHeadersRead, Context.RequestAborted);
7071
if (!response.IsSuccessStatusCode)
7172
{
72-
Logger.LogError("An error occurred while retrieving an access token: the remote server " +
73-
"returned a {Status} response with the following payload: {Headers} {Body}.",
74-
/* Status: */ response.StatusCode,
75-
/* Headers: */ response.Headers.ToString(),
76-
/* Body: */ await response.Content.ReadAsStringAsync(Context.RequestAborted));
77-
73+
await Log.AccessTokenError(Logger, response, Context.RequestAborted);
7874
return OAuthTokenResponse.Failed(new Exception("An error occurred while retrieving an access token."));
7975
}
8076

@@ -116,12 +112,7 @@ protected override async Task<AuthenticationTicket> CreateTicketAsync(
116112

117113
if (!response.IsSuccessStatusCode)
118114
{
119-
Logger.LogError("An error occurred while retrieving the user profile: the remote server " +
120-
"returned a {Status} response with the following payload: {Headers} {Body}.",
121-
/* Status: */ response.StatusCode,
122-
/* Headers: */ response.Headers.ToString(),
123-
/* Body: */ await response.Content.ReadAsStringAsync(Context.RequestAborted));
124-
115+
await Log.UserProfileErrorAsync(Logger, response, Context.RequestAborted);
125116
throw new HttpRequestException("An error occurred while retrieving user information.");
126117
}
127118

@@ -239,4 +230,39 @@ protected override string BuildChallengeUrl([NotNull] AuthenticationProperties p
239230

240231
return QueryHelpers.AddQueryString(Options.AuthorizationEndpoint, parameters!);
241232
}
233+
234+
private static partial class Log
235+
{
236+
internal static async Task UserProfileErrorAsync(ILogger logger, HttpResponseMessage response, CancellationToken cancellationToken)
237+
{
238+
UserProfileError(
239+
logger,
240+
response.StatusCode,
241+
response.Headers.ToString(),
242+
await response.Content.ReadAsStringAsync(cancellationToken));
243+
}
244+
245+
internal static async Task AccessTokenError(ILogger logger, HttpResponseMessage response, CancellationToken cancellationToken)
246+
{
247+
AccessTokenError(
248+
logger,
249+
response.StatusCode,
250+
response.Headers.ToString(),
251+
await response.Content.ReadAsStringAsync(cancellationToken));
252+
}
253+
254+
[LoggerMessage(1, LogLevel.Error, "An error occurred while retrieving the user profile: the remote server returned a {Status} response with the following payload: {Headers} {Body}.")]
255+
private static partial void UserProfileError(
256+
ILogger logger,
257+
HttpStatusCode status,
258+
string headers,
259+
string body);
260+
261+
[LoggerMessage(2, LogLevel.Error, "An error occurred while retrieving an access token: the remote server returned a {Status} response with the following payload: {Headers} {Body}.")]
262+
private static partial void AccessTokenError(
263+
ILogger logger,
264+
HttpStatusCode status,
265+
string headers,
266+
string body);
267+
}
242268
}

src/AspNet.Security.OAuth.Amazon/AmazonAuthenticationHandler.cs

Lines changed: 21 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ namespace AspNet.Security.OAuth.Amazon;
1717
/// <summary>
1818
/// Defines a handler for authentication using Amazon.
1919
/// </summary>
20-
public class AmazonAuthenticationHandler : OAuthHandler<AmazonAuthenticationOptions>
20+
public partial class AmazonAuthenticationHandler : OAuthHandler<AmazonAuthenticationOptions>
2121
{
2222
/// <summary>
2323
/// Initializes a new instance of the <see cref="AmazonAuthenticationHandler"/> class.
@@ -55,12 +55,7 @@ protected override async Task<AuthenticationTicket> CreateTicketAsync(
5555
using var response = await Backchannel.SendAsync(request, HttpCompletionOption.ResponseHeadersRead, Context.RequestAborted);
5656
if (!response.IsSuccessStatusCode)
5757
{
58-
Logger.LogError("An error occurred while retrieving the user profile: the remote server " +
59-
"returned a {Status} response with the following payload: {Headers} {Body}.",
60-
/* Status: */ response.StatusCode,
61-
/* Headers: */ response.Headers.ToString(),
62-
/* Body: */ await response.Content.ReadAsStringAsync(Context.RequestAborted));
63-
58+
await Log.UserProfileErrorAsync(Logger, response, Context.RequestAborted);
6459
throw new HttpRequestException("An error occurred while retrieving the user profile from Amazon.");
6560
}
6661

@@ -73,4 +68,23 @@ protected override async Task<AuthenticationTicket> CreateTicketAsync(
7368
await Events.CreatingTicket(context);
7469
return new AuthenticationTicket(context.Principal!, context.Properties, Scheme.Name);
7570
}
71+
72+
private static partial class Log
73+
{
74+
internal static async Task UserProfileErrorAsync(ILogger logger, HttpResponseMessage response, CancellationToken cancellationToken)
75+
{
76+
UserProfileError(
77+
logger,
78+
response.StatusCode,
79+
response.Headers.ToString(),
80+
await response.Content.ReadAsStringAsync(cancellationToken));
81+
}
82+
83+
[LoggerMessage(1, LogLevel.Error, "An error occurred while retrieving the user profile: the remote server returned a {Status} response with the following payload: {Headers} {Body}.")]
84+
private static partial void UserProfileError(
85+
ILogger logger,
86+
System.Net.HttpStatusCode status,
87+
string headers,
88+
string body);
89+
}
7690
}

src/AspNet.Security.OAuth.AmoCrm/AmoCrmAuthenticationHandler.cs

Lines changed: 21 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ namespace AspNet.Security.OAuth.AmoCrm;
1616
/// <summary>
1717
/// Defines a handler for authentication using amoCRM.
1818
/// </summary>
19-
public class AmoCrmAuthenticationHandler : OAuthHandler<AmoCrmAuthenticationOptions>
19+
public partial class AmoCrmAuthenticationHandler : OAuthHandler<AmoCrmAuthenticationOptions>
2020
{
2121
/// <summary>
2222
/// Initializes a new instance of the <see cref="AmoCrmAuthenticationHandler"/> class.
@@ -49,12 +49,7 @@ protected override async Task<AuthenticationTicket> CreateTicketAsync(
4949
using var response = await Backchannel.SendAsync(request, HttpCompletionOption.ResponseHeadersRead, Context.RequestAborted);
5050
if (!response.IsSuccessStatusCode)
5151
{
52-
Logger.LogError("An error occurred while retrieving the user profile: the remote server " +
53-
"returned a {Status} response with the following payload: {Headers} {Body}.",
54-
/* Status: */ response.StatusCode,
55-
/* Headers: */ response.Headers.ToString(),
56-
/* Body: */ await response.Content.ReadAsStringAsync(Context.RequestAborted));
57-
52+
await Log.UserProfileErrorAsync(Logger, response, Context.RequestAborted);
5853
throw new HttpRequestException("An error occurred while retrieving the user profile from amoCRM.");
5954
}
6055

@@ -67,4 +62,23 @@ protected override async Task<AuthenticationTicket> CreateTicketAsync(
6762
await Events.CreatingTicket(context);
6863
return new AuthenticationTicket(context.Principal!, context.Properties, Scheme.Name);
6964
}
65+
66+
private static partial class Log
67+
{
68+
internal static async Task UserProfileErrorAsync(ILogger logger, HttpResponseMessage response, CancellationToken cancellationToken)
69+
{
70+
UserProfileError(
71+
logger,
72+
response.StatusCode,
73+
response.Headers.ToString(),
74+
await response.Content.ReadAsStringAsync(cancellationToken));
75+
}
76+
77+
[LoggerMessage(1, LogLevel.Error, "An error occurred while retrieving the user profile: the remote server returned a {Status} response with the following payload: {Headers} {Body}.")]
78+
private static partial void UserProfileError(
79+
ILogger logger,
80+
System.Net.HttpStatusCode status,
81+
string headers,
82+
string body);
83+
}
7084
}

src/AspNet.Security.OAuth.Apple/AppleAuthenticationHandler.cs

Lines changed: 32 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ namespace AspNet.Security.OAuth.Apple;
1919
/// <summary>
2020
/// Defines a handler for authentication using Apple.
2121
/// </summary>
22-
public class AppleAuthenticationHandler : OAuthHandler<AppleAuthenticationOptions>
22+
public partial class AppleAuthenticationHandler : OAuthHandler<AppleAuthenticationOptions>
2323
{
2424
/// <summary>
2525
/// Initializes a new instance of the <see cref="AppleAuthenticationHandler"/> class.
@@ -69,16 +69,16 @@ protected override async Task<AuthenticationTicket> CreateTicketAsync(
6969
{
7070
string? idToken = tokens.Response!.RootElement.GetString("id_token");
7171

72-
Logger.LogInformation("Creating ticket for Sign in with Apple.");
72+
Log.CreatingTicket(Logger);
7373

7474
if (Logger.IsEnabled(LogLevel.Trace))
7575
{
76-
Logger.LogTrace("Access Token: {AccessToken}", tokens.AccessToken);
77-
Logger.LogTrace("Refresh Token: {RefreshToken}", tokens.RefreshToken);
78-
Logger.LogTrace("Token Type: {TokenType}", tokens.TokenType);
79-
Logger.LogTrace("Expires In: {ExpiresIn}", tokens.ExpiresIn);
80-
Logger.LogTrace("Response: {TokenResponse}", tokens.Response.RootElement);
81-
Logger.LogTrace("ID Token: {IdToken}", idToken);
76+
Log.LogAccessToken(Logger, tokens.AccessToken);
77+
Log.LogRefreshToken(Logger, tokens.RefreshToken);
78+
Log.LogTokenType(Logger, tokens.TokenType);
79+
Log.LogExpiresIn(Logger, tokens.ExpiresIn);
80+
Log.LogTokenResponse(Logger, tokens.Response.RootElement);
81+
Log.LogIdToken(Logger, idToken);
8282
}
8383

8484
if (string.IsNullOrWhiteSpace(idToken))
@@ -364,4 +364,28 @@ private async Task<HandleRequestResult> HandleRemoteAuthenticateAsync(
364364
return HandleRequestResult.Fail("Failed to retrieve user information from remote server.", properties);
365365
}
366366
}
367+
368+
private static partial class Log
369+
{
370+
[LoggerMessage(1, LogLevel.Information, "Creating ticket for Sign in with Apple.")]
371+
internal static partial void CreatingTicket(ILogger logger);
372+
373+
[LoggerMessage(2, LogLevel.Trace, "Access Token: {AccessToken}", SkipEnabledCheck = true)]
374+
internal static partial void LogAccessToken(ILogger logger, string? accessToken);
375+
376+
[LoggerMessage(3, LogLevel.Trace, "Refresh Token: {RefreshToken}", SkipEnabledCheck = true)]
377+
internal static partial void LogRefreshToken(ILogger logger, string? refreshToken);
378+
379+
[LoggerMessage(4, LogLevel.Trace, "Token Type: {TokenType}", SkipEnabledCheck = true)]
380+
internal static partial void LogTokenType(ILogger logger, string? tokenType);
381+
382+
[LoggerMessage(5, LogLevel.Trace, "Expires In: {ExpiresIn}", SkipEnabledCheck = true)]
383+
internal static partial void LogExpiresIn(ILogger logger, string? expiresIn);
384+
385+
[LoggerMessage(6, LogLevel.Trace, "Response: {TokenResponse}", SkipEnabledCheck = true)]
386+
internal static partial void LogTokenResponse(ILogger logger, JsonElement tokenResponse);
387+
388+
[LoggerMessage(7, LogLevel.Trace, "ID Token: {IdToken}", SkipEnabledCheck = true)]
389+
internal static partial void LogIdToken(ILogger logger, string? idToken);
390+
}
367391
}

src/AspNet.Security.OAuth.Apple/Internal/DefaultAppleClientSecretGenerator.cs

Lines changed: 22 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@
1212

1313
namespace AspNet.Security.OAuth.Apple.Internal;
1414

15-
internal sealed class DefaultAppleClientSecretGenerator : AppleClientSecretGenerator
15+
internal sealed partial class DefaultAppleClientSecretGenerator : AppleClientSecretGenerator
1616
{
1717
private readonly IMemoryCache _cache;
1818
private readonly ISystemClock _clock;
@@ -46,11 +46,7 @@ public override async Task<string> GenerateAsync([NotNull] AppleGenerateClientSe
4646
}
4747
catch (Exception ex)
4848
{
49-
_logger.LogError(
50-
ex,
51-
"Failed to generate new client secret for the {SchemeName} authentication scheme.",
52-
context.Scheme.Name);
53-
49+
Log.ClientSecretGenerationFailed(_logger, ex, context.Scheme.Name);
5450
throw;
5551
}
5652
});
@@ -76,10 +72,7 @@ private static string CreateCacheKey(AppleAuthenticationOptions options)
7672
var expiresAt = _clock.UtcNow.Add(context.Options.ClientSecretExpiresAfter).UtcDateTime;
7773
var subject = new Claim("sub", context.Options.ClientId);
7874

79-
_logger.LogDebug(
80-
"Generating new client secret for subject {Subject} that will expire at {ExpiresAt}.",
81-
subject.Value,
82-
expiresAt);
75+
Log.GeneratingNewClientSecret(_logger, subject.Value, expiresAt);
8376

8477
var tokenDescriptor = new SecurityTokenDescriptor()
8578
{
@@ -99,7 +92,7 @@ private static string CreateCacheKey(AppleAuthenticationOptions options)
9992
clientSecret = context.Options.SecurityTokenHandler.CreateToken(tokenDescriptor);
10093
}
10194

102-
_logger.LogTrace("Generated new client secret with value {ClientSecret}.", clientSecret);
95+
Log.GeneratedNewClientSecret(_logger, clientSecret);
10396

10497
return (clientSecret, expiresAt);
10598
}
@@ -131,4 +124,22 @@ private SigningCredentials CreateSigningCredentials(string keyId, ECDsa algorith
131124
CryptoProviderFactory = _cryptoProviderFactory,
132125
};
133126
}
127+
128+
private static partial class Log
129+
{
130+
[LoggerMessage(1, LogLevel.Error, "Failed to generate new client secret for the {SchemeName} authentication scheme.")]
131+
internal static partial void ClientSecretGenerationFailed(
132+
ILogger logger,
133+
Exception exception,
134+
string schemeName);
135+
136+
[LoggerMessage(2, LogLevel.Debug, "Generating new client secret for subject {Subject} that will expire at {ExpiresAt}.")]
137+
internal static partial void GeneratingNewClientSecret(
138+
ILogger logger,
139+
string subject,
140+
DateTime expiresAt);
141+
142+
[LoggerMessage(3, LogLevel.Trace, "Generated new client secret with value {ClientSecret}.")]
143+
internal static partial void GeneratedNewClientSecret(ILogger logger, string clientSecret);
144+
}
134145
}

0 commit comments

Comments
 (0)