|
|
|
@ -1,10 +1,13 @@ |
|
|
|
using System; |
|
|
|
using System.Diagnostics; |
|
|
|
using System.Linq; |
|
|
|
using System.Threading.Tasks; |
|
|
|
using Microsoft.Extensions.DependencyInjection; |
|
|
|
using Microsoft.Extensions.Options; |
|
|
|
using Volo.Abp.Aspects; |
|
|
|
using Volo.Abp.DependencyInjection; |
|
|
|
using Volo.Abp.DynamicProxy; |
|
|
|
using Volo.Abp.Users; |
|
|
|
|
|
|
|
namespace Volo.Abp.Auditing |
|
|
|
{ |
|
|
|
@ -19,12 +22,65 @@ namespace Volo.Abp.Auditing |
|
|
|
|
|
|
|
public override async Task InterceptAsync(IAbpMethodInvocation invocation) |
|
|
|
{ |
|
|
|
if (!ShouldIntercept(invocation, out var auditLog, out var auditLogAction)) |
|
|
|
using (var serviceScope = _serviceScopeFactory.CreateScope()) |
|
|
|
{ |
|
|
|
await invocation.ProceedAsync(); |
|
|
|
return; |
|
|
|
var auditingHelper = serviceScope.ServiceProvider.GetRequiredService<IAuditingHelper>(); |
|
|
|
var auditingOptions = serviceScope.ServiceProvider.GetRequiredService<IOptions<AbpAuditingOptions>>().Value; |
|
|
|
|
|
|
|
if (!ShouldIntercept(invocation, auditingOptions, auditingHelper)) |
|
|
|
{ |
|
|
|
await invocation.ProceedAsync(); |
|
|
|
return; |
|
|
|
} |
|
|
|
|
|
|
|
var auditingManager = serviceScope.ServiceProvider.GetRequiredService<IAuditingManager>(); |
|
|
|
if (auditingManager.Current != null) |
|
|
|
{ |
|
|
|
await ProceedByLoggingAsync(invocation, auditingHelper, auditingManager.Current); |
|
|
|
} |
|
|
|
else |
|
|
|
{ |
|
|
|
var currentUser = serviceScope.ServiceProvider.GetRequiredService<ICurrentUser>(); |
|
|
|
await ProcessWithNewAuditingScopeAsync(invocation, auditingOptions, currentUser, auditingManager, auditingHelper); |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
protected virtual bool ShouldIntercept(IAbpMethodInvocation invocation, |
|
|
|
AbpAuditingOptions options, |
|
|
|
IAuditingHelper auditingHelper) |
|
|
|
{ |
|
|
|
if (!options.IsEnabled) |
|
|
|
{ |
|
|
|
return false; |
|
|
|
} |
|
|
|
|
|
|
|
if (AbpCrossCuttingConcerns.IsApplied(invocation.TargetObject, AbpCrossCuttingConcerns.Auditing)) |
|
|
|
{ |
|
|
|
return false; |
|
|
|
} |
|
|
|
|
|
|
|
if (!auditingHelper.ShouldSaveAudit(invocation.Method)) |
|
|
|
{ |
|
|
|
return false; |
|
|
|
} |
|
|
|
|
|
|
|
return true; |
|
|
|
} |
|
|
|
|
|
|
|
private static async Task ProceedByLoggingAsync( |
|
|
|
IAbpMethodInvocation invocation, |
|
|
|
IAuditingHelper auditingHelper, |
|
|
|
IAuditLogScope auditLogScope) |
|
|
|
{ |
|
|
|
var auditLog = auditLogScope.Log; |
|
|
|
var auditLogAction = auditingHelper.CreateAuditLogAction( |
|
|
|
auditLog, |
|
|
|
invocation.TargetObject.GetType(), |
|
|
|
invocation.Method, |
|
|
|
invocation.Arguments |
|
|
|
); |
|
|
|
|
|
|
|
var stopwatch = Stopwatch.StartNew(); |
|
|
|
|
|
|
|
try |
|
|
|
@ -43,45 +99,65 @@ namespace Volo.Abp.Auditing |
|
|
|
auditLog.Actions.Add(auditLogAction); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
protected virtual bool ShouldIntercept( |
|
|
|
IAbpMethodInvocation invocation, |
|
|
|
out AuditLogInfo auditLog, |
|
|
|
out AuditLogActionInfo auditLogAction) |
|
|
|
|
|
|
|
private async Task ProcessWithNewAuditingScopeAsync( |
|
|
|
IAbpMethodInvocation invocation, |
|
|
|
AbpAuditingOptions options, |
|
|
|
ICurrentUser currentUser, |
|
|
|
IAuditingManager auditingManager, |
|
|
|
IAuditingHelper auditingHelper) |
|
|
|
{ |
|
|
|
auditLog = null; |
|
|
|
auditLogAction = null; |
|
|
|
|
|
|
|
if (AbpCrossCuttingConcerns.IsApplied(invocation.TargetObject, AbpCrossCuttingConcerns.Auditing)) |
|
|
|
var hasError = false; |
|
|
|
using (var saveHandle = auditingManager.BeginScope()) |
|
|
|
{ |
|
|
|
return false; |
|
|
|
} |
|
|
|
try |
|
|
|
{ |
|
|
|
await ProceedByLoggingAsync(invocation, auditingHelper, auditingManager.Current); |
|
|
|
|
|
|
|
using (var scope = _serviceScopeFactory.CreateScope()) |
|
|
|
{ |
|
|
|
var auditingManager = scope.ServiceProvider.GetRequiredService<IAuditingManager>(); |
|
|
|
var auditLogScope = auditingManager.Current; |
|
|
|
if (auditLogScope == null) |
|
|
|
Debug.Assert(auditingManager.Current != null); |
|
|
|
if (auditingManager.Current.Log.Exceptions.Any()) |
|
|
|
{ |
|
|
|
hasError = true; |
|
|
|
} |
|
|
|
} |
|
|
|
catch (Exception) |
|
|
|
{ |
|
|
|
return false; |
|
|
|
hasError = true; |
|
|
|
throw; |
|
|
|
} |
|
|
|
|
|
|
|
var auditingHelper = scope.ServiceProvider.GetRequiredService<IAuditingHelper>(); |
|
|
|
if (!auditingHelper.ShouldSaveAudit(invocation.Method)) |
|
|
|
finally |
|
|
|
{ |
|
|
|
return false; |
|
|
|
if (ShouldWriteAuditLog(invocation, options, currentUser, hasError)) |
|
|
|
{ |
|
|
|
await saveHandle.SaveAsync(); |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
private bool ShouldWriteAuditLog( |
|
|
|
IAbpMethodInvocation invocation, |
|
|
|
AbpAuditingOptions options, |
|
|
|
ICurrentUser currentUser, |
|
|
|
bool hasError) |
|
|
|
{ |
|
|
|
if (options.AlwaysLogOnException && hasError) |
|
|
|
{ |
|
|
|
return true; |
|
|
|
} |
|
|
|
|
|
|
|
auditLog = auditLogScope.Log; |
|
|
|
auditLogAction = auditingHelper.CreateAuditLogAction( |
|
|
|
auditLog, |
|
|
|
invocation.TargetObject.GetType(), |
|
|
|
invocation.Method, |
|
|
|
invocation.Arguments |
|
|
|
); |
|
|
|
if (!options.IsEnabledForAnonymousUsers && !currentUser.IsAuthenticated) |
|
|
|
{ |
|
|
|
return false; |
|
|
|
} |
|
|
|
|
|
|
|
return true; |
|
|
|
if (!options.IsEnabledForGetRequests && |
|
|
|
invocation.Method.Name.StartsWith("Get",StringComparison.OrdinalIgnoreCase)) |
|
|
|
{ |
|
|
|
return false; |
|
|
|
} |
|
|
|
|
|
|
|
return true; |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |