49 lines
1.7 KiB
C#
49 lines
1.7 KiB
C#
using MediatR;
|
|
using mws.backend.dotnet.application.Common;
|
|
using mws.backend.dotnet.domain.Audit;
|
|
|
|
namespace mws.backend.dotnet.application.Audit;
|
|
|
|
public class AuditLogBehavior<TRequest, TResponse>(
|
|
IUnitOfWork uow,
|
|
ICurrentUser currentUser,
|
|
IAuditContext auditContext)
|
|
: IPipelineBehavior<TRequest, TResponse> where TRequest : notnull
|
|
{
|
|
public async Task<TResponse> Handle(TRequest request, RequestHandlerDelegate<TResponse> next, CancellationToken ct)
|
|
{
|
|
if (request is not IAuditableRequest auditable)
|
|
{
|
|
return await next();
|
|
}
|
|
|
|
auditContext.EntityId = null;
|
|
auditContext.EntityName = null;
|
|
|
|
var response = await next();
|
|
|
|
uow.ActionLogs.Add(new ActionLog
|
|
{
|
|
Id = Guid.NewGuid(),
|
|
ActorUserId = currentUser.UserId ?? Guid.Empty,
|
|
ActorUsername = TruncateRequired(currentUser.Username ?? "unknown", 100),
|
|
Action = auditable.Action,
|
|
EntityType = auditable.EntityType,
|
|
EntityId = auditable.EntityId ?? auditContext.EntityId ?? (response as IHasEntityId)?.EntityId,
|
|
EntityName = Truncate(auditable.EntityName ?? auditContext.EntityName, 255),
|
|
IpAddress = currentUser.IpAddress,
|
|
UserAgent = currentUser.UserAgent,
|
|
CreatedAt = DateTimeOffset.UtcNow,
|
|
});
|
|
await uow.SaveChangesAsync(ct);
|
|
|
|
return response;
|
|
}
|
|
|
|
private static string TruncateRequired(string value, int max) =>
|
|
value.Length <= max ? value : value[..max];
|
|
|
|
private static string? Truncate(string? value, int max) =>
|
|
value is null || value.Length <= max ? value : value[..max];
|
|
}
|