Created
February 11, 2022 03:16
-
-
Save maximgorbatyuk/afcce77dd3124409c184b4d80294f1c0 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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