Implemented IUserAuthenticatorKeyStore for use in two-factor authentication.

This commit is contained in:
JudahGabriel
2018-02-22 09:05:12 -06:00
parent 1f5ee40119
commit 92cf554784
3 changed files with 86 additions and 18 deletions
+5
View File
@@ -72,6 +72,11 @@ namespace RavenDB.Identity
/// </summary>
public virtual bool TwoFactorEnabled { get; set; }
/// <summary>
/// The two-factor authenticator key.
/// </summary>
public string TwoFactorAuthenticatorKey { get; set; }
/// <summary>
/// The roles of the user. To modify the user's roles, use <see cref="UserManager{TUser}.AddToRoleAsync(TUser, string)"/> nad <see cref="UserManager{TUser}.RemoveFromRolesAsync(TUser, IEnumerable{string})"/>.
/// </summary>
+2 -2
View File
@@ -14,11 +14,11 @@
<RepositoryUrl>https://github.com/JudahGabriel/RavenDB.Identity</RepositoryUrl>
<PackageLicenseUrl>https://github.com/JudahGabriel/RavenDB.Identity/blob/master/LICENSE.md</PackageLicenseUrl>
<PackageIconUrl>https://github.com/JudahGabriel/RavenDB.Identity/blob/master/RavenDB.Identity/nuget-icon.png?raw=true</PackageIconUrl>
<copyright>Copyright 2017 BitShuva</copyright>
<copyright>Copyright 2018 BitShuva</copyright>
<GenerateAssemblyConfigurationAttribute>false</GenerateAssemblyConfigurationAttribute>
<GenerateAssemblyCompanyAttribute>false</GenerateAssemblyCompanyAttribute>
<GenerateAssemblyProductAttribute>false</GenerateAssemblyProductAttribute>
<Version>3.0.0</Version>
<Version>3.1.0</Version>
<GeneratePackageOnBuild>False</GeneratePackageOnBuild>
</PropertyGroup>
+79 -16
View File
@@ -27,18 +27,27 @@ namespace RavenDB.Identity
IUserEmailStore<TUser>,
IUserLockoutStore<TUser>,
IUserTwoFactorStore<TUser>,
IUserPhoneNumberStore<TUser>
IUserPhoneNumberStore<TUser>,
IUserAuthenticatorKeyStore<TUser>
where TUser : IdentityUser
{
private bool _disposed;
private readonly Func<IAsyncDocumentSession> getSessionFunc;
private IAsyncDocumentSession _session;
/// <summary>
/// Creates a new user store that uses the Raven document session returned from the specified session fetcher.
/// </summary>
/// <param name="getSession">The function that gets the Raven document session.</param>
public UserStore(Func<IAsyncDocumentSession> getSession)
{
this.getSessionFunc = getSession;
}
/// <summary>
/// Creates a new user store that uses the specified Raven document session.
/// </summary>
/// <param name="session"></param>
public UserStore(IAsyncDocumentSession session)
{
this._session = session;
@@ -46,6 +55,9 @@ namespace RavenDB.Identity
#region IDispoable implementation
/// <summary>
/// Disposes the user store.
/// </summary>
public void Dispose()
{
_disposed = true;
@@ -55,6 +67,7 @@ namespace RavenDB.Identity
#region IUserStore implementation
/// <inheritdoc />
public Task<string> GetUserIdAsync(TUser user, CancellationToken cancellationToken)
{
ThrowIfNullDisposedCancelled(user, cancellationToken);
@@ -62,6 +75,7 @@ namespace RavenDB.Identity
return Task.FromResult(user.Id);
}
/// <inheritdoc />
public Task<string> GetUserNameAsync(TUser user, CancellationToken cancellationToken)
{
ThrowIfNullDisposedCancelled(user, cancellationToken);
@@ -69,6 +83,7 @@ namespace RavenDB.Identity
return Task.FromResult(user.UserName);
}
/// <inheritdoc />
public Task SetUserNameAsync(TUser user, string userName, CancellationToken cancellationToken)
{
ThrowIfNullDisposedCancelled(user, cancellationToken);
@@ -77,6 +92,7 @@ namespace RavenDB.Identity
return Task.CompletedTask;
}
/// <inheritdoc />
public Task<string> GetNormalizedUserNameAsync(TUser user, CancellationToken cancellationToken)
{
ThrowIfNullDisposedCancelled(user, cancellationToken);
@@ -85,6 +101,7 @@ namespace RavenDB.Identity
return Task.FromResult(user.UserName);
}
/// <inheritdoc />
public Task SetNormalizedUserNameAsync(TUser user, string normalizedName, CancellationToken cancellationToken)
{
ThrowIfNullDisposedCancelled(user, cancellationToken);
@@ -93,6 +110,7 @@ namespace RavenDB.Identity
return Task.CompletedTask;
}
/// <inheritdoc />
public async Task<IdentityResult> CreateAsync(TUser user, CancellationToken cancellationToken)
{
ThrowIfNullDisposedCancelled(user, cancellationToken);
@@ -115,6 +133,7 @@ namespace RavenDB.Identity
return IdentityResult.Success;
}
/// <inheritdoc />
public Task<IdentityResult> UpdateAsync(TUser user, CancellationToken cancellationToken)
{
ThrowIfNullDisposedCancelled(user, cancellationToken);
@@ -122,6 +141,7 @@ namespace RavenDB.Identity
return Task.FromResult(IdentityResult.Success);
}
/// <inheritdoc />
public async Task<IdentityResult> DeleteAsync(TUser user, CancellationToken cancellationToken)
{
ThrowIfNullDisposedCancelled(user, cancellationToken);
@@ -138,6 +158,7 @@ namespace RavenDB.Identity
return IdentityResult.Success;
}
/// <inheritdoc />
public Task<TUser> FindByIdAsync(string userId, CancellationToken cancellationToken)
{
ThrowIfDisposedOrCancelled(cancellationToken);
@@ -145,6 +166,7 @@ namespace RavenDB.Identity
return DbSession.LoadAsync<TUser>(userId);
}
/// <inheritdoc />
public async Task<TUser> FindByNameAsync(string normalizedUserName, CancellationToken cancellationToken)
{
ThrowIfDisposedOrCancelled(cancellationToken);
@@ -168,6 +190,7 @@ namespace RavenDB.Identity
#region IUserLoginStore implementation
/// <inheritdoc />
public async Task AddLoginAsync(TUser user, UserLoginInfo login, CancellationToken cancellationToken)
{
ThrowIfNullDisposedCancelled(user, cancellationToken);
@@ -191,6 +214,7 @@ namespace RavenDB.Identity
}
}
/// <inheritdoc />
public async Task RemoveLoginAsync(TUser user, string loginProvider, string providerKey, CancellationToken cancellationToken)
{
ThrowIfNullDisposedCancelled(user, cancellationToken);
@@ -208,6 +232,7 @@ namespace RavenDB.Identity
user.Logins.RemoveAll(x => x.LoginProvider == login.LoginProvider && x.ProviderKey == login.ProviderKey);
}
/// <inheritdoc />
public Task<IList<UserLoginInfo>> GetLoginsAsync(TUser user, CancellationToken cancellationToken)
{
ThrowIfNullDisposedCancelled(user, cancellationToken);
@@ -215,6 +240,7 @@ namespace RavenDB.Identity
return Task.FromResult(user.Logins.ToIList());
}
/// <inheritdoc />
public async Task<TUser> FindByLoginAsync(string loginProvider, string providerKey, CancellationToken cancellationToken)
{
var login = new UserLoginInfo(loginProvider, providerKey, string.Empty);
@@ -232,6 +258,7 @@ namespace RavenDB.Identity
#region IUserClaimStore implementation
/// <inheritdoc />
public Task<IList<Claim>> GetClaimsAsync(TUser user, CancellationToken cancellationToken)
{
ThrowIfNullDisposedCancelled(user, cancellationToken);
@@ -242,6 +269,7 @@ namespace RavenDB.Identity
return Task.FromResult(result);
}
/// <inheritdoc />
public Task AddClaimsAsync(TUser user, IEnumerable<Claim> claims, CancellationToken cancellationToken)
{
ThrowIfNullDisposedCancelled(user, cancellationToken);
@@ -250,6 +278,7 @@ namespace RavenDB.Identity
return Task.CompletedTask;
}
/// <inheritdoc />
public async Task ReplaceClaimAsync(TUser user, Claim claim, Claim newClaim, CancellationToken cancellationToken)
{
ThrowIfNullDisposedCancelled(user, cancellationToken);
@@ -262,6 +291,7 @@ namespace RavenDB.Identity
}
}
/// <inheritdoc />
public Task RemoveClaimsAsync(TUser user, IEnumerable<Claim> claims, CancellationToken cancellationToken)
{
ThrowIfNullDisposedCancelled(user, cancellationToken);
@@ -270,6 +300,7 @@ namespace RavenDB.Identity
return Task.CompletedTask;
}
/// <inheritdoc />
public Task<IList<TUser>> GetUsersForClaimAsync(Claim claim, CancellationToken cancellationToken)
{
ThrowIfDisposedOrCancelled(cancellationToken);
@@ -287,13 +318,7 @@ namespace RavenDB.Identity
#region IUserRoleStore implementation
/// <summary>
/// Adds the user to the specified role.
/// </summary>
/// <param name="user">The user.</param>
/// <param name="roleName">The name of the role.</param>
/// <param name="cancellationToken"></param>
/// <returns></returns>
/// <inheritdoc />
public async Task AddToRoleAsync(TUser user, string roleName, CancellationToken cancellationToken)
{
ThrowIfNullDisposedCancelled(user, cancellationToken);
@@ -320,13 +345,7 @@ namespace RavenDB.Identity
}
}
/// <summary>
/// Removes the user from the specified role.
/// </summary>
/// <param name="user"></param>
/// <param name="roleName"></param>
/// <param name="cancellationToken"></param>
/// <returns></returns>
/// <inheritdoc />
public async Task RemoveFromRoleAsync(TUser user, string roleName, CancellationToken cancellationToken)
{
ThrowIfNullDisposedCancelled(user, cancellationToken);
@@ -341,6 +360,7 @@ namespace RavenDB.Identity
}
}
/// <inheritdoc />
public Task<IList<string>> GetRolesAsync(TUser user, CancellationToken cancellationToken)
{
ThrowIfNullDisposedCancelled(user, cancellationToken);
@@ -348,6 +368,7 @@ namespace RavenDB.Identity
return Task.FromResult<IList<string>>(new List<string>(user.Roles));
}
/// <inheritdoc />
public Task<bool> IsInRoleAsync(TUser user, string roleName, CancellationToken cancellationToken)
{
if (string.IsNullOrEmpty(roleName))
@@ -358,6 +379,7 @@ namespace RavenDB.Identity
return Task.FromResult(user.Roles.Contains(roleName, StringComparer.OrdinalIgnoreCase));
}
/// <inheritdoc />
public Task<IList<TUser>> GetUsersInRoleAsync(string roleName, CancellationToken cancellationToken)
{
ThrowIfDisposedOrCancelled(cancellationToken);
@@ -376,6 +398,7 @@ namespace RavenDB.Identity
#region IUserPasswordStore implementation
/// <inheritdoc />
public Task SetPasswordHashAsync(TUser user, string passwordHash, CancellationToken cancellationToken)
{
ThrowIfNullDisposedCancelled(user, cancellationToken);
@@ -384,6 +407,7 @@ namespace RavenDB.Identity
return Task.CompletedTask;
}
/// <inheritdoc />
public Task<string> GetPasswordHashAsync(TUser user, CancellationToken cancellationToken)
{
ThrowIfNullDisposedCancelled(user, cancellationToken);
@@ -391,6 +415,7 @@ namespace RavenDB.Identity
return Task.FromResult(user.PasswordHash);
}
/// <inheritdoc />
public Task<bool> HasPasswordAsync(TUser user, CancellationToken cancellationToken)
{
ThrowIfNullDisposedCancelled(user, cancellationToken);
@@ -402,6 +427,7 @@ namespace RavenDB.Identity
#region IUserSecurityStampStore implementation
/// <inheritdoc />
public Task SetSecurityStampAsync(TUser user, string stamp, CancellationToken cancellationToken)
{
ThrowIfNullDisposedCancelled(user, cancellationToken);
@@ -410,6 +436,7 @@ namespace RavenDB.Identity
return Task.CompletedTask;
}
/// <inheritdoc />
public Task<string> GetSecurityStampAsync(TUser user, CancellationToken cancellationToken)
{
ThrowIfNullDisposedCancelled(user, cancellationToken);
@@ -421,6 +448,7 @@ namespace RavenDB.Identity
#region IUserEmailStore implementation
/// <inheritdoc />
public Task SetEmailAsync(TUser user, string email, CancellationToken cancellationToken)
{
ThrowIfDisposedOrCancelled(cancellationToken);
@@ -428,6 +456,7 @@ namespace RavenDB.Identity
return Task.CompletedTask;
}
/// <inheritdoc />
public Task<string> GetEmailAsync(TUser user, CancellationToken cancellationToken)
{
ThrowIfNullDisposedCancelled(user, cancellationToken);
@@ -435,6 +464,7 @@ namespace RavenDB.Identity
return Task.FromResult(user.Email);
}
/// <inheritdoc />
public Task<bool> GetEmailConfirmedAsync(TUser user, CancellationToken cancellationToken)
{
ThrowIfNullDisposedCancelled(user, cancellationToken);
@@ -442,6 +472,7 @@ namespace RavenDB.Identity
return Task.FromResult(user.EmailConfirmed);
}
/// <inheritdoc />
public Task SetEmailConfirmedAsync(TUser user, bool confirmed, CancellationToken cancellationToken)
{
ThrowIfNullDisposedCancelled(user, cancellationToken);
@@ -450,6 +481,7 @@ namespace RavenDB.Identity
return Task.CompletedTask;
}
/// <inheritdoc />
public Task<TUser> FindByEmailAsync(string normalizedEmail, CancellationToken cancellationToken)
{
ThrowIfDisposedOrCancelled(cancellationToken);
@@ -458,6 +490,7 @@ namespace RavenDB.Identity
.FirstOrDefaultAsync(u => u.Email == normalizedEmail, cancellationToken);
}
/// <inheritdoc />
public Task<string> GetNormalizedEmailAsync(TUser user, CancellationToken cancellationToken)
{
ThrowIfNullDisposedCancelled(user, cancellationToken);
@@ -466,6 +499,7 @@ namespace RavenDB.Identity
return Task.FromResult(user.Email);
}
/// <inheritdoc />
public Task SetNormalizedEmailAsync(TUser user, string normalizedEmail, CancellationToken cancellationToken)
{
ThrowIfNullDisposedCancelled(user, cancellationToken);
@@ -482,6 +516,7 @@ namespace RavenDB.Identity
#region IUserLockoutStore implementation
/// <inheritdoc />
public Task<DateTimeOffset?> GetLockoutEndDateAsync(TUser user, CancellationToken cancellationToken)
{
ThrowIfNullDisposedCancelled(user, cancellationToken);
@@ -489,6 +524,7 @@ namespace RavenDB.Identity
return Task.FromResult(user.LockoutEndDate);
}
/// <inheritdoc />
public Task SetLockoutEndDateAsync(TUser user, DateTimeOffset? lockoutEnd, CancellationToken cancellationToken)
{
ThrowIfNullDisposedCancelled(user, cancellationToken);
@@ -497,6 +533,7 @@ namespace RavenDB.Identity
return Task.CompletedTask;
}
/// <inheritdoc />
public Task<int> IncrementAccessFailedCountAsync(TUser user, CancellationToken cancellationToken)
{
ThrowIfNullDisposedCancelled(user, cancellationToken);
@@ -505,6 +542,7 @@ namespace RavenDB.Identity
return Task.FromResult(user.AccessFailedCount);
}
/// <inheritdoc />
public Task ResetAccessFailedCountAsync(TUser user, CancellationToken cancellationToken)
{
ThrowIfNullDisposedCancelled(user, cancellationToken);
@@ -513,6 +551,7 @@ namespace RavenDB.Identity
return Task.CompletedTask;
}
/// <inheritdoc />
public Task<int> GetAccessFailedCountAsync(TUser user, CancellationToken cancellationToken)
{
ThrowIfNullDisposedCancelled(user, cancellationToken);
@@ -520,12 +559,14 @@ namespace RavenDB.Identity
return Task.FromResult(user.AccessFailedCount);
}
/// <inheritdoc />
public Task<bool> GetLockoutEnabledAsync(TUser user, CancellationToken cancellationToken)
{
ThrowIfNullDisposedCancelled(user, cancellationToken);
return Task.FromResult(user.LockoutEnabled);
}
/// <inheritdoc />
public Task SetLockoutEnabledAsync(TUser user, bool enabled, CancellationToken cancellationToken)
{
ThrowIfNullDisposedCancelled(user, cancellationToken);
@@ -538,6 +579,7 @@ namespace RavenDB.Identity
#region IUserTwoFactorStore implementation
/// <inheritdoc />
public Task SetTwoFactorEnabledAsync(TUser user, bool enabled, CancellationToken cancellationToken)
{
ThrowIfNullDisposedCancelled(user, cancellationToken);
@@ -546,6 +588,7 @@ namespace RavenDB.Identity
return Task.CompletedTask;
}
/// <inheritdoc />
public Task<bool> GetTwoFactorEnabledAsync(TUser user, CancellationToken cancellationToken)
{
ThrowIfNullDisposedCancelled(user, cancellationToken);
@@ -557,6 +600,7 @@ namespace RavenDB.Identity
#region IUserPhoneNumberStore implementation
/// <inheritdoc />
public Task SetPhoneNumberAsync(TUser user, string phoneNumber, CancellationToken cancellationToken)
{
ThrowIfNullDisposedCancelled(user, cancellationToken);
@@ -565,6 +609,7 @@ namespace RavenDB.Identity
return Task.CompletedTask;
}
/// <inheritdoc />
public Task<string> GetPhoneNumberAsync(TUser user, CancellationToken cancellationToken)
{
ThrowIfNullDisposedCancelled(user, cancellationToken);
@@ -572,6 +617,7 @@ namespace RavenDB.Identity
return Task.FromResult(user.PhoneNumber);
}
/// <inheritdoc />
public Task<bool> GetPhoneNumberConfirmedAsync(TUser user, CancellationToken cancellationToken)
{
ThrowIfNullDisposedCancelled(user, cancellationToken);
@@ -579,6 +625,7 @@ namespace RavenDB.Identity
return Task.FromResult(user.IsPhoneNumberConfirmed);
}
/// <inheritdoc />
public Task SetPhoneNumberConfirmedAsync(TUser user, bool confirmed, CancellationToken cancellationToken)
{
ThrowIfNullDisposedCancelled(user, cancellationToken);
@@ -589,6 +636,23 @@ namespace RavenDB.Identity
#endregion
#region IUserAuthenticatorKeyStore implementation
/// <inheritdoc />
public Task SetAuthenticatorKeyAsync(TUser user, string key, CancellationToken cancellationToken)
{
user.TwoFactorAuthenticatorKey = key;
return Task.CompletedTask;
}
/// <inheritdoc />
public Task<string> GetAuthenticatorKeyAsync(TUser user, CancellationToken cancellationToken)
{
return Task.FromResult(user.TwoFactorAuthenticatorKey);
}
#endregion
private IAsyncDocumentSession DbSession
{
get
@@ -623,6 +687,5 @@ namespace RavenDB.Identity
}
token.ThrowIfCancellationRequested();
}
}
}