private async Task Rollback(CancellationToken cancellationToken, params StoreTypes[] rollback) { if (rollback == null) { throw new ArgumentNullException(nameof(rollback)); } foreach (var i in rollback) { switch (i) { case StoreTypes.UserStore: await UserStore.RollbackAsync(cancellationToken); break; case StoreTypes.EmailStore: await EmailStore.RollbackAsync(cancellationToken); break; case StoreTypes.LockoutStore: await LockoutStore.RollbackAsync(cancellationToken); break; case StoreTypes.NameStore: await NameStore.RollbackAsync(cancellationToken); break; case StoreTypes.PasswordStore: await PasswordStore.RollbackAsync(cancellationToken); break; case StoreTypes.TokenStore: await TokenStore.RollbackAsync(cancellationToken); break; case StoreTypes.ClaimStore: await ClaimStore.RollbackAsync(cancellationToken); break; default: throw new ArgumentOutOfRangeException(); } } }
public async Task <AuthenticationResult> RemoveUser(TUser user, CancellationToken cancellationToken) { if (user == null) { throw new ArgumentNullException(nameof(user)); } Handle(cancellationToken); var stores = new List <StoreTypes>(); var result = await EmailStore.DeleteUserAsync(user, cancellationToken); stores.Add(StoreTypes.EmailStore); await AssertSingle(user, result, cancellationToken, stores); result = await ClaimStore.DeleteUserAsync(user, cancellationToken); stores.Add(StoreTypes.ClaimStore); await AssertSingle(user, result, cancellationToken, stores); await LoginStore.DeleteUser(user, cancellationToken); stores.Add(StoreTypes.LoginStore); await TokenStore.RemoveUserAsync(user, cancellationToken); stores.Add(StoreTypes.TokenStore); result = await LockoutStore.DeleteUserAsync(user, cancellationToken); stores.Add(StoreTypes.NameStore); await AssertSingle(user, result, cancellationToken, stores); result = await NameStore.DeleteUserAsync(user, cancellationToken); stores.Add(StoreTypes.NameStore); await AssertSingle(user, result, cancellationToken, stores); result = await PasswordStore.DeleteUserAsync(user, cancellationToken); stores.Add(StoreTypes.PasswordStore); await AssertSingle(user, result, cancellationToken, stores); result = await UserStore.DeleteUserAsync(user, cancellationToken); stores.Add(StoreTypes.UserStore); await AssertSingle(user, result, cancellationToken, stores); return(AuthenticationResult.Success()); }
public void Dispose() { if (IsDiposed) { return; } UserStore.Dispose(); PasswordStore.Dispose(); EmailStore.Dispose(); TokenStore.Dispose(); LockoutStore.Dispose(); NameStore.Dispose(); ClaimStore.Dispose(); IsDiposed = true; }
public async Task <AuthenticationResult <string> > CreateUserAsync(TUser user, string name, string username, string password, string email, CancellationToken cancellationToken) { // Handle any cancellation Handle(cancellationToken); // Quick validation of the parameters supplied. Validation of empty strings should be done above as well. if (user == null) { throw new ArgumentNullException(nameof(user)); } if (string.IsNullOrEmpty(username)) { throw new ArgumentNullException(nameof(username)); } if (string.IsNullOrEmpty(nameof(password))) { throw new ArgumentNullException(nameof(password)); } if (string.IsNullOrEmpty(nameof(email))) { throw new ArgumentNullException(nameof(email)); } // Validates the parameters var validation = await ValidationConfiguration.EmailValidator.ValidateAsync(email, cancellationToken); if (!validation.Succeeded) { return(AuthenticationResult <string> .Invalidate(validation)); } validation = await ValidationConfiguration.UserNameValidator.ValidateAsync(username, cancellationToken); if (!validation.Succeeded) { return(AuthenticationResult <string> .Invalidate(validation)); } validation = await ValidationConfiguration.NameValidator.ValidateAsync(name, cancellationToken); if (!validation.Succeeded) { return(AuthenticationResult <string> .Invalidate(validation)); } validation = await ValidationConfiguration.PasswordValidator.ValidateAsync(password, cancellationToken); if (!validation.Succeeded) { return(AuthenticationResult <string> .Invalidate(validation)); } validation = await ValidationConfiguration.UserValidator.ValidateAsync(user, cancellationToken); if (!validation.Succeeded) { return(AuthenticationResult <string> .Invalidate(validation)); } // Create the id of the new user var id = Guid.NewGuid().ToString(); // All stores that have been modified var a = new List <StoreTypes>(); // Add user in database and retrieve the resulting user var queryResult = await UserStore.CreateUserAsync(user, id, username, DateTime.Now, cancellationToken); a.Add(StoreTypes.UserStore); if (!queryResult.Succeeded || queryResult.RowsModified != 1) { await Rollback(cancellationToken, a.ToArray()); return(AuthenticationResult <string> .ServerFault()); } var qUser = queryResult.Result; // Add user to email store var result = await EmailStore.CreateUserAsync(qUser, email, cancellationToken); a.Add(StoreTypes.EmailStore); if (!result.Succeeded || result.RowsModified != 1) { await Rollback(cancellationToken, a.ToArray()); return(AuthenticationResult <string> .ServerFault()); } //Add user to password store var salt = await SecurityConfiguration.RandomProvider.GenerateRandomAsync(cancellationToken); var hashed = await SecurityConfiguration.PasswordHasher.HashPassword(password, salt, cancellationToken); result = await PasswordStore.CreateUserAsync(qUser, hashed, salt, cancellationToken); a.Add(StoreTypes.PasswordStore); if (!result.Succeeded || result.RowsModified != 1) { await Rollback(cancellationToken, a.ToArray()); return(AuthenticationResult <string> .ServerFault()); } // Start adding the email and configure it to be activated with a link. var guid = Guid.NewGuid().ToString(); var token = Convert.ToBase64String( SecurityConfiguration.TokenProvider.CreateToken(qUser, guid, Security.TokenField.Activation)); result = await EmailStore.CreateUserAsync(qUser, email, cancellationToken); a.Add(StoreTypes.EmailStore); if (!result.Succeeded || result.RowsModified != 1) { await Rollback(cancellationToken, a.ToArray()); return(AuthenticationResult <string> .ServerFault()); } result = await TokenStore.CreateTokenAsync(qUser, token, cancellationToken); a.Add(StoreTypes.TokenStore); if (!result.Succeeded || result.RowsModified != 1) { await Rollback(cancellationToken, a.ToArray()); return(AuthenticationResult <string> .ServerFault()); } // Email the user with the result await EmailConfiguration.AccountVerificationTemplate.LoadAsync(new { Email = email, Token = id }); await EmailConfiguration.EmailProvider.Email(EmailConfiguration.AccountVerificationTemplate, email, cancellationToken); // Add a lockout field result = await LockoutStore.CreateUserAsync(qUser, cancellationToken); a.Add(StoreTypes.LockoutStore); if (!result.Succeeded || result.RowsModified != 1) { await Rollback(cancellationToken, a.ToArray()); return(AuthenticationResult <string> .ServerFault()); } // Add a potential claims field result = await ClaimStore.CreateClaimsAsync(qUser, SecurityConfiguration.DefaultClaims, cancellationToken); a.Add(StoreTypes.ClaimStore); if (!result.Succeeded || result.RowsModified != SecurityConfiguration.DefaultClaims.Count()) { await Rollback(cancellationToken, a.ToArray()); return(AuthenticationResult <string> .ServerFault()); } result = await NameStore.CreateUserAsync(qUser, name, cancellationToken); a.Add(StoreTypes.NameStore); if (!result.Succeeded || result.RowsModified != SecurityConfiguration.DefaultClaims.Count()) { await Rollback(cancellationToken, a.ToArray()); return(AuthenticationResult <string> .ServerFault()); } await Commit(cancellationToken, a.ToArray()); return(AuthenticationResult <string> .Success(id)); }