Skip to content

Instantly share code, notes, and snippets.

@maximgorbatyuk
Created February 11, 2022 03:16
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save maximgorbatyuk/afcce77dd3124409c184b4d80294f1c0 to your computer and use it in GitHub Desktop.
Save maximgorbatyuk/afcce77dd3124409c184b4d80294f1c0 to your computer and use it in GitHub Desktop.
using System;
using System.IO;
using System.Linq;
using System.Security.Claims;
using System.Threading.Tasks;
using Database;
using MG.Utils.Abstract.Extensions;
using MG.Utils.EFCore;
using Microsoft.AspNetCore.Http;
using Microsoft.Extensions.DependencyInjection;
using Models.Audit;
namespace Web.Middlewares
{
public class AuditLogMiddleware
{
private readonly RequestDelegate _next;
public AuditLogMiddleware(RequestDelegate next)
{
_next = next;
}
public async Task InvokeAsync(HttpContext context, IServiceScopeFactory factory)
{
context.Request.EnableBuffering();
await ProcessRequestAsync(context);
var requestBody = await ReadBodyAsync(context.Request);
var auditLog = new WebRequestAuditLog(
UserId(context),
context.Request,
context.Response,
requestBody);
using var scope = factory.CreateScope();
await TrySaveAuditOrIgnoreAsync(auditLog, scope.ServiceProvider.GetRequiredService<DatabaseContext>());
}
private static async Task TrySaveAuditOrIgnoreAsync(WebRequestAuditLog auditLog, DatabaseContext dbContext)
{
try
{
await dbContext.AuditLogs.AddAsync(auditLog);
await dbContext.TrySaveChangesAsync();
}
catch (Exception)
{
// ignored
}
}
private async Task ProcessRequestAsync(
HttpContext context)
{
try
{
await _next(context);
}
catch (Exception)
{
// ignored
}
}
private static async Task<string> ReadBodyAsync(HttpRequest request)
{
if (request.Method == "GET")
{
return null;
}
var stream = request.Body;
stream.Seek(0, SeekOrigin.Begin);
using var reader = new StreamReader(stream);
var bodyString = await reader.ReadToEndAsync();
return bodyString;
}
private static long? UserId(HttpContext context)
{
var user = context.User;
if (!user.Claims.Any())
{
return null;
}
return long.TryParse(user.GetClaimValue(ClaimTypes.NameIdentifier), out var userId)
? userId
: null;
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment