Browse Source

Merge pull request #24718 from abpframework/AuditingDisabledState

Add ambient auditing disable/enable support.
pull/24740/head
Ahmet Çelik 2 weeks ago
committed by GitHub
parent
commit
255efbf877
No known key found for this signature in database GPG Key ID: B5690EEEBB952194
  1. 11
      framework/src/Volo.Abp.Auditing/Volo/Abp/Auditing/AuditingDisabledState.cs
  2. 24
      framework/src/Volo.Abp.Auditing/Volo/Abp/Auditing/AuditingHelper.cs
  3. 19
      framework/src/Volo.Abp.Auditing/Volo/Abp/Auditing/IAuditingHelper.cs
  4. 139
      framework/test/Volo.Abp.Auditing.Tests/Volo/Abp/Auditing/AuditingHelper_Tests.cs
  5. 11
      modules/cms-kit/src/Volo.CmsKit.Public.Web/Pages/CmsKitPageRouteValueTransformer.cs

11
framework/src/Volo.Abp.Auditing/Volo/Abp/Auditing/AuditingDisabledState.cs

@ -0,0 +1,11 @@
namespace Volo.Abp.Auditing;
public class AuditingDisabledState
{
public bool IsDisabled { get; private set; }
public AuditingDisabledState(bool isDisabled)
{
IsDisabled = isDisabled;
}
}

24
framework/src/Volo.Abp.Auditing/Volo/Abp/Auditing/AuditingHelper.cs

@ -8,6 +8,7 @@ using Microsoft.Extensions.Options;
using Volo.Abp.Clients;
using Volo.Abp.DependencyInjection;
using Volo.Abp.MultiTenancy;
using Volo.Abp.Threading;
using Volo.Abp.Timing;
using Volo.Abp.Tracing;
using Volo.Abp.Users;
@ -26,6 +27,7 @@ public class AuditingHelper : IAuditingHelper, ITransientDependency
protected IAuditSerializer AuditSerializer;
protected IServiceProvider ServiceProvider;
protected ICorrelationIdProvider CorrelationIdProvider { get; }
protected IAmbientScopeProvider<AuditingDisabledState> AuditingDisabledState { get; }
public AuditingHelper(
IAuditSerializer auditSerializer,
@ -37,7 +39,8 @@ public class AuditingHelper : IAuditingHelper, ITransientDependency
IAuditingStore auditingStore,
ILogger<AuditingHelper> logger,
IServiceProvider serviceProvider,
ICorrelationIdProvider correlationIdProvider)
ICorrelationIdProvider correlationIdProvider,
IAmbientScopeProvider<AuditingDisabledState> auditingDisabledState)
{
Options = options.Value;
AuditSerializer = auditSerializer;
@ -50,6 +53,7 @@ public class AuditingHelper : IAuditingHelper, ITransientDependency
Logger = logger;
ServiceProvider = serviceProvider;
CorrelationIdProvider = correlationIdProvider;
AuditingDisabledState = auditingDisabledState;
}
public virtual bool ShouldSaveAudit(MethodInfo? methodInfo, bool defaultValue = false, bool ignoreIntegrationServiceAttribute = false)
@ -64,6 +68,11 @@ public class AuditingHelper : IAuditingHelper, ITransientDependency
return false;
}
if (!IsAuditingEnabled())
{
return false;
}
if (methodInfo.IsDefined(typeof(AuditedAttribute), true))
{
return true;
@ -178,6 +187,19 @@ public class AuditingHelper : IAuditingHelper, ITransientDependency
return actionInfo;
}
private const string AuditingDisabledScopeKey = "Volo.Abp.Auditing.DisabledScope";
public virtual IDisposable DisableAuditing()
{
return AuditingDisabledState.BeginScope(AuditingDisabledScopeKey, new AuditingDisabledState(true));
}
public virtual bool IsAuditingEnabled()
{
var state = AuditingDisabledState.GetValue(AuditingDisabledScopeKey);
return state == null || !state.IsDisabled;
}
protected virtual void ExecutePreContributors(AuditLogInfo auditLogInfo)
{
using (var scope = ServiceProvider.CreateScope())

19
framework/src/Volo.Abp.Auditing/Volo/Abp/Auditing/IAuditingHelper.cs

@ -26,4 +26,23 @@ public interface IAuditingHelper
MethodInfo method,
IDictionary<string, object?> arguments
);
/// <summary>
/// Creates a scope in which auditing is temporarily disabled.
/// </summary>
/// <returns>
/// An <see cref="IDisposable"/> that restores the previous auditing state
/// when disposed. This method supports nested scopes; disposing a scope
/// restores the auditing state that was active before that scope was created.
/// </returns>
IDisposable DisableAuditing();
/// <summary>
/// Determines whether auditing is currently enabled.
/// </summary>
/// <returns>
/// <c>true</c> if auditing is enabled in the current context; otherwise, <c>false</c>.
/// This reflects any active scopes created by <see cref="DisableAuditing"/>.
/// </returns>
bool IsAuditingEnabled();
}

139
framework/test/Volo.Abp.Auditing.Tests/Volo/Abp/Auditing/AuditingHelper_Tests.cs

@ -0,0 +1,139 @@
using System.Threading.Tasks;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.DependencyInjection.Extensions;
using NSubstitute;
using Volo.Abp.DependencyInjection;
using Xunit;
namespace Volo.Abp.Auditing;
public class AuditingHelper_Tests : AbpAuditingTestBase
{
private readonly IAuditingHelper _auditingHelper;
protected IAuditingStore AuditingStore;
public AuditingHelper_Tests()
{
_auditingHelper = GetRequiredService<IAuditingHelper>();
}
protected override void AfterAddApplication(IServiceCollection services)
{
AuditingStore = Substitute.For<IAuditingStore>();
services.Replace(ServiceDescriptor.Singleton(AuditingStore));
}
[Fact]
public async Task Should_Write_AuditLog_Without_DisableAuditing()
{
var myAuditedObject = GetRequiredService<MyAuditedObject>();
await myAuditedObject.DoItAsync();
await AuditingStore.Received().SaveAsync(Arg.Any<AuditLogInfo>());
}
[Fact]
public async Task Should_Not_Write_AuditLog_With_DisableAuditing()
{
var myAuditedObject = GetRequiredService<MyAuditedObject>();
using (_auditingHelper.DisableAuditing())
{
await myAuditedObject.DoItAsync();
}
await AuditingStore.DidNotReceive().SaveAsync(Arg.Any<AuditLogInfo>());
}
[Fact]
public async Task Should_Write_AuditLog_After_DisableAuditing_Scope_Disposed()
{
var myAuditedObject = GetRequiredService<MyAuditedObject>();
using (_auditingHelper.DisableAuditing())
{
await myAuditedObject.DoItAsync();
}
AuditingStore.ClearReceivedCalls();
await myAuditedObject.DoItAsync();
await AuditingStore.Received().SaveAsync(Arg.Any<AuditLogInfo>());
}
[Fact]
public async Task Should_Not_Write_AuditLog_With_Nested_DisableAuditing()
{
var myAuditedObject = GetRequiredService<MyAuditedObject>();
using (_auditingHelper.DisableAuditing())
{
await myAuditedObject.DoItAsync();
using (_auditingHelper.DisableAuditing())
{
await myAuditedObject.DoItAsync();
}
await myAuditedObject.DoItAsync();
}
await AuditingStore.DidNotReceive().SaveAsync(Arg.Any<AuditLogInfo>());
}
[Fact]
public void Should_Return_True_When_Auditing_Is_Enabled()
{
Assert.True(_auditingHelper.IsAuditingEnabled());
}
[Fact]
public void Should_Return_False_When_Auditing_Is_Disabled()
{
using (_auditingHelper.DisableAuditing())
{
Assert.False(_auditingHelper.IsAuditingEnabled());
}
}
[Fact]
public void Should_Return_True_After_DisableAuditing_Scope_Disposed()
{
using (_auditingHelper.DisableAuditing())
{
Assert.False(_auditingHelper.IsAuditingEnabled());
}
Assert.True(_auditingHelper.IsAuditingEnabled());
}
[Fact]
public void Should_Return_False_With_Nested_DisableAuditing()
{
using (_auditingHelper.DisableAuditing())
{
Assert.False(_auditingHelper.IsAuditingEnabled());
using (_auditingHelper.DisableAuditing())
{
Assert.False(_auditingHelper.IsAuditingEnabled());
}
Assert.False(_auditingHelper.IsAuditingEnabled());
}
}
public interface IMyAuditedObject : ITransientDependency, IAuditingEnabled
{
}
public class MyAuditedObject : IMyAuditedObject
{
public virtual Task DoItAsync()
{
return Task.CompletedTask;
}
}
}

11
modules/cms-kit/src/Volo.CmsKit.Public.Web/Pages/CmsKitPageRouteValueTransformer.cs

@ -1,6 +1,7 @@
using System.Threading.Tasks;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Routing;
using Volo.Abp.Auditing;
using Volo.Abp.Caching;
using Volo.Abp.Features;
using Volo.Abp.MultiTenancy;
@ -16,18 +17,21 @@ public class CmsKitPageRouteValueTransformer : CmsKitDynamicRouteValueTransforme
protected IFeatureChecker FeatureChecker { get; }
protected IPagePublicAppService PagePublicAppService { get; }
protected IDistributedCache<PageCacheItem> PageCache { get; }
protected IAuditingHelper AuditingHelper { get; }
public CmsKitPageRouteValueTransformer(
ICurrentTenant currentTenant,
ITenantConfigurationProvider tenantConfigurationProvider,
IFeatureChecker featureChecker,
IPagePublicAppService pagePublicAppService,
IDistributedCache<PageCacheItem> pageCache)
IDistributedCache<PageCacheItem> pageCache,
IAuditingHelper auditingHelper)
: base(currentTenant, tenantConfigurationProvider)
{
FeatureChecker = featureChecker;
PagePublicAppService = pagePublicAppService;
PageCache = pageCache;
AuditingHelper = auditingHelper;
}
protected async override ValueTask<RouteValueDictionary> DoTransformAsync(HttpContext httpContext, RouteValueDictionary values)
@ -44,7 +48,10 @@ public class CmsKitPageRouteValueTransformer : CmsKitDynamicRouteValueTransforme
var exist = await PageCache.GetAsync(PageCacheItem.GetKey(slug)) != null;
if (!exist)
{
exist = await PagePublicAppService.DoesSlugExistAsync(slug);
using (AuditingHelper.DisableAuditing())
{
exist = await PagePublicAppService.DoesSlugExistAsync(slug);
}
}
if (exist)

Loading…
Cancel
Save