diff --git a/RavenDB.Identity/RavenDB.Identity.csproj b/RavenDB.Identity/RavenDB.Identity.csproj index 4344cae..a17b068 100644 --- a/RavenDB.Identity/RavenDB.Identity.csproj +++ b/RavenDB.Identity/RavenDB.Identity.csproj @@ -7,7 +7,7 @@ true RavenDB.Identity RavenDB Identity for ASP.NET Core - RavenDB.Identity + RavenDB.IdentityVT ravendb identity aspnetcore membership authentication nosql authorization https://github.com/JudahGabriel/RavenDB.Identity git @@ -19,7 +19,7 @@ false false false - 6.1 + 16.1 False Raven.Identity Custom IdentityRole types are stored using their type name in the ID. UserStore can now handle custom IdentityRole types. @@ -29,7 +29,7 @@ - + diff --git a/RavenDB.Identity/RoleStore.cs b/RavenDB.Identity/RoleStore.cs index b21e398..ca7e339 100644 --- a/RavenDB.Identity/RoleStore.cs +++ b/RavenDB.Identity/RoleStore.cs @@ -230,7 +230,7 @@ namespace Raven.Identity /// The name of the role. /// The used to propagate notifications that the operation should be canceled. /// The that represents the asynchronous operation. - public Task SetRoleNameAsync(TRole role, string roleName, CancellationToken cancellationToken = default(CancellationToken)) + public async Task SetRoleNameAsync(TRole role, string roleName, CancellationToken cancellationToken = default(CancellationToken)) { cancellationToken.ThrowIfCancellationRequested(); ThrowIfDisposed(); @@ -238,8 +238,11 @@ namespace Raven.Identity { throw new ArgumentNullException(nameof(role)); } - role.Name = roleName; - return Task.CompletedTask; + using (IAsyncDocumentSession session = Store.OpenAsyncSession()) + { + role.Name = roleName; + await session.SaveChangesAsync(cancellationToken); + } } /// @@ -359,7 +362,7 @@ namespace Raven.Identity /// The claim to add to the role. /// The used to propagate notifications that the operation should be canceled. /// The that represents the asynchronous operation. - public Task AddClaimAsync(TRole role, Claim claim, CancellationToken cancellationToken = default(CancellationToken)) + public async Task AddClaimAsync(TRole role, Claim claim, CancellationToken cancellationToken = default(CancellationToken)) { ThrowIfDisposed(); if (role == null) @@ -370,9 +373,12 @@ namespace Raven.Identity { throw new ArgumentNullException(nameof(claim)); } - role.Claims.Add(CreateRoleClaim(role, claim)); - return Task.FromResult(false); + using (IAsyncDocumentSession session = Store.OpenAsyncSession()) + { + role.Claims.Add(CreateRoleClaim(role, claim)); + await session.SaveChangesAsync(cancellationToken); + } } /// @@ -394,12 +400,14 @@ namespace Raven.Identity throw new ArgumentNullException(nameof(claim)); } - await Task.FromResult(0); - - var claims = role.Claims.Where(c => c.ClaimValue == claim.Value).ToList(); - foreach (var c in claims) + using (IAsyncDocumentSession session = Store.OpenAsyncSession()) { - role.Claims.Remove(c); + var claims = role.Claims.Where(c => c.ClaimValue == claim.Value).ToList(); + foreach (var c in claims) + { + role.Claims.Remove(c); + } + await session.SaveChangesAsync(cancellationToken); } } diff --git a/RavenDB.Identity/UserStore.cs b/RavenDB.Identity/UserStore.cs index 3fdb61b..82d260d 100644 --- a/RavenDB.Identity/UserStore.cs +++ b/RavenDB.Identity/UserStore.cs @@ -79,12 +79,16 @@ namespace Raven.Identity } /// - public Task SetUserNameAsync(TUser user, string userName, CancellationToken cancellationToken) + public async Task SetUserNameAsync(TUser user, string userName, CancellationToken cancellationToken) { ThrowIfNullDisposedCancelled(user, cancellationToken); user.UserName = userName; - return Task.CompletedTask; + + using (IAsyncDocumentSession session = _store.OpenAsyncSession()) + { + await session.SaveChangesAsync(cancellationToken); + } } /// @@ -97,12 +101,16 @@ namespace Raven.Identity } /// - public Task SetNormalizedUserNameAsync(TUser user, string normalizedName, CancellationToken cancellationToken) + public async Task SetNormalizedUserNameAsync(TUser user, string normalizedName, CancellationToken cancellationToken) { ThrowIfNullDisposedCancelled(user, cancellationToken); user.UserName = normalizedName.ToLowerInvariant(); - return Task.CompletedTask; + + using (IAsyncDocumentSession session = _store.OpenAsyncSession()) + { + await session.SaveChangesAsync(cancellationToken); + } } /// @@ -164,7 +172,7 @@ namespace Raven.Identity // we need to roll back the email reservation. try { - await session.SaveChangesAsync(); + await session.SaveChangesAsync(cancellationToken); } catch (Exception) { @@ -212,7 +220,7 @@ namespace Raven.Identity using (IAsyncDocumentSession session = _store.OpenAsyncSession()) { session.Delete(user); - await session.SaveChangesAsync(); + await session.SaveChangesAsync(cancellationToken); } return IdentityResult.Success; @@ -281,6 +289,7 @@ namespace Raven.Identity using (IAsyncDocumentSession session = _store.OpenAsyncSession()) { await session.StoreAsync(userLogin); + await session.SaveChangesAsync(cancellationToken); } } } @@ -299,6 +308,7 @@ namespace Raven.Identity if (loginDoc != null) { session.Delete(loginDoc); + await session.SaveChangesAsync(cancellationToken); } } @@ -349,12 +359,15 @@ namespace Raven.Identity } /// - public Task AddClaimsAsync(TUser user, IEnumerable claims, CancellationToken cancellationToken) + public async Task AddClaimsAsync(TUser user, IEnumerable claims, CancellationToken cancellationToken) { ThrowIfNullDisposedCancelled(user, cancellationToken); - user.Claims.AddRange(claims.Select(c => new IdentityUserClaim { ClaimType = c.Type, ClaimValue = c.Value })); - return Task.CompletedTask; + using (IAsyncDocumentSession session = _store.OpenAsyncSession()) + { + user.Claims.AddRange(claims.Select(c => new IdentityUserClaim { ClaimType = c.Type, ClaimValue = c.Value })); + await session.SaveChangesAsync(cancellationToken); + } } /// @@ -366,17 +379,20 @@ namespace Raven.Identity if (indexOfClaim != -1) { user.Claims.RemoveAt(indexOfClaim); - await this.AddClaimsAsync(user, new[] { newClaim }, cancellationToken); + await AddClaimsAsync(user, new[] { newClaim }, cancellationToken); } } /// - public Task RemoveClaimsAsync(TUser user, IEnumerable claims, CancellationToken cancellationToken) + public async Task RemoveClaimsAsync(TUser user, IEnumerable claims, CancellationToken cancellationToken) { ThrowIfNullDisposedCancelled(user, cancellationToken); - user.Claims.RemoveAll(identityClaim => claims.Any(c => c.Type == identityClaim.ClaimType && c.Value == identityClaim.ClaimValue)); - return Task.CompletedTask; + using (IAsyncDocumentSession session = _store.OpenAsyncSession()) + { + user.Claims.RemoveAll(identityClaim => claims.Any(c => c.Type == identityClaim.ClaimType && c.Value == identityClaim.ClaimValue)); + await session.SaveChangesAsync(cancellationToken); + } } /// @@ -434,6 +450,8 @@ namespace Raven.Identity { existingRoleOrNull.Users.Add(user.Id); } + + await session.SaveChangesAsync(cancellationToken); } } @@ -453,6 +471,7 @@ namespace Raven.Identity { roleOrNull.Users.Remove(user.Id); } + await session.SaveChangesAsync(cancellationToken); } } @@ -498,12 +517,15 @@ namespace Raven.Identity #region IUserPasswordStore implementation /// - public Task SetPasswordHashAsync(TUser user, string passwordHash, CancellationToken cancellationToken) + public async Task SetPasswordHashAsync(TUser user, string passwordHash, CancellationToken cancellationToken) { ThrowIfNullDisposedCancelled(user, cancellationToken); - user.PasswordHash = passwordHash; - return Task.CompletedTask; + using (IAsyncDocumentSession session = _store.OpenAsyncSession()) + { + user.PasswordHash = passwordHash; + await session.SaveChangesAsync(cancellationToken); + } } /// @@ -527,12 +549,15 @@ namespace Raven.Identity #region IUserSecurityStampStore implementation /// - public Task SetSecurityStampAsync(TUser user, string stamp, CancellationToken cancellationToken) + public async Task SetSecurityStampAsync(TUser user, string stamp, CancellationToken cancellationToken) { ThrowIfNullDisposedCancelled(user, cancellationToken); - user.SecurityStamp = stamp; - return Task.CompletedTask; + using (IAsyncDocumentSession session = _store.OpenAsyncSession()) + { + user.SecurityStamp = stamp; + await session.SaveChangesAsync(cancellationToken); + } } /// @@ -548,11 +573,14 @@ namespace Raven.Identity #region IUserEmailStore implementation /// - public Task SetEmailAsync(TUser user, string email, CancellationToken cancellationToken) + public async Task SetEmailAsync(TUser user, string email, CancellationToken cancellationToken) { ThrowIfDisposedOrCancelled(cancellationToken); - user.Email = email ?? throw new ArgumentNullException(nameof(email)); - return Task.CompletedTask; + using (IAsyncDocumentSession session = _store.OpenAsyncSession()) + { + user.Email = email ?? throw new ArgumentNullException(nameof(email)); + await session.SaveChangesAsync(cancellationToken); + } } /// @@ -572,12 +600,15 @@ namespace Raven.Identity } /// - public Task SetEmailConfirmedAsync(TUser user, bool confirmed, CancellationToken cancellationToken) + public async Task SetEmailConfirmedAsync(TUser user, bool confirmed, CancellationToken cancellationToken) { ThrowIfNullDisposedCancelled(user, cancellationToken); - user.EmailConfirmed = confirmed; - return Task.CompletedTask; + using (IAsyncDocumentSession session = _store.OpenAsyncSession()) + { + user.EmailConfirmed = confirmed; + await session.SaveChangesAsync(cancellationToken); + } } /// @@ -602,7 +633,7 @@ namespace Raven.Identity } /// - public Task SetNormalizedEmailAsync(TUser user, string normalizedEmail, CancellationToken cancellationToken) + public async Task SetNormalizedEmailAsync(TUser user, string normalizedEmail, CancellationToken cancellationToken) { ThrowIfNullDisposedCancelled(user, cancellationToken); if (string.IsNullOrEmpty(normalizedEmail)) @@ -610,8 +641,11 @@ namespace Raven.Identity throw new ArgumentNullException(nameof(normalizedEmail)); } - user.Email = normalizedEmail.ToLowerInvariant(); // I don't like the ALL CAPS default. We're going all lower. - return Task.CompletedTask; + using (IAsyncDocumentSession session = _store.OpenAsyncSession()) + { + user.Email = normalizedEmail.ToLowerInvariant(); // I don't like the ALL CAPS default. We're going all lower. + await session.SaveChangesAsync(cancellationToken); + } } #endregion @@ -627,30 +661,41 @@ namespace Raven.Identity } /// - public Task SetLockoutEndDateAsync(TUser user, DateTimeOffset? lockoutEnd, CancellationToken cancellationToken) + public async Task SetLockoutEndDateAsync(TUser user, DateTimeOffset? lockoutEnd, CancellationToken cancellationToken) { ThrowIfNullDisposedCancelled(user, cancellationToken); - user.LockoutEnd = lockoutEnd; - return Task.CompletedTask; + using (IAsyncDocumentSession session = _store.OpenAsyncSession()) + { + user.LockoutEnd = lockoutEnd; + await session.SaveChangesAsync(cancellationToken); + } } /// - public Task IncrementAccessFailedCountAsync(TUser user, CancellationToken cancellationToken) + public async Task IncrementAccessFailedCountAsync(TUser user, CancellationToken cancellationToken) { ThrowIfNullDisposedCancelled(user, cancellationToken); - user.AccessFailedCount++; - return Task.FromResult(user.AccessFailedCount); + using (IAsyncDocumentSession session = _store.OpenAsyncSession()) + { + user.AccessFailedCount++; + await session.SaveChangesAsync(cancellationToken); + } + + return user.AccessFailedCount; } /// - public Task ResetAccessFailedCountAsync(TUser user, CancellationToken cancellationToken) + public async Task ResetAccessFailedCountAsync(TUser user, CancellationToken cancellationToken) { ThrowIfNullDisposedCancelled(user, cancellationToken); - user.AccessFailedCount = 0; - return Task.CompletedTask; + using (IAsyncDocumentSession session = _store.OpenAsyncSession()) + { + user.AccessFailedCount = 0; + await session.SaveChangesAsync(cancellationToken); + } } /// @@ -669,12 +714,15 @@ namespace Raven.Identity } /// - public Task SetLockoutEnabledAsync(TUser user, bool enabled, CancellationToken cancellationToken) + public async Task SetLockoutEnabledAsync(TUser user, bool enabled, CancellationToken cancellationToken) { ThrowIfNullDisposedCancelled(user, cancellationToken); - user.LockoutEnabled = enabled; - return Task.CompletedTask; + using (IAsyncDocumentSession session = _store.OpenAsyncSession()) + { + user.LockoutEnabled = enabled; + await session.SaveChangesAsync(cancellationToken); + } } #endregion @@ -682,12 +730,15 @@ namespace Raven.Identity #region IUserTwoFactorStore implementation /// - public Task SetTwoFactorEnabledAsync(TUser user, bool enabled, CancellationToken cancellationToken) + public async Task SetTwoFactorEnabledAsync(TUser user, bool enabled, CancellationToken cancellationToken) { ThrowIfNullDisposedCancelled(user, cancellationToken); - user.TwoFactorEnabled = enabled; - return Task.CompletedTask; + using (IAsyncDocumentSession session = _store.OpenAsyncSession()) + { + user.TwoFactorEnabled = enabled; + await session.SaveChangesAsync(cancellationToken); + } } /// @@ -703,12 +754,15 @@ namespace Raven.Identity #region IUserPhoneNumberStore implementation /// - public Task SetPhoneNumberAsync(TUser user, string phoneNumber, CancellationToken cancellationToken) + public async Task SetPhoneNumberAsync(TUser user, string phoneNumber, CancellationToken cancellationToken) { ThrowIfNullDisposedCancelled(user, cancellationToken); - user.PhoneNumber = phoneNumber; - return Task.CompletedTask; + using (IAsyncDocumentSession session = _store.OpenAsyncSession()) + { + user.PhoneNumber = phoneNumber; + await session.SaveChangesAsync(cancellationToken); + } } /// @@ -728,12 +782,15 @@ namespace Raven.Identity } /// - public Task SetPhoneNumberConfirmedAsync(TUser user, bool confirmed, CancellationToken cancellationToken) + public async Task SetPhoneNumberConfirmedAsync(TUser user, bool confirmed, CancellationToken cancellationToken) { ThrowIfNullDisposedCancelled(user, cancellationToken); - user.PhoneNumberConfirmed = confirmed; - return Task.CompletedTask; + using (IAsyncDocumentSession session = _store.OpenAsyncSession()) + { + user.PhoneNumberConfirmed = confirmed; + await session.SaveChangesAsync(cancellationToken); + } } #endregion @@ -741,10 +798,13 @@ namespace Raven.Identity #region IUserAuthenticatorKeyStore implementation /// - public Task SetAuthenticatorKeyAsync(TUser user, string key, CancellationToken cancellationToken) + public async Task SetAuthenticatorKeyAsync(TUser user, string key, CancellationToken cancellationToken) { - user.TwoFactorAuthenticatorKey = key; - return Task.CompletedTask; + using (IAsyncDocumentSession session = _store.OpenAsyncSession()) + { + user.TwoFactorAuthenticatorKey = key; + await session.SaveChangesAsync(cancellationToken); + } } /// @@ -780,20 +840,21 @@ namespace Raven.Identity } existingOrNull.Value = value; + + await session.SaveChangesAsync(cancellationToken); } } /// - public Task RemoveTokenAsync(TUser user, string loginProvider, string name, CancellationToken cancellationToken) + public async Task RemoveTokenAsync(TUser user, string loginProvider, string name, CancellationToken cancellationToken) { var id = IdentityUserAuthToken.GetWellKnownId(_store, user.Id, loginProvider, name); using (IAsyncDocumentSession session = _store.OpenAsyncSession()) { session.Delete(id); + await session.SaveChangesAsync(cancellationToken); } - - return Task.CompletedTask; } /// @@ -814,16 +875,24 @@ namespace Raven.Identity } /// - public Task ReplaceCodesAsync(TUser user, IEnumerable recoveryCodes, CancellationToken cancellationToken) + public async Task ReplaceCodesAsync(TUser user, IEnumerable recoveryCodes, CancellationToken cancellationToken) { - user.TwoFactorRecoveryCodes = new List(recoveryCodes); - return Task.CompletedTask; + using (IAsyncDocumentSession session = _store.OpenAsyncSession()) + { + user.TwoFactorRecoveryCodes = new List(recoveryCodes); + await session.SaveChangesAsync(cancellationToken); + } } /// - public Task RedeemCodeAsync(TUser user, string code, CancellationToken cancellationToken) + public async Task RedeemCodeAsync(TUser user, string code, CancellationToken cancellationToken) { - return Task.FromResult(user.TwoFactorRecoveryCodes.Remove(code)); + using (IAsyncDocumentSession session = _store.OpenAsyncSession()) + { + bool isRemoved = user.TwoFactorRecoveryCodes.Remove(code); + await session.SaveChangesAsync(cancellationToken); + return isRemoved; + } } ///