Beispiel #1
0
        public async Task <IActionResult> Login(SignInModel signInModel)
        {
            ViewData["ButtonID"] = ButtonID.Login;

            // Check if fields are entered and match checks.
            if (!ModelState.IsValid)
            {
                return(View(signInModel));
            }

            // Model State is Valid; Check Captcha
            if (!await _captcha.IsCaptchaValidAsync())
            {
                ModelState.AddModelError(_captcha.CaptchaValidationError().Key, _captcha.CaptchaValidationError().Value);
                return(View());
            }

            // Attempt to sign the user in.
            SignInResult result = await _accountRepository.PasswordSignInAsync(signInModel, GetRemoteClientIPv4());

            if (result.Succeeded)
            {
                _logger.LogInformation($"USER {signInModel.Username} has logged in.");
                // Store the fact that the CAPTCHA was completed successfully.
                await _captcha.CacheNewCaptchaValidateAsync();

                // Change the time of last login.
                await _accountRepository.UpdateLastLoginAsync(signInModel.Username);

                // Redirect
                return(RedirectToAction(nameof(UserPanelController.Index), GoliathControllers.UserPanelController));
            }
            // Result failed. Check for reason why.

            if (result.IsLockedOut)
            {
                ModelState.AddModelError(string.Empty, "Please try again later.");
            }
            else if (result.IsNotAllowed)
            {
                ModelState.AddModelError(string.Empty, "You must verify your email!");
            }
            else if (result.RequiresTwoFactor)
            {
                await _twoFactorTokenRepository.CreateTokenAsync(signInModel.Username, GoliathHelper.GenerateSecureRandomNumber());

                return(RedirectToAction(nameof(TwoFactorValidation), new { userName = signInModel.Username }));
            }
            else
            {
                ModelState.AddModelError(string.Empty, "Invalid Credentials.");
            }

            // Invalidate Captcha Cookie.
            _captcha.DeleteCaptchaCookie();
            // Return view with errors.
            return(View(signInModel));
        }
        public async Task<IActionResult> Profile(ProfileSettingsModel model)
        {
            if (!ModelState.IsValid)
            {
                return View(model);
            }

            if (!await _captcha.IsCaptchaValidAsync())
            {
                ModelState.AddModelError(_captcha.CaptchaValidationError().Key, _captcha.CaptchaValidationError().Value);
                return View();
            }

            ApplicationUser goliathUser = await _accountRepository.GetUserFromContextAsync(User);

            if (!await _timeouts.CanRequestProfileSettingsUpdateAsync(goliathUser.Id))
            {
                ModelState.AddModelError(string.Empty, "Please wait before updating your profile again.");
                return View();
            }

           #region Simple value updates

            // ** Values which do not need database checking
            goliathUser.BackgroundColor = model.BackgroundColor;
            goliathUser.DarkTheme = model.DarkThemeEnabled;
            goliathUser.LogoutThreshold = int.Parse(model.LogoutThreshold);
            // ** If settings which require a two-factor code are updated.
            bool requiresTwoFactor = false;

            #endregion Simple value updates

            #region Validating email

            if (!string.IsNullOrWhiteSpace(model.NewEmail))
            {
                if (await _accountRepository.DoesEmailExistAsync(model.NewEmail))
                {
                    ModelState.AddModelError(string.Empty, $"The email {model.NewEmail} is currently in use.");
                    return View();
                }
                else
                {
                    goliathUser.UnverifiedNewEmail = model.NewEmail;
                    requiresTwoFactor = true;
                }
            }

            #endregion Validating email

            #region Validating phone number

            if (!string.IsNullOrWhiteSpace(model.NewPhoneNumber))
            {
                if (await _accountRepository.DoesPhoneNumberExistAsync(model.NewPhoneNumber))
                {
                    ModelState.AddModelError(string.Empty, $"The phone number {model.NewPhoneNumber} is currently in use.");
                    return View();
                }
                else
                {
                    goliathUser.UnverifiedNewPhone = model.NewPhoneNumber;
                    requiresTwoFactor = true;
                }
            }

            #endregion Validating phone number

            #region Validating password

            if (!string.IsNullOrWhiteSpace(model.NewPassword))
            {
                if (await _accountRepository.IsPasswordValidAsync(goliathUser, model.NewPassword))
                {
                    ModelState.AddModelError(string.Empty, "Your new password must be different then your previous password.");
                    return View();
                }
                IdentityResult result = await _accountRepository.UpdatePasswordAsync(goliathUser, model.CurrentPassword, model.NewPassword);
                if (!result.Succeeded)
                {
                    _captcha.DeleteCaptchaCookie();
                    ModelState.AddModelError(string.Empty, "Your entry in \"Current Password\" does not match your current password.");
                    return View();
                }
                goliathUser.LastPasswordUpdate = DateTime.UtcNow.ToString();
                requiresTwoFactor = true;
            }

            #endregion Validating password

            #region Check two-factor codes

            if (goliathUser.TwoFactorEnabled && requiresTwoFactor)
            {
                if (string.IsNullOrWhiteSpace(model.TwoFactorCode))
                {
                    _captcha.DeleteCaptchaCookie();
                    ModelState.AddModelError(string.Empty, "Your two-factor code is invalid.");
                    return View();
                }
                if (!await _accountRepository.TwoFactorCodeValidAsync(goliathUser, model.TwoFactorCode))
                {
                    _captcha.DeleteCaptchaCookie();
                    ModelState.AddModelError(string.Empty, "Your two-factor code is invalid.");
                    return View();
                }
            }

            #endregion Check two-factor codes

            #region Sending potential verification emails

            // If all of the user settings are correct then check if we need to send messages to
            // update phone/email.
            if (!string.IsNullOrWhiteSpace(model.NewEmail))
            {
                await _accountRepository.GenerateNewEmailConfirmationTokenAsync(goliathUser, new DeviceParser(GetClientUserAgent(), GetRemoteClientIPv4()));
            }
            if (!string.IsNullOrWhiteSpace(model.NewPhoneNumber))
            {
                await _accountRepository.GenerateNewPhoneConfirmationTokenAsync(goliathUser, new DeviceParser(GetClientUserAgent(), GetRemoteClientIPv4()));
            }

            #endregion Sending potential verification emails

            #region Updating/Caching
            // Update all of the changed values.
            await _accountRepository.UpdateUserAsync(goliathUser);
            await _captcha.CacheNewCaptchaValidateAsync();
            await _timeouts.UpdateRequestAsync(goliathUser.Id, UserRequest.UpdateProfileSettings);
            #endregion Updating/Caching

            ModelState.Clear();
            _logger.LogInformation($"{goliathUser.Id} ({goliathUser.UserName}) - Updated profile settings successfully.");
            TempData[TempDataKeys.Redirect] = RedirectPurpose.SettingsUpdatedSuccess;
            return View();
        }