/// <summary>
 /// Resets a user's password to a new, automatically generated password.
 /// </summary>
 /// <param name="username">The user to reset the password for.</param>
 /// <param name="answer">The password answer for the specified user.</param>
 /// <returns>
 /// The new password for the specified user.
 /// </returns>
 public override string ResetPassword(string username, string answer)
 {
     using (var session = this.DocumentStore.OpenSession())
     {
         try
         {
             var q = from u in session.Query <User>()
                     where u.Username == username && u.ApplicationName == this.ApplicationName
                     select u;
             var user = q.SingleOrDefault();
             if (user == null)
             {
                 throw new Exception("The user to reset the password for could not be found.");
             }
             var newPassword = Membership.GeneratePassword(8, 2);
             user.PasswordHash = PasswordUtil.HashPassword(newPassword, user.PasswordSalt);
             session.SaveChanges();
             return(newPassword);
         }
         catch (Exception ex)
         {
             // TODO: log exception properly
             Console.WriteLine(ex.ToString());
             throw;
         }
     }
 }
 /// <summary>
 /// Verifies that the specified user name and password exist in the data source.
 /// </summary>
 /// <param name="username">The name of the user to validate.</param>
 /// <param name="password">The password for the specified user.</param>
 /// <returns>
 /// true if the specified username and password are valid; otherwise, false.
 /// </returns>
 public override bool ValidateUser(string username, string password)
 {
     using (var session = this.DocumentStore.OpenSession())
     {
         var q = from u in session.Query <User>()
                 where u.Username == username                        // && u.ApplicationName == this.ApplicationName
                 select u;
         var user = q.SingleOrDefault();
         if (user != null && user.PasswordHash == PasswordUtil.HashPassword(password, user.PasswordSalt))
         {
             user.DateLastLogin = DateTime.Now;
             session.SaveChanges();
             return(true);
         }
     }
     return(false);
 }
        /// <summary>
        /// Processes a request to update the password for a membership user.
        /// </summary>
        /// <param name="username">The user to update the password for.</param>
        /// <param name="oldPassword">The current password for the specified user.</param>
        /// <param name="newPassword">The new password for the specified user.</param>
        /// <returns>
        /// true if the password was updated successfully; otherwise, false.
        /// </returns>
        public override bool ChangePassword(string username, string oldPassword, string newPassword)
        {
            ValidatePasswordEventArgs args = new ValidatePasswordEventArgs(username, newPassword, false);

            OnValidatingPassword(args);
            if (args.Cancel)
            {
                throw new MembershipPasswordException("Apparently, the new password doesn't seem to be valid.");
            }
            using (var session = this.DocumentStore.OpenSession())
            {
                var q = from u in session.Query <User>()
                        where u.Username == username && u.ApplicationName == this.ApplicationName
                        select u;
                var user = q.SingleOrDefault();
                if (user == null || user.PasswordHash != PasswordUtil.HashPassword(oldPassword, user.PasswordSalt))
                {
                    throw new MembershipPasswordException("Invalid username or old password.");
                }
                user.PasswordHash = PasswordUtil.HashPassword(newPassword, user.PasswordSalt);
                session.SaveChanges();
            }
            return(true);
        }
        /// <summary>
        /// Adds a new membership user to the data source.
        /// </summary>
        /// <param name="username">The user name for the new user.</param>
        /// <param name="password">The password for the new user.</param>
        /// <param name="email">The e-mail address for the new user.</param>
        /// <param name="passwordQuestion">The password question for the new user.</param>
        /// <param name="passwordAnswer">The password answer for the new user</param>
        /// <param name="isApproved">Whether or not the new user is approved to be validated.</param>
        /// <param name="providerUserKey">The unique identifier from the membership data source for the user.</param>
        /// <param name="status">A <see cref="T:System.Web.Security.MembershipCreateStatus"/> enumeration value indicating whether the user was created successfully.</param>
        /// <returns>
        /// A <see cref="T:System.Web.Security.MembershipUser"/> object populated with the information for the newly created user.
        /// </returns>
        public override MembershipUser CreateUser(string username, string password, string email, string passwordQuestion, string passwordAnswer, bool isApproved, object providerUserKey, out MembershipCreateStatus status)
        {
            ValidatePasswordEventArgs args = new ValidatePasswordEventArgs(username, password, true);

            OnValidatingPassword(args);
            if (args.Cancel)
            {
                status = MembershipCreateStatus.InvalidPassword;
                return(null);
            }

            var user = new User {
                Username = username, PasswordSalt = PasswordUtil.CreateRandomSalt()
            };

            user.PasswordHash    = PasswordUtil.HashPassword(password, user.PasswordSalt);
            user.Email           = email;
            user.ApplicationName = this.ApplicationName;
            user.DateCreated     = DateTime.Now;

            using (var session = this.DocumentStore.OpenSession()) {
                try {
                    session.Store(user);
                    session.SaveChanges();
                    status = MembershipCreateStatus.Success;
                    return(new MembershipUser(ProviderName, username, user.Id, email, null, null, true, false, user.DateCreated,
                                              new DateTime(1900, 1, 1), new DateTime(1900, 1, 1), DateTime.Now, new DateTime(1900, 1, 1)));
                }
                catch (Exception ex) {
                    // TODO: log exception properly
                    Console.WriteLine(ex.ToString());
                    status = MembershipCreateStatus.ProviderError;
                }
            }
            return(null);
        }