From 137d79848f20f0e1fe1bfbc281c4d39996ce1df9 Mon Sep 17 00:00:00 2001 From: John Cardinal Date: Sun, 31 May 2020 23:56:41 +0000 Subject: [PATCH] --- server/AyaNova/Startup.cs | 117 ++++++++++++++++-- .../generator/CoreJobMetricsSnapshot.cs | 34 +++++ 2 files changed, 143 insertions(+), 8 deletions(-) diff --git a/server/AyaNova/Startup.cs b/server/AyaNova/Startup.cs index 3ff4376a..1527c020 100644 --- a/server/AyaNova/Startup.cs +++ b/server/AyaNova/Startup.cs @@ -69,7 +69,64 @@ namespace AyaNova services.AddMiniProfiler(options => { options.RouteBasePath = "/profiler"; - + //options.ShouldProfile = request => MyShouldThisBeProfiledFunction(request); + options.ShouldProfile = request => + { + + return true; + }; + //options.IgnoredPaths + options.ResultsAuthorize = request => + { + // if(request.HttpContext.Items) + //{[AY_ROLES, 0]} + if (request.HttpContext.Items["AY_PROFILER_ALLOWED"] != null) + { + return true; + } + + // //Idea: use a query parameter on page link to stats + // //that param is download token, if it's present it tries to validate it and then allow if ok + // //weirdly this gets called on any request not just for the results, so need to check the path first then do the rest I guess or just default to false + // //System.Diagnostics.Debug.WriteLine(request.Path.Value); + // // /profiler/results-index + // // /profiler/results-list + // // /profiler/results-list + // // /profiler/results-list + // // /profiler/results + // if (request.Path.Value.StartsWith("/profiler/results")) + // { + // //someone is requesting the profiler + // //check for a dl token "t" and rehydrate user if found + // //if(request.Query.Count==0) return false; + // if (!request.Query.ContainsKey("t")) return false; + // var token = request.Query["t"]; + // using (AyContext ct = ServiceProviderProvider.DBContext) + // { + // var DownloadUser = ct.User.AsNoTracking().SingleOrDefault(z => z.DlKey == token && z.Active == true); + // if (DownloadUser == null) return false; + + + // //this is necessary because they might have an expired JWT but this would just keep on working without a date check + // //the default is the same timespan as the jwt so it's all good + // var utcNow = new DateTimeOffset(DateTime.Now.ToUniversalTime(), TimeSpan.Zero); + // if (DownloadUser.DlKeyExpire < utcNow.DateTime) return false; + + // //Ok, it's allowed, let's go + // return true; + + + // } + + // } + + return false; + }; + // options.ShouldProfile` + options.EnableServerTimingHeader = false; + options.TrackConnectionOpenClose = false; + // options.ShouldProfile=false; + }).AddEntityFramework(); @@ -116,11 +173,7 @@ namespace AyaNova FileUtil.EnsureUserAndUtilityFoldersExistAndAreNotIdentical(_hostingEnvironment.ContentRootPath); #region DATABASE - // //NOTE: this is required to workaround a bug with miniprofiler - // //if I don't add the memory cache service miniprofiler does but the - // //addition of npgsql below fucks up the config for memory cache somehow - // //documented here: https://github.com/MiniProfiler/dotnet/issues/433 - // services.AddMemoryCache(); + _connectionString = ServerBootConfig.AYANOVA_DB_CONNECTION; @@ -320,8 +373,6 @@ namespace AyaNova // { // app.UseDeveloperExceptionPage(); // } - _newLog.LogDebug("Profiler"); - app.UseMiniProfiler(); //Store a reference to the dependency injection service for static classes ServiceProviderProvider.Provider = app.ApplicationServices; @@ -383,6 +434,50 @@ namespace AyaNova { if (!context.User.Identity.IsAuthenticated) { + //Is this a profiler route? If so we're going to use the dl token to authorize + if (context.Request.Path.Value.StartsWith("/profiler/results")) + { + //someone is requesting the profiler + //check for a dl token "t" and rehydrate user if found + //Note that the profiler UI triggers it's own requests to to get the token + //we need to check the referer which was the first page of profile + + string token = string.Empty; + //is the token in the request? + if (context.Request.Query.ContainsKey("t")) + { + token = context.Request.Query["t"].ToString(); + } + else if (context.Request.Headers["Referer"].Count > 0) + {//Maybe it's in the referer + var q = Microsoft.AspNetCore.WebUtilities.QueryHelpers.ParseQuery(context.Request.Headers["Referer"]); + if (q.ContainsKey("t")) + { + token = q["t"].ToString(); + } + } + + if (!string.IsNullOrWhiteSpace(token)) + { + using (AyContext ct = ServiceProviderProvider.DBContext) + { + var DownloadUser = ct.User.AsNoTracking().SingleOrDefault(z => z.DlKey == token.ToString() && z.Active == true); + if (DownloadUser != null) + { + //this is necessary because they might have an expired JWT but this would just keep on working without a date check + //the default is the same timespan as the jwt so it's all good + var utcNow = new DateTimeOffset(DateTime.Now.ToUniversalTime(), TimeSpan.Zero); + if (DownloadUser.DlKeyExpire > utcNow.DateTime) + { + //TODO: extra role check required here + context.Request.HttpContext.Items["AY_PROFILER_ALLOWED"] = true; + } + } + } + } + } + + context.Request.HttpContext.Items["AY_ROLES"] = 0; await next.Invoke(); } @@ -434,6 +529,12 @@ namespace AyaNova #endregion + + _newLog.LogDebug("Profiler"); + app.UseMiniProfiler(); + + + _newLog.LogDebug("Endpoints pipeline"); app.UseEndpoints(endpoints => { diff --git a/server/AyaNova/generator/CoreJobMetricsSnapshot.cs b/server/AyaNova/generator/CoreJobMetricsSnapshot.cs index 34daf2e5..094fd5bc 100644 --- a/server/AyaNova/generator/CoreJobMetricsSnapshot.cs +++ b/server/AyaNova/generator/CoreJobMetricsSnapshot.cs @@ -1,4 +1,5 @@ using System; +using System.Linq; using System.Diagnostics; using Microsoft.Extensions.Logging; using AyaNova.Util; @@ -93,6 +94,39 @@ namespace AyaNova.Biz //System.Diagnostics.Debug.WriteLine("MM SAVED"); } _lastMMSnapshot = now; + + + //TEST + var profiler = MiniProfiler.StartNew("My Profiler Name"); + if (profiler != null) + { + var Options = profiler.Options; + + var guids = Options.Storage.List(100); + // var lastId = context.Request["last-id"]; + // if (!lastId.IsNullOrWhiteSpace() && Guid.TryParse(lastId, out var lastGuid)) + // { + // guids = guids.TakeWhile(g => g != lastGuid); + // } + + var ministats = guids.Reverse() + .Select(g => Options.Storage.Load(g)) + .Where(p => p != null) + .Select(p => new + { + p.Id, + p.Name, + p.ClientTimings, + p.Started, + p.HasUserViewed, + p.MachineName, + p.User, + p.DurationMilliseconds + }).ToList(); + if(ministats.Count>0){ + var v=ministats.Count; + } + } } /////////////////////////////////////////////