Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 4 additions & 1 deletion .editorconfig
Original file line number Diff line number Diff line change
Expand Up @@ -175,6 +175,9 @@ dotnet_diagnostic.CA1845.severity = warning
# CA1846: Prefer AsSpan over Substring
dotnet_diagnostic.CA1846.severity = warning

# CA2007: Consider calling ConfigureAwait on the awaited task
dotnet_diagnostic.CA2007.severity = warning

# CA2008: Do not create tasks without passing a TaskScheduler
dotnet_diagnostic.CA2008.severity = warning

Expand Down Expand Up @@ -250,7 +253,7 @@ dotnet_diagnostic.IDE0161.severity = warning
dotnet_style_allow_multiple_blank_lines_experimental = false
dotnet_diagnostic.IDE2000.severity = warning

[**/{test,samples,perf}/**.{cs,vb}]
[{eng/tools/**.cs,**/{test,samples,perf}/**.cs}]
# CA1018: Mark attributes with AttributeUsageAttribute
dotnet_diagnostic.CA1018.severity = suggestion
# CA1507: Use nameof to express symbol names
Expand Down
6 changes: 6 additions & 0 deletions eng/targets/CSharp.Common.targets
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,12 @@
<!-- Turn off unused usings warning for multi-targeted projects. Fixing them using ifdefs looks worse than ignoring the warnings. -->
<NoWarn Condition="'$(TargetFrameworks)' != ''">$(NoWarn);IDE0005</NoWarn>

<!--
Turn off ConfigureAwait analyzer rule in the projects that are exclusively meant to run in ASP.NET Core or Blazor contexts.
Since we don't have a good way to detect this, we'll use the presence of ns2.0 as a proxy.
-->
<NoWarn Condition="'$(_IsSrcProject)' != 'true' OR !$(TargetFrameworks.Contains('netstandard'))">$(NoWarn);CA2007</NoWarn>

<!-- Enable .NET code style analysis during build for src projects. -->
<EnforceCodeStyleInBuild Condition="'$(EnforceCodeStyleInBuild)' == ''">true</EnforceCodeStyleInBuild>

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -101,7 +101,7 @@ public Task StopAsync(CancellationToken cancellationToken = default)
// Yes, async void. We need to be async. We need to be void. We handle the exceptions in RunAsync
private async void Timer_Tick(object? state)
{
await RunAsync();
await RunAsync().ConfigureAwait(false);
}

// Internal for testing
Expand All @@ -125,7 +125,7 @@ internal async Task RunAsync()
_runTokenSource = cancellation;
cancellation.CancelAfter(timeout);

await RunAsyncCore(cancellation.Token);
await RunAsyncCore(cancellation.Token).ConfigureAwait(false);

Logger.HealthCheckPublisherProcessingEnd(_logger, duration.GetElapsedTime());
}
Expand All @@ -151,7 +151,7 @@ private async Task RunAsyncCore(CancellationToken cancellationToken)
await Task.Yield();

// The health checks service does it's own logging, and doesn't throw exceptions.
var report = await _healthCheckService.CheckHealthAsync(_options.Value.Predicate, cancellationToken);
var report = await _healthCheckService.CheckHealthAsync(_options.Value.Predicate, cancellationToken).ConfigureAwait(false);

var publishers = _publishers;
var tasks = new Task[publishers.Length];
Expand All @@ -160,7 +160,7 @@ private async Task RunAsyncCore(CancellationToken cancellationToken)
tasks[i] = RunPublisherAsync(publishers[i], report, cancellationToken);
}

await Task.WhenAll(tasks);
await Task.WhenAll(tasks).ConfigureAwait(false);
}

private async Task RunPublisherAsync(IHealthCheckPublisher publisher, HealthReport report, CancellationToken cancellationToken)
Expand All @@ -171,7 +171,7 @@ private async Task RunPublisherAsync(IHealthCheckPublisher publisher, HealthRepo
{
Logger.HealthCheckPublisherBegin(_logger, publisher);

await publisher.PublishAsync(report, cancellationToken);
await publisher.PublishAsync(report, cancellationToken).ConfigureAwait(false);
Logger.HealthCheckPublisherEnd(_logger, publisher, duration.GetElapsedTime());
}
catch (OperationCanceledException) when (IsStopping)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ public class AuthenticatorTokenProvider<TUser> : IUserTwoFactorTokenProvider<TUs
/// <returns>True if the user has an authenticator key set, otherwise false.</returns>
public virtual async Task<bool> CanGenerateTwoFactorTokenAsync(UserManager<TUser> manager, TUser user)
{
var key = await manager.GetAuthenticatorKeyAsync(user);
var key = await manager.GetAuthenticatorKeyAsync(user).ConfigureAwait(false);

return !string.IsNullOrWhiteSpace(key);
}
Expand All @@ -47,7 +47,7 @@ public virtual Task<string> GenerateAsync(string purpose, UserManager<TUser> man
/// <returns></returns>
public virtual async Task<bool> ValidateAsync(string purpose, string token, UserManager<TUser> manager, TUser user)
{
var key = await manager.GetAuthenticatorKeyAsync(user);
var key = await manager.GetAuthenticatorKeyAsync(user).ConfigureAwait(false);
int code;
if (key == null || !int.TryParse(token, out code))
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,6 @@ public class DefaultUserConfirmation<TUser> : IUserConfirmation<TUser> where TUs
/// <returns>The <see cref="Task"/> that represents the asynchronous operation, containing the <see cref="IdentityResult"/> of the confirmation operation.</returns>
public virtual async Task<bool> IsConfirmedAsync(UserManager<TUser> manager, TUser user)
{
return await manager.IsEmailConfirmedAsync(user);
return await manager.IsEmailConfirmedAsync(user).ConfigureAwait(false);
}
}
6 changes: 3 additions & 3 deletions src/Identity/Extensions.Core/src/EmailTokenProvider.cs
Original file line number Diff line number Diff line change
Expand Up @@ -20,9 +20,9 @@ public class EmailTokenProvider<TUser> : TotpSecurityStampBasedTokenProvider<TUs
/// <returns>True if the user has an email address set, otherwise false.</returns>
public override async Task<bool> CanGenerateTwoFactorTokenAsync(UserManager<TUser> manager, TUser user)
{
var email = await manager.GetEmailAsync(user);
var email = await manager.GetEmailAsync(user).ConfigureAwait(false);

return !string.IsNullOrWhiteSpace(email) && await manager.IsEmailConfirmedAsync(user);
return !string.IsNullOrWhiteSpace(email) && await manager.IsEmailConfirmedAsync(user).ConfigureAwait(false);
}

/// <summary>
Expand All @@ -35,7 +35,7 @@ public override async Task<bool> CanGenerateTwoFactorTokenAsync(UserManager<TUse
public override async Task<string> GetUserModifierAsync(string purpose, UserManager<TUser> manager,
TUser user)
{
var email = await manager.GetEmailAsync(user);
var email = await manager.GetEmailAsync(user).ConfigureAwait(false);

return $"Email:{purpose}:{email}";
}
Expand Down
6 changes: 3 additions & 3 deletions src/Identity/Extensions.Core/src/PhoneNumberTokenProvider.cs
Original file line number Diff line number Diff line change
Expand Up @@ -33,9 +33,9 @@ public override async Task<bool> CanGenerateTwoFactorTokenAsync(UserManager<TUse
throw new ArgumentNullException(nameof(manager));
}

var phoneNumber = await manager.GetPhoneNumberAsync(user);
var phoneNumber = await manager.GetPhoneNumberAsync(user).ConfigureAwait(false);

return !string.IsNullOrWhiteSpace(phoneNumber) && await manager.IsPhoneNumberConfirmedAsync(user);
return !string.IsNullOrWhiteSpace(phoneNumber) && await manager.IsPhoneNumberConfirmedAsync(user).ConfigureAwait(false);
}

/// <summary>
Expand All @@ -55,7 +55,7 @@ public override async Task<string> GetUserModifierAsync(string purpose, UserMana
throw new ArgumentNullException(nameof(manager));
}

var phoneNumber = await manager.GetPhoneNumberAsync(user);
var phoneNumber = await manager.GetPhoneNumberAsync(user).ConfigureAwait(false);

return $"PhoneNumber:{purpose}:{phoneNumber}";
}
Expand Down
34 changes: 17 additions & 17 deletions src/Identity/Extensions.Core/src/RoleManager.cs
Original file line number Diff line number Diff line change
Expand Up @@ -160,13 +160,13 @@ public virtual async Task<IdentityResult> CreateAsync(TRole role)
{
throw new ArgumentNullException(nameof(role));
}
var result = await ValidateRoleAsync(role);
var result = await ValidateRoleAsync(role).ConfigureAwait(false);
if (!result.Succeeded)
{
return result;
}
await UpdateNormalizedRoleNameAsync(role);
result = await Store.CreateAsync(role, CancellationToken);
await UpdateNormalizedRoleNameAsync(role).ConfigureAwait(false);
result = await Store.CreateAsync(role, CancellationToken).ConfigureAwait(false);
return result;
}

Expand All @@ -179,8 +179,8 @@ public virtual async Task<IdentityResult> CreateAsync(TRole role)
/// </returns>
public virtual async Task UpdateNormalizedRoleNameAsync(TRole role)
{
var name = await GetRoleNameAsync(role);
await Store.SetNormalizedRoleNameAsync(role, NormalizeKey(name), CancellationToken);
var name = await GetRoleNameAsync(role).ConfigureAwait(false);
await Store.SetNormalizedRoleNameAsync(role, NormalizeKey(name), CancellationToken).ConfigureAwait(false);
}

/// <summary>
Expand Down Expand Up @@ -234,7 +234,7 @@ public virtual async Task<bool> RoleExistsAsync(string roleName)
throw new ArgumentNullException(nameof(roleName));
}

return await FindByNameAsync(roleName) != null;
return await FindByNameAsync(roleName).ConfigureAwait(false) != null;
}

/// <summary>
Expand Down Expand Up @@ -288,8 +288,8 @@ public virtual async Task<IdentityResult> SetRoleNameAsync(TRole role, string na
{
ThrowIfDisposed();

await Store.SetRoleNameAsync(role, name, CancellationToken);
await UpdateNormalizedRoleNameAsync(role);
await Store.SetRoleNameAsync(role, name, CancellationToken).ConfigureAwait(false);
await UpdateNormalizedRoleNameAsync(role).ConfigureAwait(false);
return IdentityResult.Success;
}

Expand Down Expand Up @@ -348,8 +348,8 @@ public virtual async Task<IdentityResult> AddClaimAsync(TRole role, Claim claim)
throw new ArgumentNullException(nameof(role));
}

await claimStore.AddClaimAsync(role, claim, CancellationToken);
return await UpdateRoleAsync(role);
await claimStore.AddClaimAsync(role, claim, CancellationToken).ConfigureAwait(false);
return await UpdateRoleAsync(role).ConfigureAwait(false);
}

/// <summary>
Expand All @@ -370,8 +370,8 @@ public virtual async Task<IdentityResult> RemoveClaimAsync(TRole role, Claim cla
throw new ArgumentNullException(nameof(role));
}

await claimStore.RemoveClaimAsync(role, claim, CancellationToken);
return await UpdateRoleAsync(role);
await claimStore.RemoveClaimAsync(role, claim, CancellationToken).ConfigureAwait(false);
return await UpdateRoleAsync(role).ConfigureAwait(false);
}

/// <summary>
Expand Down Expand Up @@ -426,15 +426,15 @@ protected virtual async Task<IdentityResult> ValidateRoleAsync(TRole role)
var errors = new List<IdentityError>();
foreach (var v in RoleValidators)
{
var result = await v.ValidateAsync(this, role);
var result = await v.ValidateAsync(this, role).ConfigureAwait(false);
if (!result.Succeeded)
{
errors.AddRange(result.Errors);
}
}
if (errors.Count > 0)
{
Logger.LogWarning(LoggerEventIds.RoleValidationFailed, "Role {roleId} validation failed: {errors}.", await GetRoleIdAsync(role), string.Join(";", errors.Select(e => e.Code)));
Logger.LogWarning(LoggerEventIds.RoleValidationFailed, "Role {roleId} validation failed: {errors}.", await GetRoleIdAsync(role).ConfigureAwait(false), string.Join(";", errors.Select(e => e.Code)));
return IdentityResult.Failed(errors.ToArray());
}
return IdentityResult.Success;
Expand All @@ -447,13 +447,13 @@ protected virtual async Task<IdentityResult> ValidateRoleAsync(TRole role)
/// <returns>Whether the operation was successful.</returns>
protected virtual async Task<IdentityResult> UpdateRoleAsync(TRole role)
{
var result = await ValidateRoleAsync(role);
var result = await ValidateRoleAsync(role).ConfigureAwait(false);
if (!result.Succeeded)
{
return result;
}
await UpdateNormalizedRoleNameAsync(role);
return await Store.UpdateAsync(role, CancellationToken);
await UpdateNormalizedRoleNameAsync(role).ConfigureAwait(false);
return await Store.UpdateAsync(role, CancellationToken).ConfigureAwait(false);
}

// IRoleClaimStore methods
Expand Down
8 changes: 4 additions & 4 deletions src/Identity/Extensions.Core/src/RoleValidator.cs
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ public virtual async Task<IdentityResult> ValidateAsync(RoleManager<TRole> manag
throw new ArgumentNullException(nameof(role));
}
var errors = new List<IdentityError>();
await ValidateRoleName(manager, role, errors);
await ValidateRoleName(manager, role, errors).ConfigureAwait(false);
if (errors.Count > 0)
{
return IdentityResult.Failed(errors.ToArray());
Expand All @@ -52,16 +52,16 @@ public virtual async Task<IdentityResult> ValidateAsync(RoleManager<TRole> manag
private async Task ValidateRoleName(RoleManager<TRole> manager, TRole role,
ICollection<IdentityError> errors)
{
var roleName = await manager.GetRoleNameAsync(role);
var roleName = await manager.GetRoleNameAsync(role).ConfigureAwait(false);
if (string.IsNullOrWhiteSpace(roleName))
{
errors.Add(Describer.InvalidRoleName(roleName));
}
else
{
var owner = await manager.FindByNameAsync(roleName);
var owner = await manager.FindByNameAsync(roleName).ConfigureAwait(false);
if (owner != null &&
!string.Equals(await manager.GetRoleIdAsync(owner), await manager.GetRoleIdAsync(role)))
!string.Equals(await manager.GetRoleIdAsync(owner).ConfigureAwait(false), await manager.GetRoleIdAsync(role).ConfigureAwait(false)))
{
errors.Add(Describer.DuplicateRoleName(roleName));
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -39,8 +39,8 @@ public virtual async Task<string> GenerateAsync(string purpose, UserManager<TUse
{
throw new ArgumentNullException(nameof(manager));
}
var token = await manager.CreateSecurityTokenAsync(user);
var modifier = await GetUserModifierAsync(purpose, manager, user);
var token = await manager.CreateSecurityTokenAsync(user).ConfigureAwait(false);
var modifier = await GetUserModifierAsync(purpose, manager, user).ConfigureAwait(false);

return Rfc6238AuthenticationService.GenerateCode(token, modifier).ToString("D6", CultureInfo.InvariantCulture);
}
Expand Down Expand Up @@ -69,8 +69,8 @@ public virtual async Task<bool> ValidateAsync(string purpose, string token, User
{
return false;
}
var securityToken = await manager.CreateSecurityTokenAsync(user);
var modifier = await GetUserModifierAsync(purpose, manager, user);
var securityToken = await manager.CreateSecurityTokenAsync(user).ConfigureAwait(false);
var modifier = await GetUserModifierAsync(purpose, manager, user).ConfigureAwait(false);

return securityToken != null && Rfc6238AuthenticationService.ValidateCode(securityToken, code, modifier);
}
Expand All @@ -91,7 +91,7 @@ public virtual async Task<string> GetUserModifierAsync(string purpose, UserManag
{
throw new ArgumentNullException(nameof(manager));
}
var userId = await manager.GetUserIdAsync(user);
var userId = await manager.GetUserIdAsync(user).ConfigureAwait(false);

return $"Totp:{purpose}:{userId}";
}
Expand Down
20 changes: 10 additions & 10 deletions src/Identity/Extensions.Core/src/UserClaimsPrincipalFactory.cs
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,7 @@ public virtual async Task<ClaimsPrincipal> CreateAsync(TUser user)
{
throw new ArgumentNullException(nameof(user));
}
var id = await GenerateClaimsAsync(user);
var id = await GenerateClaimsAsync(user).ConfigureAwait(false);
return new ClaimsPrincipal(id);
}

Expand All @@ -74,16 +74,16 @@ public virtual async Task<ClaimsPrincipal> CreateAsync(TUser user)
/// <returns>The <see cref="Task"/> that represents the asynchronous creation operation, containing the created <see cref="ClaimsIdentity"/>.</returns>
protected virtual async Task<ClaimsIdentity> GenerateClaimsAsync(TUser user)
{
var userId = await UserManager.GetUserIdAsync(user);
var userName = await UserManager.GetUserNameAsync(user);
var userId = await UserManager.GetUserIdAsync(user).ConfigureAwait(false);
var userName = await UserManager.GetUserNameAsync(user).ConfigureAwait(false);
var id = new ClaimsIdentity("Identity.Application", // REVIEW: Used to match Application scheme
Options.ClaimsIdentity.UserNameClaimType,
Options.ClaimsIdentity.RoleClaimType);
id.AddClaim(new Claim(Options.ClaimsIdentity.UserIdClaimType, userId));
id.AddClaim(new Claim(Options.ClaimsIdentity.UserNameClaimType, userName));
if (UserManager.SupportsUserEmail)
{
var email = await UserManager.GetEmailAsync(user);
var email = await UserManager.GetEmailAsync(user).ConfigureAwait(false);
if (!string.IsNullOrEmpty(email))
{
id.AddClaim(new Claim(Options.ClaimsIdentity.EmailClaimType, email));
Expand All @@ -92,11 +92,11 @@ protected virtual async Task<ClaimsIdentity> GenerateClaimsAsync(TUser user)
if (UserManager.SupportsUserSecurityStamp)
{
id.AddClaim(new Claim(Options.ClaimsIdentity.SecurityStampClaimType,
await UserManager.GetSecurityStampAsync(user)));
await UserManager.GetSecurityStampAsync(user).ConfigureAwait(false)));
}
if (UserManager.SupportsUserClaim)
{
id.AddClaims(await UserManager.GetClaimsAsync(user));
id.AddClaims(await UserManager.GetClaimsAsync(user).ConfigureAwait(false));
}
return id;
}
Expand Down Expand Up @@ -142,19 +142,19 @@ public UserClaimsPrincipalFactory(UserManager<TUser> userManager, RoleManager<TR
/// <returns>The <see cref="Task"/> that represents the asynchronous creation operation, containing the created <see cref="ClaimsIdentity"/>.</returns>
protected override async Task<ClaimsIdentity> GenerateClaimsAsync(TUser user)
{
var id = await base.GenerateClaimsAsync(user);
var id = await base.GenerateClaimsAsync(user).ConfigureAwait(false);
if (UserManager.SupportsUserRole)
{
var roles = await UserManager.GetRolesAsync(user);
var roles = await UserManager.GetRolesAsync(user).ConfigureAwait(false);
foreach (var roleName in roles)
{
id.AddClaim(new Claim(Options.ClaimsIdentity.RoleClaimType, roleName));
if (RoleManager.SupportsRoleClaims)
{
var role = await RoleManager.FindByNameAsync(roleName);
var role = await RoleManager.FindByNameAsync(roleName).ConfigureAwait(false);
if (role != null)
{
id.AddClaims(await RoleManager.GetClaimsAsync(role));
id.AddClaims(await RoleManager.GetClaimsAsync(role).ConfigureAwait(false));
}
}
}
Expand Down
Loading