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()); 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) { try { 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); } } catch (Exception ex) { // Just log it Logging.Logger.WriteEntry(Logging.LogLevel.Warning, "Error in Application_EndRequest", ex); } } 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 roles = new List(); 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 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)); } } } }