public virtual async Task <IdentityResult> SaveUserAsync(UserModel user) { if (user == null) { throw new ArgumentNullException(nameof(user)); } var result = await this.ValidateUserAsync(user); if (!result.Succeeded) { return(result); } try { var userEntity = user.Id != null ? await this.UserManager.FindByIdAsync(user.Id) : await this.UserManager.FindByNameAsync(user.UserName); if (userEntity == null) { return(await this.UserManager.CreateAsync(await this.UserModelToUserEntityAsync(user), user.Password)); } // This is to avoid a DbUpdateConcurrencyException to be thrown. // We are doing 3 transactions: // - Update // - Remove password // - Add password // We need to reset the concurrency-stamp after each transaction to avoid a DbUpdateConcurrencyException. var concurrencyStamp = userEntity.ConcurrencyStamp; userEntity.Email = user.Email; userEntity.EmailConfirmed = !string.IsNullOrWhiteSpace(user.Email); userEntity.UserName = user.UserName; result = await this.UserManager.UpdateAsync(userEntity); if (!result.Succeeded) { return(result); } userEntity.ConcurrencyStamp = concurrencyStamp; result = await this.UserManager.RemovePasswordAsync(userEntity); if (!result.Succeeded) { return(result); } userEntity.ConcurrencyStamp = concurrencyStamp; return(await this.UserManager.AddPasswordAsync(userEntity, user.Password)); } catch (Exception exception) { throw new InvalidOperationException($"Could not save user with id {user.Id.ToStringRepresentation()} and user-name {user.UserName.ToStringRepresentation()}.", exception); } }
public async Task UserModelToUserEntityAsync_IfUserParameterHasANullId_ShouldReturnAUserEntityWithTheIdSet() { var userModel = new UserModel(); Assert.IsNull(userModel.Id); var identityFacade = await this.CreateIdentityFacadeAsync(); var userEntity = await identityFacade.UserModelToUserEntityAsync(userModel); Assert.IsNotNull(userEntity.Id); Assert.IsFalse(new Guid(userEntity.Id) == Guid.Empty); }
public virtual async Task <IdentityResult> ValidateUserAsync(UserModel user) { if (user == null) { throw new ArgumentNullException(nameof(user)); } if (string.IsNullOrWhiteSpace(user.UserName)) { return(IdentityResult.Failed(new IdentityError { Description = "The user-name can not be null, empty or whitespaces only." })); } if (user.Password == null) { return(IdentityResult.Failed(new IdentityError { Description = $"The password for user \"{user.UserName}\" can not be null." })); } var userEntity = await this.UserModelToUserEntityAsync(user); var passwordValidationErrors = new List <IdentityError>(); foreach (var passwordValidator in this.UserManager.PasswordValidators) { var identityResult = await passwordValidator.ValidateAsync(this.UserManager, userEntity, user.Password); if (!identityResult.Succeeded) { passwordValidationErrors.AddRange(identityResult.Errors); } } if (passwordValidationErrors.Any()) { return(IdentityResult.Failed(new IdentityError { Description = $"The password \"{user.Password}\" for user \"{user.UserName}\" is invalid. {string.Join(" ", passwordValidationErrors.Select(identityError => identityError.Description))}" })); } return(IdentityResult.Success); }
protected internal virtual async Task <UserEntity> UserModelToUserEntityAsync(UserModel user) { UserEntity userEntity = null; if (user != null) { userEntity = new UserEntity { Email = user.Email, EmailConfirmed = !string.IsNullOrWhiteSpace(user.Email), UserName = user.UserName }; if (user.Id != null) { userEntity.Id = user.Id; } } return(await Task.FromResult(userEntity)); }