The next generation of the Teknik Services. Written in ASP.NET. https://www.teknik.io/
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

237 lines
9.0 KiB

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;
using System.Web.Optimization;
using System.Web.Routing;
using Teknik.Models;
using System.Data.Entity;
using System.Web.Security;
using Teknik.Areas.Users.Models;
using Teknik.Areas.Error.Controllers;
using System.Web.Helpers;
using System.Diagnostics;
using Teknik.Utilities;
using System.Text;
using Teknik.Areas.Users.Utility;
namespace Teknik
{
public class MvcApplication : System.Web.HttpApplication
{
protected void Application_Start()
{
ViewEngines.Engines.Clear();
ViewEngines.Engines.Add(new CustomRazorViewEngine());
Database.SetInitializer(new MigrateDatabaseToLatestVersion<TeknikEntities, Migrations.Configuration>());
AreaRegistration.RegisterAllAreas();
AntiForgeryConfig.RequireSsl = true;
FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters);
RouteConfig.RegisterRoutes(RouteTable.Routes);
BundleConfig.RegisterBundles(BundleTable.Bundles);
}
protected void Application_BeginRequest(object sender, EventArgs e)
{
// Start the generation time stopwatcher
var stopwatch = new Stopwatch();
HttpContext.Current.Items["Stopwatch"] = stopwatch;
stopwatch.Start();
}
protected void Application_EndRequest(object sender, EventArgs e)
{
HttpContext context = HttpContext.Current;
// Set the generation time in the header
Stopwatch stopwatch = (Stopwatch)context.Items["Stopwatch"];
stopwatch.Stop();
TimeSpan ts = stopwatch.Elapsed;
string elapsedTime = String.Format("{0} seconds", ts.TotalSeconds);
context.Response.AppendHeader("GenerationTime", elapsedTime);
// Allow this domain, or everything if local
string origin = (Request.IsLocal) ? "*" : context.Request.Headers.Get("Origin");
if (!string.IsNullOrEmpty(origin))
{
context.Response.AppendHeader("Access-Control-Allow-Origin", origin);
}
}
protected void Application_PostAuthenticateRequest(Object sender, EventArgs e)
{
// We support both Auth Tokens and Cookie Authentication
// Username and Roles for the current user
string username = string.Empty;
List<string> roles = new List<string>();
bool hasAuthToken = false;
if (Request != null)
{
if (Request.Headers.HasKeys())
{
string auth = Request.Headers["Authorization"];
if (!string.IsNullOrEmpty(auth))
{
string[] parts = auth.Split(new char[] { ' ' }, StringSplitOptions.RemoveEmptyEntries);
string type = string.Empty;
string value = string.Empty;
if (parts.Length > 0)
{
type = parts[0].ToLower();
}
if (parts.Length > 1)
{
value = parts[1];
}
using (TeknikEntities entities = new TeknikEntities())
{
// Get the user information based on the auth type
switch (type)
{
case "basic":
KeyValuePair<string, string> authCreds = StringHelper.ParseBasicAuthHeader(value);
bool tokenValid = UserHelper.UserTokenCorrect(entities, authCreds.Key, authCreds.Value);
if (tokenValid)
{
// it's valid, so let's update it's Last Used date
UserHelper.UpdateTokenLastUsed(entities, authCreds.Key, authCreds.Value, DateTime.Now);
// Set the username
username = authCreds.Key;
}
break;
default:
break;
}
}
}
}
}
if (FormsAuthentication.CookiesSupported == true && !hasAuthToken)
{
if (Request.Cookies[FormsAuthentication.FormsCookieName] != null)
{
//let us take out the username now
username = FormsAuthentication.Decrypt(Request.Cookies[FormsAuthentication.FormsCookieName].Value).Name;
}
}
// Create the new user if we found one from the supplied auth info
if (!string.IsNullOrEmpty(username))
{
using (TeknikEntities entities = new TeknikEntities())
{
User user = UserHelper.GetUser(entities, username);
// Grab all their roles
foreach (Group grp in user.Groups)
{
foreach (Role role in grp.Roles)
{
if (!roles.Contains(role.Name))
{
roles.Add(role.Name);
}
}
}
}
HttpContext.Current.User = new System.Security.Principal.GenericPrincipal(
new System.Security.Principal.GenericIdentity(username, "Forms"), roles.ToArray());
}
}
protected void Application_Error(object sender, EventArgs e)
{
// Get the last exception
Exception exception = Server.GetLastError();
// Clear the response
Response.Clear();
HttpException httpException = exception as HttpException;
RouteData routeData = new RouteData();
routeData.DataTokens.Add("namespaces", new[] { typeof(ErrorController).Namespace });
routeData.DataTokens.Add("area", "Error");
routeData.Values.Add("controller", "Error");
if (httpException == null)
{
routeData.Values.Add("action", "Exception");
}
else //It's an Http Exception, Let's handle it.
{
switch (httpException.GetHttpCode())
{
case 401:
// Unauthorized.
routeData.Values.Add("action", "Http401");
break;
case 403:
// Forbidden.
routeData.Values.Add("action", "Http403");
break;
case 404:
// Page not found.
routeData.Values.Add("action", "Http404");
break;
case 500:
// Server error.
routeData.Values.Add("action", "Http500");
break;
// Here you can handle Views to other error codes.
// I choose a General error template
default:
routeData.Values.Add("action", "General");
break;
}
}
// Pass exception details to the target error View.
routeData.Values.Add("exception", exception);
// Clear the error on server.
Server.ClearError();
// Avoid IIS7 getting in the middle
Response.TrySkipIisCustomErrors = true;
// If it is an Ajax request, we should respond with Json data, otherwise redirect
if (new HttpRequestWrapper(Request).IsAjaxRequest())
{
string jsonResult = string.Empty;
if (httpException == null)
{
jsonResult = Json.Encode(new { error = new { type = "Exception", message = exception.GetFullMessage(true) } });
}
else
{
jsonResult = Json.Encode(new { error = new { type = "Http", statuscode = httpException.GetHttpCode(), message = exception.GetFullMessage(true) } });
}
Response.Write(jsonResult);
}
else
{
// Call target Controller and pass the routeData.
IController errorController = new ErrorController();
errorController.Execute(new RequestContext(
new HttpContextWrapper(Context), routeData));
}
}
}
}