public void AuthenticateUser_Returns_Redirect_If_ModelState_IsInvalid()
        {
            LogOnModel model = new LogOnModel
                                   {
                                       Email = "goodEmail",
                                       Password = "******",
                                       RememberMe = false
                                   };

            controller.ModelState.AddModelError("", "Dummy error message.");
            ActionResult result = controller.AuthenticateUser(model, null);
            Assert.IsInstanceOf(typeof(RedirectToRouteResult), result);
            Assert.IsNotNull(controller.TempData["LogOnModel"]);
        }
        public void AuthenticateUser_Returns_Redirect_On_Success_With_ReturnUrl()
        {
            userProfile = EntityHelpers.GetValidUserProfile();
            userProfile.Email = "goodEmail";
            userProfileRepository.Add(userProfile);
            LogOnModel model = new LogOnModel
                                   {
                                       Email = "goodEmail",
                                       Password = "******",
                                       RememberMe = false
                                   };

            ActionResult result = controller.AuthenticateUser(model, "/someUrl");
            Assert.IsInstanceOf(typeof(RedirectResult), result);
            RedirectResult redirectResult = (RedirectResult)result;
            Assert.AreEqual("/someUrl", redirectResult.Url);
            Assert.IsTrue(((MockFormsAuthenticationService)controller.FormsService).SignIn_WasCalled);
        }
        private ActionResult ValidateLogon(UserProfile userProfile, LogOnModel model, string url, ref int failedLogins, ref bool mustResetPassword)
        {
            if (userProfile == null)
            {
                TempData["UserFeedback"] = "We couldn't find you in our system yet. Fill out the form below to create your profile.";
                return RedirectToAction("Register", "Account", new { returnUrl = url });
            }

            if (!userProfile.IsActivated)
            {
                return RedirectToAction("AwaitingActivation", "Account", new { returnUrl = url });
            }

            User user = userProfile.Users.FirstOrDefault();

            if (user != null)
            {
                failedLogins = user.FailedLoginAttempts;
                mustResetPassword = user.ForcePasswordChange;
            }

            if (failedLogins > MembershipService.MaxInvalidPasswordAttempts
                && TempData["LastLogOnAttempt"] != null)
            {
                var now = DateTime.Now;
                var lastAttemptedOn = (DateTime) TempData["LastLogOnAttempt"];
                var secondsToSleep = CalculateSleepSeconds(failedLogins, MembershipService.MaxInvalidPasswordAttempts);
                var unlockOn = lastAttemptedOn.AddSeconds(secondsToSleep);

                if (unlockOn > now)
                {
                    var elapsed = Convert.ToInt32((now - lastAttemptedOn).TotalSeconds);
                    var remaining = secondsToSleep > elapsed ? secondsToSleep - elapsed : 0;
                    model.RemainingSeconds = remaining;
                    model.LastLoginAttempt = lastAttemptedOn;
                    TempData["UserFeedback"] = string.Format("You still have {0} seconds left before you can try logging in again.", remaining);
                    return RedirectToAction("LogOn");
                }
            }

            return null;
        }
        public void AuthenticateUser_Returns_Redirect_If_ValidateUser_Fails()
        {
            userProfile = EntityHelpers.GetValidUserProfile();
            userProfile.Email = "goodEmail";
            userProfileRepository.Add(userProfile);
            LogOnModel model = new LogOnModel
                                   {
                                       Email = "goodEmail",
                                       Password = "******",
                                       RememberMe = false
                                   };

            ActionResult result = controller.AuthenticateUser(model, null);
            Assert.IsInstanceOf(typeof(RedirectToRouteResult), result);
            Assert.IsNotNull(controller.TempData["LogOnModel"]);
        }
        public ActionResult AuthenticateUser(LogOnModel model, string returnUrl = "")
        {
            TempData["LogOnModel"] = model;

            if (!ModelState.IsValid)
            {
                TempData["ModelErrors"] = FindModelErrors();
                return RedirectToAction("LogOn", new { returnUrl = returnUrl });
            }

            int failedLogins = 0;
            bool mustResetPassword = false;
            UserProfile userProfile;
            using (userProfileRepository)
            {
                userProfile = userProfileRepository.FindUserProfileByEmail(model.Email).FirstOrDefault();
                var validationResult = ValidateLogon(userProfile, model, returnUrl, ref failedLogins, ref mustResetPassword);

                if (validationResult != null)
                {
                    return validationResult;
                }
            }

            if (MembershipService.ValidateUser(model.Email, model.Password))
            {
                FormsService.SignIn(model.Email, model.RememberMe);

                if (mustResetPassword)
                {
                    TempData["UserFeedback"] = string.Format("Welcome {0}! Please update your password using the form below.", userProfile.FullName);
                    return RedirectToAction("ChangePassword", new { returnUrl = returnUrl });
                }

                if (!string.IsNullOrEmpty(returnUrl))
                {
                    return Redirect(returnUrl);
                }

                return RedirectToAction("Index", "UserProfile");
            }

            failedLogins++;

            if (failedLogins > MembershipService.MaxInvalidPasswordAttempts)
            {
                model.RemainingSeconds = CalculateSleepSeconds(failedLogins, MembershipService.MaxInvalidPasswordAttempts);
                model.LastLoginAttempt = DateTime.Now;
            }

            TempData["ModelErrors"] = new List<string> { "The username or password you provided are incorrect." };
            return RedirectToAction("LogOn", new { returnUrl = returnUrl });
        }