1
0
mirror of https://git.teknik.io/Teknikode/Teknik.git synced 2023-08-02 14:16:22 +02:00
Teknik/IdentityServer/Controllers/ErrorController.cs
2022-05-22 21:39:33 -07:00

251 lines
8.5 KiB
C#

using IdentityServer4.Services;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Diagnostics;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Http.Extensions;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Logging;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net.Mail;
using System.Text;
using System.Threading.Tasks;
using Teknik.Configuration;
using Teknik.IdentityServer.ViewModels;
using Teknik.Logging;
using Teknik.Utilities;
using Teknik.WebCommon;
namespace Teknik.IdentityServer.Controllers
{
public class ErrorController : DefaultController, IErrorController
{
private readonly IIdentityServerInteractionService _interaction;
public ErrorController(ILogger<Logger> logger, Config config, IIdentityServerInteractionService interaction) : base(logger, config)
{
_interaction = interaction;
}
[AllowAnonymous]
public IActionResult HttpError(int statusCode)
{
return HttpError(statusCode, null);
}
[AllowAnonymous]
public IActionResult HttpError(int statusCode, Exception ex)
{
if (ex != null)
return Http500(ex);
switch (statusCode)
{
case 401:
return Http401();
case 403:
return Http403();
case 404:
return Http404();
case 500:
return Http500(ex);
default:
return HttpGeneral(statusCode);
}
}
[AllowAnonymous]
public IActionResult HttpGeneral(int statusCode)
{
ViewBag.Title = statusCode.ToString();
LogError(LogLevel.Error, "HTTP Error Code: " + statusCode);
ErrorViewModel model = new ErrorViewModel();
model.StatusCode = statusCode;
return GenerateActionResult(CreateErrorObj("Http", statusCode, "Invalid HTTP Response"), View("~/Views/Error/HttpGeneral.cshtml", model));
}
[AllowAnonymous]
public IActionResult Http401()
{
Response.StatusCode = StatusCodes.Status401Unauthorized;
ViewBag.Title = "401";
ViewBag.Description = "Unauthorized";
LogError(LogLevel.Error, "Unauthorized");
ErrorViewModel model = new ErrorViewModel();
model.StatusCode = StatusCodes.Status401Unauthorized;
return GenerateActionResult(CreateErrorObj("Http", StatusCodes.Status401Unauthorized, "Unauthorized"), View("~/Views/Error/Http401.cshtml", model));
}
[AllowAnonymous]
public IActionResult Http403()
{
Response.StatusCode = StatusCodes.Status403Forbidden;
ViewBag.Title = "403";
ViewBag.Description = "Access Denied";
LogError(LogLevel.Error, "Access Denied");
ErrorViewModel model = new ErrorViewModel();
model.StatusCode = StatusCodes.Status403Forbidden;
return GenerateActionResult(CreateErrorObj("Http", StatusCodes.Status403Forbidden, "Access Denied"), View("~/Views/Error/Http403.cshtml", model));
}
[AllowAnonymous]
public IActionResult Http404()
{
Response.StatusCode = StatusCodes.Status404NotFound;
ViewBag.Title = "404";
ViewBag.Description = "Uh Oh, can't find it!";
LogError(LogLevel.Warning, "Page Not Found");
ErrorViewModel model = new ErrorViewModel();
model.StatusCode = StatusCodes.Status404NotFound;
return GenerateActionResult(CreateErrorObj("Http", StatusCodes.Status404NotFound, "Page Not Found"), View("~/Views/Error/Http404.cshtml", model));
}
[AllowAnonymous]
public IActionResult Http500(Exception exception)
{
if (HttpContext != null)
{
var ex = HttpContext.Features.Get<IExceptionHandlerFeature>();
if (ex != null)
{
exception = ex.Error;
}
HttpContext.Session.Set("Exception", exception);
}
Response.StatusCode = StatusCodes.Status500InternalServerError;
ViewBag.Title = "500";
ViewBag.Description = "Something Borked";
LogError(LogLevel.Error, "Server Error", exception);
ErrorViewModel model = new ErrorViewModel();
model.StatusCode = StatusCodes.Status500InternalServerError;
model.Exception = exception;
return GenerateActionResult(CreateErrorObj("Http", StatusCodes.Status500InternalServerError, exception.Message), View("~/Views/Error/Http500.cshtml", model));
}
[AllowAnonymous]
public async Task<IActionResult> IdentityError(string errorId)
{
var message = await _interaction.GetErrorContextAsync(errorId);
Response.StatusCode = StatusCodes.Status500InternalServerError;
ViewBag.Title = "Identity Error";
ViewBag.Description = "The Identity Service threw an error";
LogError(LogLevel.Error, "Identity Error: " + message?.Error);
IdentityErrorViewModel model = new IdentityErrorViewModel();
model.Title = message?.Error;
model.Description = message.ErrorDescription;
return GenerateActionResult(CreateErrorObj("Http", StatusCodes.Status500InternalServerError, message.Error), View("~/Views/Error/IdentityError.cshtml", model));
}
[HttpPost]
[AllowAnonymous]
[ValidateAntiForgeryToken]
public IActionResult SubmitErrorReport(SubmitReportViewModel model)
{
try
{
string exceptionMsg = model.Exception;
// Try to grab the actual exception that occured
Exception ex = HttpContext.Session.Get<Exception>("Exception");
if (ex != null)
{
exceptionMsg = string.Format(@"
Exception: {0}
Source: {1}
Stack Trace:
{2}
", ex.GetFullMessage(true), ex.Source, ex.StackTrace);
}
// Let's also email the message to support
SmtpClient client = new SmtpClient();
client.Host = _config.ContactConfig.EmailAccount.Host;
client.Port = _config.ContactConfig.EmailAccount.Port;
client.EnableSsl = _config.ContactConfig.EmailAccount.SSL;
client.DeliveryMethod = SmtpDeliveryMethod.Network;
client.Credentials = new System.Net.NetworkCredential(_config.ContactConfig.EmailAccount.Username, _config.ContactConfig.EmailAccount.Password);
client.Timeout = 5000;
MailMessage mail = new MailMessage(new MailAddress(_config.NoReplyEmail, _config.NoReplyEmail), new MailAddress(_config.SupportEmail, "Teknik Support"));
mail.Sender = new MailAddress(_config.ContactConfig.EmailAccount.EmailAddress);
mail.Subject = "[Exception] Application Exception Occured";
mail.Body = @"
An exception has occured at: " + model.CurrentUrl + @"
----------------------------------------
User Message:
" + model.Message + @"
----------------------------------------
" + exceptionMsg;
mail.BodyEncoding = UTF8Encoding.UTF8;
mail.DeliveryNotificationOptions = DeliveryNotificationOptions.Never;
client.Send(mail);
}
catch (Exception ex)
{
return Json(new { error = "Error submitting report. Exception: " + ex.Message });
}
return Json(new { result = "true" });
}
private object CreateErrorObj(string type, int statusCode, string message)
{
return new { error = new { type = type, status = statusCode, message = message } };
}
private void LogError(LogLevel level, string message)
{
LogError(level, message, null);
}
private void LogError(LogLevel level, string message, Exception exception)
{
if (Request != null)
{
message += " | Url: " + Request.GetDisplayUrl();
message += " | Referred Url: " + Request.Headers["Referer"].ToString();
message += " | Method: " + Request.Method;
message += " | User Agent: " + Request.Headers["User-Agent"].ToString();
}
_logger.Log(level, message, exception);
}
}
}