From fe5ae3103e862e8feefabe633324eab7620f9811 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Halil=20=C4=B0brahim=20Kalkan?= Date: Wed, 14 Mar 2018 09:25:42 +0300 Subject: [PATCH] Implemented IUserAuthenticatorKeyStore and IUserTwoFactorRecoveryCodeStore for UserStore. --- .../Abp/Identity/IdentityUserLookupService.cs | 4 +- .../Volo/Abp/Identity/IdentityUserStore.cs | 76 +++++++++++++++++++ .../HttpClientIdentityUserLookupService.cs | 4 +- .../Volo/Abp/Users/IUserLookupService.cs | 4 +- .../Volo/Abp/Users/NullUserLookupService.cs | 4 +- 5 files changed, 84 insertions(+), 8 deletions(-) diff --git a/src/Volo.Abp.Identity.Domain/Volo/Abp/Identity/IdentityUserLookupService.cs b/src/Volo.Abp.Identity.Domain/Volo/Abp/Identity/IdentityUserLookupService.cs index 4d3fb1de80..de92191d63 100644 --- a/src/Volo.Abp.Identity.Domain/Volo/Abp/Identity/IdentityUserLookupService.cs +++ b/src/Volo.Abp.Identity.Domain/Volo/Abp/Identity/IdentityUserLookupService.cs @@ -17,12 +17,12 @@ namespace Volo.Abp.Identity _lookupNormalizer = lookupNormalizer; } - public async Task FindUserByIdAsync(Guid id) + public async Task FindByIdAsync(Guid id) { return (await _userRepository.FindAsync(id)).ToUserInfo(); } - public async Task FindUserByUserNameAsync(string userName) + public async Task FindByUserNameAsync(string userName) { return (await _userRepository.FindByNormalizedUserNameAsync(_lookupNormalizer.Normalize(userName))).ToUserInfo(); } diff --git a/src/Volo.Abp.Identity.Domain/Volo/Abp/Identity/IdentityUserStore.cs b/src/Volo.Abp.Identity.Domain/Volo/Abp/Identity/IdentityUserStore.cs index c7d96bb9e8..0cec26858e 100644 --- a/src/Volo.Abp.Identity.Domain/Volo/Abp/Identity/IdentityUserStore.cs +++ b/src/Volo.Abp.Identity.Domain/Volo/Abp/Identity/IdentityUserStore.cs @@ -29,8 +29,14 @@ namespace Volo.Abp.Identity IUserPhoneNumberStore, IUserTwoFactorStore, IUserAuthenticationTokenStore, + IUserAuthenticatorKeyStore, + IUserTwoFactorRecoveryCodeStore, ITransientDependency { + private const string InternalLoginProvider = "[AspNetUserStore]"; + private const string AuthenticatorKeyTokenName = "AuthenticatorKey"; + private const string RecoveryCodeTokenName = "RecoveryCodes"; + /// /// Gets or sets the for any error that occurred with the current operation. /// @@ -1024,6 +1030,76 @@ namespace Volo.Abp.Identity return user.FindToken(loginProvider, name)?.Value; } + public Task SetAuthenticatorKeyAsync(IdentityUser user, string key, CancellationToken cancellationToken) + { + return SetTokenAsync(user, InternalLoginProvider, AuthenticatorKeyTokenName, key, cancellationToken); + } + + public Task GetAuthenticatorKeyAsync(IdentityUser user, CancellationToken cancellationToken) + { + return GetTokenAsync(user, InternalLoginProvider, AuthenticatorKeyTokenName, cancellationToken); + } + + /// + /// Returns how many recovery code are still valid for a user. + /// + /// The user who owns the recovery code. + /// The used to propagate notifications that the operation should be canceled. + /// The number of valid recovery codes for the user.. + public virtual async Task CountCodesAsync(IdentityUser user, CancellationToken cancellationToken) + { + cancellationToken.ThrowIfCancellationRequested(); + + Check.NotNull(user, nameof(user)); + + var mergedCodes = await GetTokenAsync(user, InternalLoginProvider, RecoveryCodeTokenName, cancellationToken) ?? ""; + if (mergedCodes.Length > 0) + { + return mergedCodes.Split(';').Length; + } + + return 0; + } + + /// + /// Updates the recovery codes for the user while invalidating any previous recovery codes. + /// + /// The user to store new recovery codes for. + /// The new recovery codes for the user. + /// The used to propagate notifications that the operation should be canceled. + /// The new recovery codes for the user. + public virtual Task ReplaceCodesAsync(IdentityUser user, IEnumerable recoveryCodes, CancellationToken cancellationToken) + { + var mergedCodes = string.Join(";", recoveryCodes); + return SetTokenAsync(user, InternalLoginProvider, RecoveryCodeTokenName, mergedCodes, cancellationToken); + } + + /// + /// Returns whether a recovery code is valid for a user. Note: recovery codes are only valid + /// once, and will be invalid after use. + /// + /// The user who owns the recovery code. + /// The recovery code to use. + /// The used to propagate notifications that the operation should be canceled. + /// True if the recovery code was found for the user. + public virtual async Task RedeemCodeAsync(IdentityUser user, string code, CancellationToken cancellationToken) + { + cancellationToken.ThrowIfCancellationRequested(); + + Check.NotNull(user, nameof(user)); + Check.NotNull(code, nameof(code)); + + var mergedCodes = await GetTokenAsync(user, InternalLoginProvider, RecoveryCodeTokenName, cancellationToken) ?? ""; + var splitCodes = mergedCodes.Split(';'); + if (splitCodes.Contains(code)) + { + var updatedCodes = new List(splitCodes.Where(s => s != code)); + await ReplaceCodesAsync(user, updatedCodes, cancellationToken); + return true; + } + return false; + } + public void Dispose() { diff --git a/src/Volo.Abp.Identity.HttpApi.Client/Volo/Abp/Identity/HttpClientIdentityUserLookupService.cs b/src/Volo.Abp.Identity.HttpApi.Client/Volo/Abp/Identity/HttpClientIdentityUserLookupService.cs index ae6b2476c9..8f21dd569b 100644 --- a/src/Volo.Abp.Identity.HttpApi.Client/Volo/Abp/Identity/HttpClientIdentityUserLookupService.cs +++ b/src/Volo.Abp.Identity.HttpApi.Client/Volo/Abp/Identity/HttpClientIdentityUserLookupService.cs @@ -15,13 +15,13 @@ namespace Volo.Abp.Identity _userAppService = userAppService; } - public async Task FindUserByIdAsync(Guid id) + public async Task FindByIdAsync(Guid id) { //TODO: Should return null if not found! return (await _userAppService.GetAsync(id)).ToUserInfo(); } - public async Task FindUserByUserNameAsync(string userName) + public async Task FindByUserNameAsync(string userName) { //TODO: Should return null if not found! //TODO: Search by UserName, not by a general filter! diff --git a/src/Volo.Abp.Users/Volo/Abp/Users/IUserLookupService.cs b/src/Volo.Abp.Users/Volo/Abp/Users/IUserLookupService.cs index 5c2b43161b..8265fd8250 100644 --- a/src/Volo.Abp.Users/Volo/Abp/Users/IUserLookupService.cs +++ b/src/Volo.Abp.Users/Volo/Abp/Users/IUserLookupService.cs @@ -5,9 +5,9 @@ namespace Volo.Abp.Users { public interface IUserLookupService { - Task FindUserByIdAsync(Guid id); + Task FindByIdAsync(Guid id); - Task FindUserByUserNameAsync(string userName); + Task FindByUserNameAsync(string userName); //TODO: Searching users... } diff --git a/src/Volo.Abp.Users/Volo/Abp/Users/NullUserLookupService.cs b/src/Volo.Abp.Users/Volo/Abp/Users/NullUserLookupService.cs index b16e52a704..fbf170085b 100644 --- a/src/Volo.Abp.Users/Volo/Abp/Users/NullUserLookupService.cs +++ b/src/Volo.Abp.Users/Volo/Abp/Users/NullUserLookupService.cs @@ -8,12 +8,12 @@ namespace Volo.Abp.Users { private static readonly Task NullUserResult = Task.FromResult((IUserInfo) null); - public Task FindUserByIdAsync(Guid id) + public Task FindByIdAsync(Guid id) { return NullUserResult; } - public Task FindUserByUserNameAsync(string userName) + public Task FindByUserNameAsync(string userName) { return NullUserResult; }