Updated AuditingMiddleware, updated AuditingManager

pull/2625/head
Galip Tolga Erdem 5 years ago
parent e15ab839a9
commit 58d9f3fb5c

@ -39,6 +39,10 @@ namespace Volo.Abp.AspNetCore.Auditing
try
{
await next(context).ConfigureAwait(false);
}
catch (Exception ex)
{
await scope.SaveAsync(ex).ConfigureAwait(false);
}
finally
{
@ -49,6 +53,13 @@ namespace Volo.Abp.AspNetCore.Auditing
private bool ShouldWriteAuditLog(HttpContext httpContext)
{
// IF selected, save audit logs on exception on GET requests even if audit log is disabled for GET requests.
if (Options.AlwaysLogOnException &&
string.Equals(httpContext.Request.Method, HttpMethods.Get, StringComparison.OrdinalIgnoreCase))
{
return true;
}
if (!Options.IsEnabled)
{
return false;
@ -59,7 +70,7 @@ namespace Volo.Abp.AspNetCore.Auditing
return false;
}
if (!Options.IsEnabledForGetRequests &&
if (!Options.IsEnabledForGetRequests &&
string.Equals(httpContext.Request.Method, HttpMethods.Get, StringComparison.OrdinalIgnoreCase))
{
return false;

@ -29,7 +29,13 @@ namespace Volo.Abp.Auditing
/// <summary>
/// Default: true.
/// </summary>
public bool IsEnabledForAnonymousUsers { get; set; }
public bool IsEnabledForAnonymousUsers { get; set; } = false;
/// <summary>
/// Audit log e xceptions.
/// Default: false.
/// </summary>
public bool AlwaysLogOnException { get; set; }
public List<AuditLogContributor> Contributors { get; }

@ -23,8 +23,8 @@ namespace Volo.Abp.Auditing
private readonly IAuditingStore _auditingStore;
public AuditingManager(
IAmbientScopeProvider<IAuditLogScope> ambientScopeProvider,
IAuditingHelper auditingHelper,
IAmbientScopeProvider<IAuditLogScope> ambientScopeProvider,
IAuditingHelper auditingHelper,
IAuditingStore auditingStore,
IServiceProvider serviceProvider,
IOptions<AbpAuditingOptions> options)
@ -84,7 +84,7 @@ namespace Volo.Abp.Auditing
{
var changeGroups = auditLog.EntityChanges
.Where(e => e.ChangeType == EntityChangeType.Updated)
.GroupBy(e => new {e.EntityTypeFullName, e.EntityId})
.GroupBy(e => new { e.EntityTypeFullName, e.EntityId })
.ToList();
foreach (var changeGroup in changeGroups)
@ -141,7 +141,7 @@ namespace Volo.Abp.Auditing
public DisposableSaveHandle(
AuditingManager auditingManager,
IDisposable scope,
AuditLogInfo auditLog,
AuditLogInfo auditLog,
Stopwatch stopWatch)
{
_auditingManager = auditingManager;
@ -150,15 +150,22 @@ namespace Volo.Abp.Auditing
StopWatch = stopWatch;
}
public async Task SaveAsync()
public async Task SaveAsync(Exception exception = null)
{
await _auditingManager.SaveAsync(this).ConfigureAwait(false);
if (exception != null)
{
this.AuditLog.Exceptions.Add(exception);
}
else
{
await _auditingManager.SaveAsync(this).ConfigureAwait(false);
}
}
public void Dispose()
{
_scope.Dispose();
}
}
}
}
}

@ -5,6 +5,6 @@ namespace Volo.Abp.Auditing
{
public interface IAuditLogSaveHandle : IDisposable
{
Task SaveAsync();
Task SaveAsync(Exception exception = null);
}
}

@ -0,0 +1,29 @@
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Options;
using Volo.Abp.Auditing;
namespace Volo.Abp.AspNetCore.Mvc.Auditing
{
[Route("api/audit-test")]
public class AuditTestController : AbpController
{
private readonly AbpAuditingOptions _options;
public AuditTestController(IOptions<AbpAuditingOptions> options)
{
_options = options.Value;
}
[Route("audit-success")]
public IActionResult AuditSuccessForGetRequests()
{
return Ok();
}
[Route("audit-fail")]
public IActionResult AuditFailForGetRequests()
{
throw new UserFriendlyException("Exception occurred!");
}
}
}

@ -0,0 +1,47 @@
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.DependencyInjection.Extensions;
using Microsoft.Extensions.Hosting;
using Microsoft.Extensions.Options;
using NSubstitute;
using System.Threading.Tasks;
using Volo.Abp.Auditing;
using Xunit;
namespace Volo.Abp.AspNetCore.Mvc.Auditing
{
public class AuditTestController_Tests : AspNetCoreMvcTestBase
{
private readonly AbpAuditingOptions _options;
private IAuditingStore _auditingStore;
public AuditTestController_Tests()
{
_options = ServiceProvider.GetRequiredService<IOptions<AbpAuditingOptions>>().Value;
_auditingStore = ServiceProvider.GetRequiredService<IAuditingStore>();
}
protected override void ConfigureServices(HostBuilderContext context, IServiceCollection services)
{
_auditingStore = Substitute.For<IAuditingStore>();
services.Replace(ServiceDescriptor.Singleton(_auditingStore));
base.ConfigureServices(context, services);
}
[Fact]
public async Task Should_Trigger_Middleware_And_AuditLog_Success_For_GetRequests()
{
_options.IsEnabledForGetRequests = true;
await GetResponseAsync("api/audit-test/audit-success");
//await _auditingStore.Received().SaveAsync(Arg.Any<AuditLogInfo>()); //Won't work, save happens out of scope
}
[Fact]
public async Task Should_Trigger_Middleware_And_AuditLog_Exception_Always()
{
_options.IsEnabled = false;
_options.AlwaysLogOnException = true;
await GetResponseAsync("api/audit-test/audit-fail", System.Net.HttpStatusCode.BadRequest);
//await _auditingStore.Received().SaveAsync(Arg.Any<AuditLogInfo>()); //Won't work, save happens out of scope
}
}
}
Loading…
Cancel
Save