TFA tweaks for templates (#1299)
This commit is contained in:
parent
a72acc93dc
commit
b355f59a01
|
|
@ -7,7 +7,6 @@ using System.Linq;
|
|||
using System.Linq.Expressions;
|
||||
using System.Security.Claims;
|
||||
using System.Threading.Tasks;
|
||||
using Microsoft.AspNetCore.Builder;
|
||||
using Microsoft.AspNetCore.Http;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
using Microsoft.Extensions.Logging;
|
||||
|
|
@ -1890,6 +1889,7 @@ namespace Microsoft.AspNetCore.Identity.Test
|
|||
{
|
||||
IdentityResultAssert.IsSuccess(await manager.RedeemTwoFactorRecoveryCodeAsync(user, code));
|
||||
IdentityResultAssert.IsFailure(await manager.RedeemTwoFactorRecoveryCodeAsync(user, code));
|
||||
Assert.Equal(--numCodes, await manager.CountRecoveryCodesAsync(user));
|
||||
}
|
||||
// One last time to be sure
|
||||
foreach (var code in newCodes)
|
||||
|
|
|
|||
|
|
@ -31,5 +31,13 @@ namespace Microsoft.AspNetCore.Identity
|
|||
/// <param name="cancellationToken">The <see cref="CancellationToken"/> used to propagate notifications that the operation should be canceled.</param>
|
||||
/// <returns>True if the recovery code was found for the user.</returns>
|
||||
Task<bool> RedeemCodeAsync(TUser user, string code, CancellationToken cancellationToken);
|
||||
|
||||
/// <summary>
|
||||
/// Returns how many recovery code are still valid for a user.
|
||||
/// </summary>
|
||||
/// <param name="user">The user who owns the recovery code.</param>
|
||||
/// <param name="cancellationToken">The <see cref="CancellationToken"/> used to propagate notifications that the operation should be canceled.</param>
|
||||
/// <returns>The number of valid recovery codes for the user..</returns>
|
||||
Task<int> CountCodesAsync(TUser user, CancellationToken cancellationToken);
|
||||
}
|
||||
}
|
||||
|
|
@ -2167,7 +2167,7 @@ namespace Microsoft.AspNetCore.Identity
|
|||
/// </summary>
|
||||
/// <param name="user">The user to generate recovery codes for.</param>
|
||||
/// <param name="number">The number of codes to generate.</param>
|
||||
/// <returns>The new recovery codes for the user.</returns>
|
||||
/// <returns>The new recovery codes for the user. Note: there may be less than number returned, as duplicates will be removed.</returns>
|
||||
public virtual async Task<IEnumerable<string>> GenerateNewTwoFactorRecoveryCodesAsync(TUser user, int number)
|
||||
{
|
||||
ThrowIfDisposed();
|
||||
|
|
@ -2183,7 +2183,7 @@ namespace Microsoft.AspNetCore.Identity
|
|||
newCodes.Add(CreateTwoFactorRecoveryCode());
|
||||
}
|
||||
|
||||
await store.ReplaceCodesAsync(user, newCodes, CancellationToken);
|
||||
await store.ReplaceCodesAsync(user, newCodes.Distinct(), CancellationToken);
|
||||
var update = await UpdateAsync(user);
|
||||
if (update.Succeeded)
|
||||
{
|
||||
|
|
@ -2197,9 +2197,7 @@ namespace Microsoft.AspNetCore.Identity
|
|||
/// </summary>
|
||||
/// <returns></returns>
|
||||
protected virtual string CreateTwoFactorRecoveryCode()
|
||||
{
|
||||
return Guid.NewGuid().ToString();
|
||||
}
|
||||
=> Guid.NewGuid().ToString().Substring(0, 8);
|
||||
|
||||
/// <summary>
|
||||
/// Returns whether a recovery code is valid for a user. Note: recovery codes are only valid
|
||||
|
|
@ -2225,6 +2223,23 @@ namespace Microsoft.AspNetCore.Identity
|
|||
return IdentityResult.Failed(ErrorDescriber.RecoveryCodeRedemptionFailed());
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns how many recovery code are still valid for a user.
|
||||
/// </summary>
|
||||
/// <param name="user">The user.</param>
|
||||
/// <returns>How many recovery code are still valid for a user.</returns>
|
||||
public virtual Task<int> CountRecoveryCodesAsync(TUser user)
|
||||
{
|
||||
ThrowIfDisposed();
|
||||
var store = GetRecoveryCodeStore();
|
||||
if (user == null)
|
||||
{
|
||||
throw new ArgumentNullException(nameof(user));
|
||||
}
|
||||
|
||||
return store.CountCodesAsync(user, CancellationToken);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Releases the unmanaged resources used by the role manager and optionally releases the managed resources.
|
||||
/// </summary>
|
||||
|
|
|
|||
|
|
@ -992,9 +992,7 @@ namespace Microsoft.AspNetCore.Identity
|
|||
/// <param name="cancellationToken">The <see cref="CancellationToken"/> used to propagate notifications that the operation should be canceled.</param>
|
||||
/// <returns>The <see cref="Task"/> that represents the asynchronous operation.</returns>
|
||||
public virtual Task SetAuthenticatorKeyAsync(TUser user, string key, CancellationToken cancellationToken)
|
||||
{
|
||||
return SetTokenAsync(user, InternalLoginProvider, AuthenticatorKeyTokenName, key, cancellationToken);
|
||||
}
|
||||
=> SetTokenAsync(user, InternalLoginProvider, AuthenticatorKeyTokenName, key, cancellationToken);
|
||||
|
||||
/// <summary>
|
||||
/// Get the authenticator key for the specified <paramref name="user" />.
|
||||
|
|
@ -1003,8 +1001,29 @@ namespace Microsoft.AspNetCore.Identity
|
|||
/// <param name="cancellationToken">The <see cref="CancellationToken"/> used to propagate notifications that the operation should be canceled.</param>
|
||||
/// <returns>The <see cref="Task"/> that represents the asynchronous operation, containing the security stamp for the specified <paramref name="user"/>.</returns>
|
||||
public virtual Task<string> GetAuthenticatorKeyAsync(TUser user, CancellationToken cancellationToken)
|
||||
=> GetTokenAsync(user, InternalLoginProvider, AuthenticatorKeyTokenName, cancellationToken);
|
||||
|
||||
/// <summary>
|
||||
/// Returns how many recovery code are still valid for a user.
|
||||
/// </summary>
|
||||
/// <param name="user">The user who owns the recovery code.</param>
|
||||
/// <param name="cancellationToken">The <see cref="CancellationToken"/> used to propagate notifications that the operation should be canceled.</param>
|
||||
/// <returns>The number of valid recovery codes for the user..</returns>
|
||||
public virtual async Task<int> CountCodesAsync(TUser user, CancellationToken cancellationToken)
|
||||
{
|
||||
return GetTokenAsync(user, InternalLoginProvider, AuthenticatorKeyTokenName, cancellationToken);
|
||||
cancellationToken.ThrowIfCancellationRequested();
|
||||
ThrowIfDisposed();
|
||||
|
||||
if (user == null)
|
||||
{
|
||||
throw new ArgumentNullException(nameof(user));
|
||||
}
|
||||
var mergedCodes = await GetTokenAsync(user, InternalLoginProvider, RecoveryCodeTokenName, cancellationToken) ?? "";
|
||||
if (mergedCodes.Length > 0)
|
||||
{
|
||||
return mergedCodes.Split(';').Length;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
|
|
|||
|
|
@ -431,5 +431,15 @@ namespace Microsoft.AspNetCore.Identity.InMemory
|
|||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public async Task<int> CountCodesAsync(TUser user, CancellationToken cancellationToken)
|
||||
{
|
||||
var mergedCodes = await GetTokenAsync(user, AuthenticatorStoreLoginProvider, RecoveryCodeTokenName, cancellationToken) ?? "";
|
||||
if (mergedCodes.Length > 0)
|
||||
{
|
||||
return mergedCodes.Split(';').Length;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue