This commit is contained in:
2020-05-31 23:56:41 +00:00
parent 8e91f0274b
commit 137d79848f
2 changed files with 143 additions and 8 deletions

View File

@@ -69,6 +69,63 @@ 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 =>
{

View File

@@ -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;
}
}
}
/////////////////////////////////////////////