Browse Source

Resolved #366: Audit Logging Improvements

pull/395/head
Halil ibrahim Kalkan 8 years ago
parent
commit
2927debb53
  1. 2
      framework/src/Volo.Abp.AspNetCore.Mvc/Volo/Abp/AspNetCore/Mvc/ApplicationConfigurations/AbpApplicationConfigurationScriptController.cs
  2. 6
      framework/src/Volo.Abp.AspNetCore.Mvc/Volo/Abp/AspNetCore/Mvc/Auditing/AbpAuditActionFilter.cs
  3. 4
      framework/src/Volo.Abp.AspNetCore.Mvc/Volo/Abp/AspNetCore/Mvc/ProxyScripting/AbpServiceProxyScriptController.cs
  4. 2
      framework/src/Volo.Abp.Auditing/Volo/Abp/Auditing/AuditingInterceptorRegistrar.cs
  5. 60
      framework/src/Volo.Abp.Auditing/Volo/Abp/Auditing/AuditingManager.cs
  6. 9
      framework/src/Volo.Abp.Auditing/Volo/Abp/Auditing/EntityChangeInfo.cs
  7. 6
      framework/src/Volo.Abp.EntityFrameworkCore/Volo/Abp/EntityFrameworkCore/EntityHistory/EntityHistoryHelper.cs
  8. 2
      modules/audit-logging/src/Volo.Abp.AuditLogging.EntityFrameworkCore/Volo/Abp/AuditLogging/EntityFrameworkCore/AbpAuditLoggingtDbContextModelBuilderExtensions.cs

2
framework/src/Volo.Abp.AspNetCore.Mvc/Volo/Abp/AspNetCore/Mvc/ApplicationConfigurations/AbpApplicationConfigurationScriptController.cs

@ -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;

6
framework/src/Volo.Abp.AspNetCore.Mvc/Volo/Abp/AspNetCore/Mvc/Auditing/AbpAuditActionFilter.cs

@ -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(),

4
framework/src/Volo.Abp.AspNetCore.Mvc/Volo/Abp/AspNetCore/Mvc/ProxyScripting/AbpServiceProxyScriptController.cs

@ -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;

2
framework/src/Volo.Abp.Auditing/Volo/Abp/Auditing/AuditingInterceptorRegistrar.cs

@ -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))
{

60
framework/src/Volo.Abp.Auditing/Volo/Abp/Auditing/AuditingManager.cs

@ -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

9
framework/src/Volo.Abp.Auditing/Volo/Abp/Auditing/EntityChangeInfo.cs

@ -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);
}
}
}
}

6
framework/src/Volo.Abp.EntityFrameworkCore/Volo/Abp/EntityFrameworkCore/EntityHistory/EntityHistoryHelper.cs

@ -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))
{

2
modules/audit-logging/src/Volo.Abp.AuditLogging.EntityFrameworkCore/Volo/Abp/AuditLogging/EntityFrameworkCore/AbpAuditLoggingtDbContextModelBuilderExtensions.cs

@ -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