예제 #1
0
        public async Task <IActionResult> GeneralException()
        {
            IExceptionHandlerPathFeature feature = HttpContext
                                                   .Features
                                                   .Get <IExceptionHandlerPathFeature>();
            ExceptionHandlerModel model = new()
            {
                DateTime                = $"{DateTime.UtcNow} (UTC)",
                OriginalPath            = feature?.Path ?? "Unknown",
                ExceptionSource         = feature?.Error.Source ?? "Unknown",
                ExceptionTargetSite     = feature?.Error.TargetSite.Name ?? "Unknown",
                ExceptionTargetHelpLink = feature?.Error.HelpLink ?? "Unknown",
                RawExceptionMessage     = feature?.Error.Message ?? "Unknown",

                StatusCode = HttpContext.Response.StatusCode.ToString() ?? "Unknown"
            };

            GoliathHelper.PrintDebugger(GoliathHelper.PrintType.Error, feature.Error.StackTrace);
            if (_signInManager.IsSignedIn(User))
            {
                await _repository.SignOutAsync();
            }
            _logger.LogError($"Encountered error in execution: {feature.Error.StackTrace}");
            TempData[TempDataKeys.Redirect]         = RedirectPurpose.Exception;
            TempData[TempDataKeys.ErrorInformation] = JsonConvert.SerializeObject(model);
            return(RedirectToActionPermanent(nameof(AuthController.Index), GoliathControllers.AuthController));
        }
예제 #2
0
        public async Task CacheNewCaptchaValidateAsync()
        {
            string token = GoliathHelper.GenerateSecureRandomNumber();

            _cookieManager.AddCookie(
                key: CookieKeys.ValidateCaptchaCookie,      // Name of the key.
                value: GoliathHash.HashStringSHA256(token), // A hash derived from token.
                expireTime: DateTime.UtcNow.AddMinutes(5)   // Expires in 5 minutes.
                );
            // Add the generated random number to the database.
            await _validTokens.AddTokenAsync(key : token);
        }
예제 #3
0
        /// <summary>
        /// Send an email to a user while using a template from UserEmailOptions. <br /> This method
        /// is not directly called to send an email rather it is passed through one of the public
        /// async methods of this class.
        /// </summary>
        /// <param name="options"> </param>
        /// <returns> If the email was sent successfully. </returns>
        private async Task <bool> SendEmailAsync(UserEmailOptions options)
        {
            // Setup the mail message.
            MimeMessage message = new()
            {
                Subject = options.Subject,
                Body    = new TextPart("html")
                {
                    Text = options.Body
                }
            };

            message.From.Add(new MailboxAddress(_smtpConfig.DisplayName, _smtpConfig.Address));
            // Send the email message to all recipients.
            foreach (string toEmail in options.ToEmails)
            {
                message.To.Add(new MailboxAddress("User", toEmail));
            }

            using (SmtpClient client = new())
            {
                try
                {
                    // Async connect to the SMTP host and validate it exists.
                    await client.ConnectAsync(_smtpConfig.Host, _smtpConfig.Port, MailKit.Security.SecureSocketOptions.StartTls);

                    // Attempt to login to the SMTP using the settings from appsettings.json
                    await client.AuthenticateAsync(_smtpConfig.Address, _smtpConfig.Password);

                    // Send the message to the client.
                    await client.SendAsync(message);

                    // Disconnect from the session.
                    await client.DisconnectAsync(true);

                    client.Timeout = 20000;
                    _logger.LogInformation($"Sent an email to {options.ToEmails.Aggregate((a, b) => a + ", " + b)} at {DateTime.UtcNow} (UTC).");
                    return(true);
                }
                catch (Exception e)
                {
                    _logger.LogInformation($"Failed to send an email to {options.ToEmails.Aggregate((a, b) => a + ", " + b)}.");
                    GoliathHelper.PrintDebugger(GoliathHelper.PrintType.Error, e.Message);
                    return(false);
                }
            }
        }
예제 #4
0
        public async Task<IActionResult> DownloadDataEncrypted()
        {
            ApplicationUser user = await _accountRepository.GetUserFromContextAsync(User);
            if (!await _timeouts.CanRequestDataDownloadAsync(user.Id))
            {
                TempData[TempDataKeys.HtmlMessage] = "Please wait before downloading your data again.";
                return RedirectToAction(nameof(Profile));
            }

            await Task.Delay(5000); // Wait 5 seconds.
            await _timeouts.UpdateRequestAsync(user.Id, UserRequest.RequestDataDownload);

            string key = GoliathHelper.GenerateSecureRandomString();
            string data = AesHelper.EncryptText(await _accountRepository.UserToJsonAsync(user), key, user.UserName);

            await _accountRepository.GenerateNewDataEncryptionEmailAsync(user, new DeviceParser(GetClientUserAgent(), GetRemoteClientIPv4()), key, Url.ActionLink(nameof(GoliathAesController.DecryptUserData), GoliathControllers.AesController));
            return File(Encoding.ASCII.GetBytes(data), "text/plain", user.UserName + "-data.txt");
        }
예제 #5
0
        public async Task LoadDefaultsAsync()
        {
            if (!(await _roleManager.RoleExistsAsync(GoliathRoles.Administrator)))
            {
                _logger.LogInformation("Creating SuperUser account and Goliath roles.");

                #region Create admin role

                await _roleManager.CreateAsync(new ApplicationRole()
                {
                    Name            = GoliathRoles.Administrator,
                    Icon            = HttpUtility.HtmlEncode("<span class='badge badge-pill badge-danger ml-1'>ADMIN</span>"),
                    IsAdministrator = true
                });

                #endregion Create admin role

                #region Create default role

                await _roleManager.CreateAsync(new ApplicationRole()
                {
                    Name = GoliathRoles.Default,
                    Icon = string.Empty
                });

                #endregion Create default role

                #region Create super user account

                IdentityResult result = await _userManager.CreateAsync(new ApplicationUser()
                {
                    UserName             = _config["SuperUser:Username"],
                    Email                = _config["SuperUser:Email"],
                    EmailConfirmed       = true,
                    BackgroundColor      = "#FFFFFF",
                    DarkTheme            = "false",
                    UserData             = string.Empty,
                    PendingNotifications = string.Empty,
                    LogoutThreshold      = 0,
                    AccountCreationDate  = DateTime.UtcNow.ToString(),
                    LastPasswordUpdate   = DateTime.UtcNow.ToString()
                },
                                                                       password : _config["SuperUser:Password"]
                                                                       );

                if (result.Succeeded)
                {
                    ApplicationUser superUser = await _userManager.FindByNameAsync("GoliathAdmin");

                    await _userManager.AddToRoleAsync(superUser, GoliathRoles.Administrator);
                }
                else
                {
                    GoliathHelper.PrintDebugger(GoliathHelper.PrintType.Error, "Could not create super user.");
                    return;
                }
                GoliathHelper.PrintDebugger("Created Super User.");

                #endregion Create super user account
            }
        }
예제 #6
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));
        }