Browse Source

Merge pull request #4516 from iyilm4z/entity-history-audit-log-improvements

Disable property auditing for base auditing properties
pull/4521/head
Halil İbrahim Kalkan 6 years ago
committed by GitHub
parent
commit
eb5ac8d2b6
No known key found for this signature in database GPG Key ID: 4AEE18F83AFDEB23
  1. 61
      framework/src/Volo.Abp.EntityFrameworkCore/Volo/Abp/EntityFrameworkCore/EntityHistory/EntityHistoryHelper.cs
  2. 26
      framework/test/Volo.Abp.Auditing.Tests/Volo/Abp/Auditing/App/Entities/AppEntityWithAuditedAndHasCustomAuditingProperties.cs
  3. 21
      framework/test/Volo.Abp.Auditing.Tests/Volo/Abp/Auditing/App/Entities/AppFullAuditedEntityWithAudited.cs
  4. 4
      framework/test/Volo.Abp.Auditing.Tests/Volo/Abp/Auditing/App/EntityFrameworkCore/AbpAuditingTestDbContext.cs
  5. 59
      framework/test/Volo.Abp.Auditing.Tests/Volo/Abp/Auditing/Auditing_Tests.cs

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

@ -1,6 +1,7 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using JetBrains.Annotations;
using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.ChangeTracking;
@ -241,6 +242,11 @@ namespace Volo.Abp.EntityFrameworkCore.EntityHistory
}
}
if (IsBaseAuditProperty(propertyInfo, entityType))
{
return false;
}
var isModified = !(propertyEntry.OriginalValue?.Equals(propertyEntry.CurrentValue) ?? propertyEntry.CurrentValue == null);
if (isModified)
{
@ -250,6 +256,59 @@ namespace Volo.Abp.EntityFrameworkCore.EntityHistory
return defaultValue;
}
private bool IsBaseAuditProperty(PropertyInfo propertyInfo, Type entityType)
{
if (entityType.IsAssignableTo<IHasCreationTime>()
&& propertyInfo.Name == nameof(IHasCreationTime.CreationTime))
{
return true;
}
if (entityType.IsAssignableTo<IMayHaveCreator>()
&& propertyInfo.Name == nameof(IMayHaveCreator.CreatorId))
{
return true;
}
if (entityType.IsAssignableTo<IMustHaveCreator>()
&& propertyInfo.Name == nameof(IMustHaveCreator.CreatorId))
{
return true;
}
if (entityType.IsAssignableTo<IHasModificationTime>()
&& propertyInfo.Name == nameof(IHasModificationTime.LastModificationTime))
{
return true;
}
if (entityType.IsAssignableTo<IModificationAuditedObject>()
&& propertyInfo.Name == nameof(IModificationAuditedObject.LastModifierId))
{
return true;
}
if (entityType.IsAssignableTo<ISoftDelete>()
&& propertyInfo.Name == nameof(ISoftDelete.IsDeleted))
{
return true;
}
if (entityType.IsAssignableTo<IHasDeletionTime>()
&& propertyInfo.Name == nameof(IHasDeletionTime.DeletionTime))
{
return true;
}
if (entityType.IsAssignableTo<IDeletionAuditedObject>()
&& propertyInfo.Name == nameof(IDeletionAuditedObject.DeleterId))
{
return true;
}
return false;
}
/// <summary>
/// Updates change time, entity id and foreign keys after SaveChanges is called.
/// </summary>
@ -313,4 +372,4 @@ namespace Volo.Abp.EntityFrameworkCore.EntityHistory
}
}
}
}
}

26
framework/test/Volo.Abp.Auditing.Tests/Volo/Abp/Auditing/App/Entities/AppEntityWithAuditedAndHasCustomAuditingProperties.cs

@ -0,0 +1,26 @@
using System;
using Volo.Abp.Domain.Entities;
namespace Volo.Abp.Auditing.App.Entities
{
[Audited]
public class AppEntityWithAuditedAndHasCustomAuditingProperties : AggregateRoot<Guid>
{
protected AppEntityWithAuditedAndHasCustomAuditingProperties()
{
}
public AppEntityWithAuditedAndHasCustomAuditingProperties(Guid id)
: base(id)
{
}
public DateTime? CreationTime { get; set; }
public Guid? CreatorId { get; set; }
public DateTime? LastModificationTime { get; set; }
public Guid? LastModifierId { get; set; }
public bool IsDeleted { get; set; }
public DateTime? DeletionTime { get; set; }
public Guid? DeleterId { get; set; }
}
}

21
framework/test/Volo.Abp.Auditing.Tests/Volo/Abp/Auditing/App/Entities/AppFullAuditedEntityWithAudited.cs

@ -0,0 +1,21 @@
using System;
using Volo.Abp.Domain.Entities.Auditing;
namespace Volo.Abp.Auditing.App.Entities
{
[Audited]
public class AppFullAuditedEntityWithAudited : FullAuditedAggregateRoot<Guid>
{
protected AppFullAuditedEntityWithAudited()
{
}
public AppFullAuditedEntityWithAudited(Guid id, string name)
: base(id)
{
Name = name;
}
public string Name { get; set; }
}
}

4
framework/test/Volo.Abp.Auditing.Tests/Volo/Abp/Auditing/App/EntityFrameworkCore/AbpAuditingTestDbContext.cs

@ -17,6 +17,10 @@ namespace Volo.Abp.Auditing.App.EntityFrameworkCore
public DbSet<AppEntityWithPropertyHasAudited> AppEntityWithPropertyHasAudited { get; set; }
public DbSet<AppEntityWithSelector> AppEntityWithSelector { get; set; }
public DbSet<AppFullAuditedEntityWithAudited> AppFullAuditedEntityWithAudited { get; set; }
public DbSet<AppEntityWithAuditedAndHasCustomAuditingProperties> AppEntityWithAuditedAndHasCustomAuditingProperties { get; set; }
public AbpAuditingTestDbContext(DbContextOptions<AbpAuditingTestDbContext> options)
: base(options)

59
framework/test/Volo.Abp.Auditing.Tests/Volo/Abp/Auditing/Auditing_Tests.cs

@ -1,4 +1,5 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.Extensions.DependencyInjection;
@ -215,5 +216,63 @@ namespace Volo.Abp.Auditing
#pragma warning restore 4014
}
private static List<string> GetBaseAuditPropertyNames()
{
return new List<string>
{
nameof(IHasCreationTime.CreationTime),
nameof(IMustHaveCreator.CreatorId),
nameof(IHasModificationTime.LastModificationTime),
nameof(IModificationAuditedObject.LastModifierId),
nameof(ISoftDelete.IsDeleted),
nameof(IHasDeletionTime.DeletionTime),
nameof(IDeletionAuditedObject.DeleterId)
};
}
[Fact]
public virtual async Task Should_Write_AuditLog_Ignoring_Base_Auditing_Properties_For_Entity_That_Has_Audited_Attribute()
{
using (var scope = _auditingManager.BeginScope())
{
var repository = ServiceProvider.GetRequiredService<IBasicRepository<AppFullAuditedEntityWithAudited, Guid>>();
await repository.InsertAsync(new AppFullAuditedEntityWithAudited(Guid.NewGuid(), "test name"));
await scope.SaveAsync();
}
#pragma warning disable 4014
_auditingStore.Received().SaveAsync(Arg.Is<AuditLogInfo>(x => x.EntityChanges.Count == 1
&& x.EntityChanges[0].PropertyChanges.Any(y =>
!GetBaseAuditPropertyNames().Contains(y.PropertyName))));
#pragma warning restore 4014
}
[Fact]
public virtual async Task Should_Write_AuditLog_Including_Custom_Base_Auditing_Properties_For_Entity_That_Has_Audited_Attribute()
{
using (var scope = _auditingManager.BeginScope())
{
var repository = ServiceProvider.GetRequiredService<IBasicRepository<AppEntityWithAuditedAndHasCustomAuditingProperties, Guid>>();
await repository.InsertAsync(new AppEntityWithAuditedAndHasCustomAuditingProperties(Guid.NewGuid())
{
CreationTime = DateTime.Now,
CreatorId = Guid.NewGuid(),
LastModificationTime = DateTime.Now,
LastModifierId = Guid.NewGuid(),
IsDeleted = true,
DeletionTime = DateTime.Now,
DeleterId = Guid.NewGuid()
});
await scope.SaveAsync();
}
#pragma warning disable 4014
_auditingStore.Received().SaveAsync(Arg.Is<AuditLogInfo>(x => x.EntityChanges.Count == 1
&& x.EntityChanges[0].PropertyChanges
.Where(y => y.PropertyName != nameof(AppEntityWithAuditedAndHasCustomAuditingProperties
.ExtraProperties))
.All(y => GetBaseAuditPropertyNames().Contains(y.PropertyName))));
#pragma warning restore 4014
}
}
}

Loading…
Cancel
Save