Resolved #366: Audit Logging Improvements

pull/395/head
Halil ibrahim Kalkan 7 years ago
parent 7f84239fda
commit 2927debb53

@ -2,12 +2,14 @@
using System.Text;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Mvc;
using Volo.Abp.Auditing;
using Volo.Abp.Json;
namespace Volo.Abp.AspNetCore.Mvc.ApplicationConfigurations
{
[Area("Abp")]
[Route("Abp/ApplicationConfigurationScript")]
[DisableAuditing]
public class AbpApplicationConfigurationScriptController : AbpController
{
private readonly IApplicationConfigurationBuilder _configurationBuilder;

@ -84,6 +84,12 @@ namespace Volo.Abp.AspNetCore.Mvc.Auditing
return false;
}
//TODO: This is partially duplication of AuditHelper.ShouldSaveAudit method. Check why it does not work for controllers
if (!AuditingInterceptorRegistrar.ShouldAuditTypeByDefault(context.Controller.GetType()))
{
return false;
}
auditLog = auditLogScope.Log;
auditLogAction = _auditingHelper.CreateAuditLogAction(
context.ActionDescriptor.AsControllerActionDescriptor().ControllerTypeInfo.AsType(),

@ -1,12 +1,12 @@
using Microsoft.AspNetCore.Mvc;
using Volo.Abp.Auditing;
using Volo.Abp.Http.ProxyScripting;
namespace Volo.Abp.AspNetCore.Mvc.ProxyScripting
{
//TODO: abp area?
//TODO: [DisableAuditing]
[Area("Abp")]
[Route("Abp/ServiceProxyScript")]
[DisableAuditing]
public class AbpServiceProxyScriptController : AbpController
{
private readonly IProxyScriptManager _proxyScriptManager;

@ -30,7 +30,7 @@ namespace Volo.Abp.Auditing
}
//TODO: Move to a better place
internal static bool ShouldAuditTypeByDefault(Type type)
public static bool ShouldAuditTypeByDefault(Type type)
{
if (type.IsDefined(typeof(AuditedAttribute), true))
{

@ -1,5 +1,6 @@
using System;
using System.Diagnostics;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Logging;
@ -76,18 +77,73 @@ namespace Volo.Abp.Auditing
saveHandle.StopWatch.Stop();
saveHandle.AuditLog.ExecutionDuration = Convert.ToInt32(saveHandle.StopWatch.Elapsed.TotalMilliseconds);
ExecutePostContributors(saveHandle.AuditLog);
MergeEntityChanges(saveHandle.AuditLog);
}
protected virtual void MergeEntityChanges(AuditLogInfo auditLog)
{
var changeGroups = auditLog.EntityChanges
.Where(e => e.ChangeType == EntityChangeType.Updated)
.GroupBy(e => new {e.EntityTypeFullName, e.EntityId})
.ToList();
foreach (var changeGroup in changeGroups)
{
if (changeGroup.Count() <= 1)
{
continue;
}
var firstEntityChange = changeGroup.First();
foreach (var entityChangeInfo in changeGroup)
{
if (entityChangeInfo == firstEntityChange)
{
continue;
}
firstEntityChange.Merge(entityChangeInfo);
auditLog.EntityChanges.Remove(entityChangeInfo);
}
}
}
protected virtual async Task SaveAsync(DisposableSaveHandle saveHandle)
{
BeforeSave(saveHandle);
await _auditingStore.SaveAsync(saveHandle.AuditLog);
if (ShouldSave(saveHandle.AuditLog))
{
await _auditingStore.SaveAsync(saveHandle.AuditLog);
}
}
protected virtual void Save(DisposableSaveHandle saveHandle)
{
BeforeSave(saveHandle);
_auditingStore.Save(saveHandle.AuditLog);
if (ShouldSave(saveHandle.AuditLog))
{
_auditingStore.Save(saveHandle.AuditLog);
}
}
protected bool ShouldSave(AuditLogInfo auditLog)
{
if (!auditLog.Actions.Any() && !auditLog.EntityChanges.Any())
{
return false;
}
if (!Options.IsEnabledForGetRequests && !auditLog.EntityChanges.Any())
{
//TODO: We can create another option for that: IsEnabledIfNoChangesDone?
return false;
}
return true;
}
protected class DisposableSaveHandle : IAuditLogSaveHandle

@ -27,5 +27,14 @@ namespace Volo.Abp.Auditing
{
ExtraProperties = new Dictionary<string, object>();
}
public virtual void Merge(EntityChangeInfo changeInfo)
{
//TODO: Gracefully merge (add/update) and also for ExtraProperties
foreach (var propertyChange in changeInfo.PropertyChanges)
{
PropertyChanges.Add(propertyChange);
}
}
}
}

@ -219,12 +219,12 @@ namespace Volo.Abp.EntityFrameworkCore.EntityHistory
return false;
}
if (entityType.GetTypeInfo().IsDefined(typeof(AuditedAttribute), true))
if (entityType.IsDefined(typeof(AuditedAttribute), true))
{
return true;
}
if (entityType.GetTypeInfo().IsDefined(typeof(DisableAuditingAttribute), true))
if (entityType.IsDefined(typeof(DisableAuditingAttribute), true))
{
return false;
}
@ -257,7 +257,7 @@ namespace Volo.Abp.EntityFrameworkCore.EntityHistory
}
var entityType = propertyEntry.EntityEntry.Entity.GetType();
if (entityType.GetTypeInfo().IsDefined(typeof(DisableAuditingAttribute), true))
if (entityType.IsDefined(typeof(DisableAuditingAttribute), true))
{
if (propertyInfo == null || !propertyInfo.IsDefined(typeof(AuditedAttribute), true))
{

@ -85,7 +85,7 @@ namespace Volo.Abp.AuditLogging.EntityFrameworkCore
{
b.ToTable(tablePrefix + "EntityPropertyChanges", schema);
b.Property(x => x.NewValue).HasMaxLength(EntityPropertyChangeConsts.MaxNewValueLength).IsRequired().HasColumnName(nameof(EntityPropertyChange.NewValue));
b.Property(x => x.NewValue).HasMaxLength(EntityPropertyChangeConsts.MaxNewValueLength).HasColumnName(nameof(EntityPropertyChange.NewValue));
b.Property(x => x.PropertyName).HasMaxLength(EntityPropertyChangeConsts.MaxPropertyNameLength).IsRequired().HasColumnName(nameof(EntityPropertyChange.PropertyName));
b.Property(x => x.PropertyTypeFullName).HasMaxLength(EntityPropertyChangeConsts.MaxPropertyTypeFullNameLength).IsRequired().HasColumnName(nameof(EntityPropertyChange.PropertyTypeFullName));
b.Property(x => x.OriginalValue).HasMaxLength(EntityPropertyChangeConsts.MaxOriginalValueLength).HasColumnName(nameof(EntityPropertyChange.OriginalValue));

Loading…
Cancel
Save