public ActionResult ResetLogin(UserModel.User user) { try { if (ModelState.IsValid) { //If email is valid user email if (user.IsEmailValid(user.Email)) { var resetData = new PasswordResetInfo(); //Create token and write to DB resetData = user.CreateKeyAndTable(user.Email); if (resetData != null) { //If token creation successful, send email to user if (user.SendResetEmail(user.Email, resetData)) { //email success view return RedirectToAction("EmailSent", "User"); } else { //error view return RedirectToAction("Error", "User"); } } else { //error view return RedirectToAction("Error", "User"); } } else { return RedirectToAction("EmailSent", "User"); } } return View(user); } catch (Exception ex) { Logger.WriteErrorLog(ex); return View(user); } }
/// <summary> /// use to write password reset objects to mongo DB /// </summary> /// <returns>true if successful</returns> public bool WritePasswordResetData(PasswordResetInfo info) { try { //Write object to Mongo DB Collection var mongoDatabase = MongoConnection.Connect(); mongoDatabase.GetCollection<PasswordResetInfo>(PasswordResetCollection).Insert(info); return true; } catch (Exception ex) { Logger.WriteErrorLog(ex); return false; } }
/// <summary> /// used to update mongoDB collection /// </summary> public void UpdatePasswordResetData(PasswordResetInfo info) { try { //Update applicable password reset collection var mongoDatabase = MongoConnection.Connect(); mongoDatabase.GetCollection<PasswordResetInfo>(PasswordResetCollection).Save(info); } catch (Exception ex) { Logger.WriteErrorLog(ex); } }
/// <summary> /// Checks if email exists in database /// </summary> /// <param name="_email">User name</param> /// <returns>PasswordResetInfo</returns> public PasswordResetInfo CreateKeyAndTable(string _email) { try { var token = new PasswordResetInfo(); //24 hour expiration token.Expiration = DateTimeOffset.Now.AddHours(24); token.Redeemed = false; //Get UserID based on validated email using (var cn = new SqlConnection(@"Data Source=(LocalDB)")) { string _sql = @"SELECT [Id] FROM [dbo].[System_Users] " + @"WHERE [Email] = @e"; var cmd = new SqlCommand(_sql, cn); cmd.Parameters .Add(new SqlParameter("@e", SqlDbType.NVarChar)) .Value = _email; cn.Open(); var reader = cmd.ExecuteReader(); while (reader.Read()) { token.CustomerId = reader[0].ToString(); } } //Get hash using (var rng = new RNGCryptoServiceProvider()) { byte[] data = new byte[4]; rng.GetBytes(data); token.ResetHash = BitConverter.ToInt32(data, 0); } Mongo MongoWrite = new Mongo(); MongoWrite.WritePasswordResetData(token); return token; } catch (Exception ex) { Logger.WriteErrorLog(ex); return null; } }
/// <summary> /// Validates hash, updates DB /// </summary> /// <param name="_hash">User name</param> /// <returns>HashValidation</returns> public HashValidation ValidateHash(string _hash, string _password) { try { //Get UserID corresponding to hash var ExpiredHash = false; var RetrievedToken = new PasswordResetInfo(); RetrievedToken.Redeemed = true; RetrievedToken.RedemptionTime = DateTimeOffset.Now; Mongo MongoRead = new Mongo(); var MongoResults = new List<PasswordResetInfo>(); MongoResults = MongoRead.GetPasswordResetData(); foreach (var result in MongoResults) { if (result.ResetHash.ToString() == _hash && result.Expiration > DateTime.Now) { RetrievedToken.CustomerId = result.CustomerId; RetrievedToken._id = new ObjectId(); RetrievedToken._id = result._id; RetrievedToken.Expiration = result.Expiration; RetrievedToken.ResetHash = result.ResetHash; if (result.Redeemed) { //Hash expired return HashValidation.Expired; } break; } if (result.ResetHash.ToString() == _hash && result.Expiration < DateTime.Now) { //Hash expired ExpiredHash = true; } } if (RetrievedToken.CustomerId == String.Empty || RetrievedToken.CustomerId == null) { if (ExpiredHash) { //Hash expired return HashValidation.Expired; } //Hash not found return HashValidation.NotFound; } //Update Password in SQL Server using (var cn = new SqlConnection(@"Data Source=(LocalDB)")) { string _sql = @"UPDATE [dbo].[System_Users] SET Password=@e WHERE [Id] = @c"; var cmd = new SqlCommand(_sql, cn); cmd.Parameters .Add(new SqlParameter("@e", SqlDbType.NVarChar)) .Value = BusinessLogic.SHA1.Encode(_password); cmd.Parameters .Add(new SqlParameter("@c", SqlDbType.NVarChar)) .Value = RetrievedToken.CustomerId; cn.Open(); cmd.ExecuteNonQuery(); } // Set Redeemed and Redemption Time for applicable MongoDb Collection Mongo MongoWrite = new Mongo(); MongoWrite.UpdatePasswordResetData(RetrievedToken); return HashValidation.Validated; } catch (Exception ex) { Logger.WriteErrorLog(ex); return HashValidation.NotFound; } }
/// <summary> /// Sends reset email to customer /// </summary> /// <param name="_email">User name</param> /// <returns>true if successful</returns> public bool SendResetEmail(string _email, PasswordResetInfo tokenData) { try { var userName = String.Empty; var Createdtoken = new PasswordResetInfo(); Createdtoken = tokenData; //Get Username based on validated email using (var cn = new SqlConnection(@"Data Source=(LocalDB)")) { string _sql = @"SELECT [Username] FROM [dbo].[System_Users] " + @"WHERE [Email] = @e"; var cmd = new SqlCommand(_sql, cn); cmd.Parameters .Add(new SqlParameter("@e", SqlDbType.NVarChar)) .Value = _email; cn.Open(); var reader = cmd.ExecuteReader(); while (reader.Read()) { userName = reader[0].ToString(); } } //Send Email return MailgunAgent.Send(_email, userName, Createdtoken.ResetHash); } catch (Exception ex) { Logger.WriteErrorLog(ex); return false; } }