public async Task UpdatePasswordAsync(User userToUpdate, string newPassword)
        {
            if (userToUpdate is null)
            {
                throw new ArgumentNullException(nameof(userToUpdate));
            }

            if (newPassword.IsNullOrWhiteSpace())
            {
                throw new ArgumentNullException(nameof(newPassword));
            }

            if (userToUpdate.Status != UserStatuses.Active)
            {
                throw new ArgumentException(
                          $"Can only update passwords for active users. UserId={userToUpdate.UserId}");
            }

            UpdateUserPasswordUsingPBKDF2(userToUpdate, newPassword);

            userToUpdate.Modified = VirtualDateTime.Now;

            // save
            await DataRepository.SaveChangesAsync();

            // log password changed
            await UserAuditLog.LogPasswordChangedAsync(userToUpdate, userToUpdate.EmailAddress);
        }
        public async Task UpdateEmailAsync(User userToUpdate, string newEmailAddress)
        {
            if (userToUpdate is null)
            {
                throw new ArgumentNullException(nameof(userToUpdate));
            }

            if (newEmailAddress.IsNullOrWhiteSpace())
            {
                throw new ArgumentNullException(nameof(newEmailAddress));
            }

            if (userToUpdate.Status != UserStatuses.Active)
            {
                throw new ArgumentException($"Can only update emails for active users. UserId={userToUpdate.UserId}");
            }

            var oldEmailAddress = userToUpdate.EmailAddress;

            // update email
            var now = VirtualDateTime.Now;

            userToUpdate.EmailAddress      = newEmailAddress;
            userToUpdate.EmailVerifiedDate = now;
            userToUpdate.Modified          = now;

            // save
            await DataRepository.SaveChangesAsync();

            // log email change
            await UserAuditLog.LogEmailChangedAsync(oldEmailAddress, newEmailAddress, userToUpdate,
                                                    userToUpdate.EmailAddress);
        }
        public async Task <bool> UpdateDetailsAsync(User userToUpdate, UpdateDetailsModel changeDetails)
        {
            if (userToUpdate is null)
            {
                throw new ArgumentNullException(nameof(userToUpdate));
            }

            if (changeDetails is null)
            {
                throw new ArgumentNullException(nameof(changeDetails));
            }

            if (userToUpdate.Status != UserStatuses.Active)
            {
                throw new ArgumentException($"Can only update details for active users. UserId={userToUpdate.UserId}");
            }

            // check we have changes
            var originalDetails = AutoMapper.Map <UpdateDetailsModel>(userToUpdate);

            if (originalDetails.Equals(changeDetails))
            {
                return(false);
            }

            // update current user with new details
            userToUpdate.Firstname          = changeDetails.FirstName;
            userToUpdate.Lastname           = changeDetails.LastName;
            userToUpdate.JobTitle           = changeDetails.JobTitle;
            userToUpdate.ContactFirstName   = changeDetails.FirstName;
            userToUpdate.ContactLastName    = changeDetails.LastName;
            userToUpdate.ContactJobTitle    = changeDetails.JobTitle;
            userToUpdate.ContactPhoneNumber = changeDetails.ContactPhoneNumber;
            userToUpdate.SendUpdates        = changeDetails.SendUpdates;
            userToUpdate.AllowContact       = changeDetails.AllowContact;
            userToUpdate.Modified           = VirtualDateTime.Now;

            // save
            await DataRepository.SaveChangesAsync();

            // log details changed
            await UserAuditLog.LogDetailsChangedAsync(originalDetails, changeDetails, userToUpdate,
                                                      userToUpdate.EmailAddress);

            // success
            return(true);
        }
        public async Task RetireUserAsync(User userToRetire)
        {
            if (userToRetire is null)
            {
                throw new ArgumentNullException(nameof(userToRetire));
            }

            if (userToRetire.Status != UserStatuses.Active)
            {
                throw new ArgumentException($"Can only retire active users. UserId={userToRetire.UserId}");
            }

            // update status
            userToRetire.SetStatus(UserStatuses.Retired, userToRetire, "User retired");
            userToRetire.Modified = VirtualDateTime.Now;

            // save
            await DataRepository.SaveChangesAsync();

            // log status changed
            await UserAuditLog.LogUserRetiredAsync(userToRetire, userToRetire.EmailAddress);
        }