From 036df4e837e75c555d054945818387b54352f705 Mon Sep 17 00:00:00 2001 From: Halil ibrahim Kalkan Date: Tue, 10 Jul 2018 11:17:16 +0300 Subject: [PATCH] Auditing enhancements. Added EntityHistorySelectorList option. Renamed AuditingOptions to AbpAuditingOptions. Ignored some Identity properties for audit logging. --- .../Mvc/Auditing/AbpAuditActionFilter.cs | 4 +-- .../Auditing/AbpAuditingMiddleware.cs | 4 +-- ...ditingOptions.cs => AbpAuditingOptions.cs} | 8 +++-- .../Volo/Abp/Auditing/AuditingHelper.cs | 4 +-- .../Abp/Auditing/EntityHistorySelectorList.cs | 12 +++++++ .../Auditing/IEntityHistorySelectorList.cs | 14 +++++++++ .../Abp/Auditing/JsonNetAuditSerializer.cs | 4 +-- .../Volo/Abp/NamedTypeSelector.cs | 31 +++++++++++++++++++ .../Abp/NamedTypeSelectorListExtensions.cs | 24 ++++++++++++++ .../EntityHistorySelectorListExtensions.cs | 20 ++++++++++++ .../EntityHistory/EntityHistoryHelper.cs | 14 ++++----- .../Volo/Abp/Identity/IdentityRole.cs | 3 ++ .../Volo/Abp/Identity/IdentityUser.cs | 6 ++++ 13 files changed, 131 insertions(+), 17 deletions(-) rename framework/src/Volo.Abp.Auditing/Volo/Abp/Auditing/{AuditingOptions.cs => AbpAuditingOptions.cs} (81%) create mode 100644 framework/src/Volo.Abp.Auditing/Volo/Abp/Auditing/EntityHistorySelectorList.cs create mode 100644 framework/src/Volo.Abp.Auditing/Volo/Abp/Auditing/IEntityHistorySelectorList.cs create mode 100644 framework/src/Volo.Abp.Core/Volo/Abp/NamedTypeSelector.cs create mode 100644 framework/src/Volo.Abp.Core/Volo/Abp/NamedTypeSelectorListExtensions.cs create mode 100644 framework/src/Volo.Abp.Ddd.Domain/Volo/Abp/Auditing/EntityHistorySelectorListExtensions.cs diff --git a/framework/src/Volo.Abp.AspNetCore.Mvc/Volo/Abp/AspNetCore/Mvc/Auditing/AbpAuditActionFilter.cs b/framework/src/Volo.Abp.AspNetCore.Mvc/Volo/Abp/AspNetCore/Mvc/Auditing/AbpAuditActionFilter.cs index 660d979048..b3cb9f6f0a 100644 --- a/framework/src/Volo.Abp.AspNetCore.Mvc/Volo/Abp/AspNetCore/Mvc/Auditing/AbpAuditActionFilter.cs +++ b/framework/src/Volo.Abp.AspNetCore.Mvc/Volo/Abp/AspNetCore/Mvc/Auditing/AbpAuditActionFilter.cs @@ -12,11 +12,11 @@ namespace Volo.Abp.AspNetCore.Mvc.Auditing { public class AbpAuditActionFilter : IAsyncActionFilter, ITransientDependency { - protected AuditingOptions Options { get; } + protected AbpAuditingOptions Options { get; } private readonly IAuditingHelper _auditingHelper; private readonly IAuditingManager _auditingManager; - public AbpAuditActionFilter(IOptions options, IAuditingHelper auditingHelper, IAuditingManager auditingManager) + public AbpAuditActionFilter(IOptions options, IAuditingHelper auditingHelper, IAuditingManager auditingManager) { Options = options.Value; _auditingHelper = auditingHelper; diff --git a/framework/src/Volo.Abp.AspNetCore/Volo/Abp/AspNetCore/Auditing/AbpAuditingMiddleware.cs b/framework/src/Volo.Abp.AspNetCore/Volo/Abp/AspNetCore/Auditing/AbpAuditingMiddleware.cs index 73754636ec..97bc76338c 100644 --- a/framework/src/Volo.Abp.AspNetCore/Volo/Abp/AspNetCore/Auditing/AbpAuditingMiddleware.cs +++ b/framework/src/Volo.Abp.AspNetCore/Volo/Abp/AspNetCore/Auditing/AbpAuditingMiddleware.cs @@ -11,14 +11,14 @@ namespace Volo.Abp.AspNetCore.Auditing private readonly RequestDelegate _next; private readonly IAuditingManager _auditingManager; - protected AuditingOptions Options { get; } + protected AbpAuditingOptions Options { get; } protected ICurrentUser CurrentUser { get; } public AbpAuditingMiddleware( RequestDelegate next, IAuditingManager auditingManager, ICurrentUser currentUser, - IOptions options) + IOptions options) { _next = next; _auditingManager = auditingManager; diff --git a/framework/src/Volo.Abp.Auditing/Volo/Abp/Auditing/AuditingOptions.cs b/framework/src/Volo.Abp.Auditing/Volo/Abp/Auditing/AbpAuditingOptions.cs similarity index 81% rename from framework/src/Volo.Abp.Auditing/Volo/Abp/Auditing/AuditingOptions.cs rename to framework/src/Volo.Abp.Auditing/Volo/Abp/Auditing/AbpAuditingOptions.cs index e4abafa949..60ce105c10 100644 --- a/framework/src/Volo.Abp.Auditing/Volo/Abp/Auditing/AuditingOptions.cs +++ b/framework/src/Volo.Abp.Auditing/Volo/Abp/Auditing/AbpAuditingOptions.cs @@ -5,7 +5,7 @@ using System.Linq.Expressions; namespace Volo.Abp.Auditing { - public class AuditingOptions + public class AbpAuditingOptions { //TODO: Consider to add an option to disable auditing for application service methods? @@ -23,7 +23,9 @@ namespace Volo.Abp.Auditing public List IgnoredTypes { get; } - public AuditingOptions() + public IEntityHistorySelectorList EntityHistorySelectors { get; } + + public AbpAuditingOptions() { IsEnabled = true; IsEnabledForAnonymousUsers = true; @@ -38,6 +40,8 @@ namespace Volo.Abp.Auditing typeof(Stream), typeof(Expression) }; + + EntityHistorySelectors = new EntityHistorySelectorList(); } } } \ No newline at end of file diff --git a/framework/src/Volo.Abp.Auditing/Volo/Abp/Auditing/AuditingHelper.cs b/framework/src/Volo.Abp.Auditing/Volo/Abp/Auditing/AuditingHelper.cs index cfbdfa98b3..ce87fc069b 100644 --- a/framework/src/Volo.Abp.Auditing/Volo/Abp/Auditing/AuditingHelper.cs +++ b/framework/src/Volo.Abp.Auditing/Volo/Abp/Auditing/AuditingHelper.cs @@ -19,13 +19,13 @@ namespace Volo.Abp.Auditing protected ICurrentUser CurrentUser { get; } protected ICurrentTenant CurrentTenant { get; } protected IClock Clock { get; } - protected AuditingOptions Options; + protected AbpAuditingOptions Options; protected IAuditSerializer AuditSerializer; protected IServiceProvider ServiceProvider; public AuditingHelper( IAuditSerializer auditSerializer, - IOptions options, + IOptions options, ICurrentUser currentUser, ICurrentTenant currentTenant, IClock clock, diff --git a/framework/src/Volo.Abp.Auditing/Volo/Abp/Auditing/EntityHistorySelectorList.cs b/framework/src/Volo.Abp.Auditing/Volo/Abp/Auditing/EntityHistorySelectorList.cs new file mode 100644 index 0000000000..4e2d32377c --- /dev/null +++ b/framework/src/Volo.Abp.Auditing/Volo/Abp/Auditing/EntityHistorySelectorList.cs @@ -0,0 +1,12 @@ +using System.Collections.Generic; + +namespace Volo.Abp.Auditing +{ + internal class EntityHistorySelectorList : List, IEntityHistorySelectorList + { + public bool RemoveByName(string name) + { + return RemoveAll(s => s.Name == name) > 0; + } + } +} diff --git a/framework/src/Volo.Abp.Auditing/Volo/Abp/Auditing/IEntityHistorySelectorList.cs b/framework/src/Volo.Abp.Auditing/Volo/Abp/Auditing/IEntityHistorySelectorList.cs new file mode 100644 index 0000000000..9d2d7ea45f --- /dev/null +++ b/framework/src/Volo.Abp.Auditing/Volo/Abp/Auditing/IEntityHistorySelectorList.cs @@ -0,0 +1,14 @@ +using System.Collections.Generic; + +namespace Volo.Abp.Auditing +{ + public interface IEntityHistorySelectorList : IList + { + /// + /// Removes a selector by name. + /// + /// + /// + bool RemoveByName(string name); + } +} diff --git a/framework/src/Volo.Abp.Auditing/Volo/Abp/Auditing/JsonNetAuditSerializer.cs b/framework/src/Volo.Abp.Auditing/Volo/Abp/Auditing/JsonNetAuditSerializer.cs index a99d6a5019..8cc44e0888 100644 --- a/framework/src/Volo.Abp.Auditing/Volo/Abp/Auditing/JsonNetAuditSerializer.cs +++ b/framework/src/Volo.Abp.Auditing/Volo/Abp/Auditing/JsonNetAuditSerializer.cs @@ -6,9 +6,9 @@ namespace Volo.Abp.Auditing { public class JsonNetAuditSerializer : IAuditSerializer, ITransientDependency { - protected AuditingOptions Options; + protected AbpAuditingOptions Options; - public JsonNetAuditSerializer(IOptions options) + public JsonNetAuditSerializer(IOptions options) { Options = options.Value; } diff --git a/framework/src/Volo.Abp.Core/Volo/Abp/NamedTypeSelector.cs b/framework/src/Volo.Abp.Core/Volo/Abp/NamedTypeSelector.cs new file mode 100644 index 0000000000..bfba2b1828 --- /dev/null +++ b/framework/src/Volo.Abp.Core/Volo/Abp/NamedTypeSelector.cs @@ -0,0 +1,31 @@ +using System; + +namespace Volo.Abp +{ + /// + /// Used to represent a named type selector. + /// + public class NamedTypeSelector + { + /// + /// Name of the selector. + /// + public string Name { get; set; } + + /// + /// Predicate. + /// + public Func Predicate { get; set; } + + /// + /// Creates new object. + /// + /// Name + /// Predicate + public NamedTypeSelector(string name, Func predicate) + { + Name = name; + Predicate = predicate; + } + } +} \ No newline at end of file diff --git a/framework/src/Volo.Abp.Core/Volo/Abp/NamedTypeSelectorListExtensions.cs b/framework/src/Volo.Abp.Core/Volo/Abp/NamedTypeSelectorListExtensions.cs new file mode 100644 index 0000000000..b06025085b --- /dev/null +++ b/framework/src/Volo.Abp.Core/Volo/Abp/NamedTypeSelectorListExtensions.cs @@ -0,0 +1,24 @@ +using System; +using System.Collections.Generic; +using System.Linq; + +namespace Volo.Abp +{ + public static class NamedTypeSelectorListExtensions + { + /// + /// Add list of types to the list. + /// + /// List of NamedTypeSelector items + /// An arbitrary but unique name (can be later used to remove types from the list) + /// + public static void Add(this IList list, string name, params Type[] types) + { + Check.NotNull(list, nameof(list)); + Check.NotNull(name, nameof(name)); + Check.NotNull(types, nameof(types)); + + list.Add(new NamedTypeSelector(name, type => types.Any(type.IsAssignableFrom))); + } + } +} \ No newline at end of file diff --git a/framework/src/Volo.Abp.Ddd.Domain/Volo/Abp/Auditing/EntityHistorySelectorListExtensions.cs b/framework/src/Volo.Abp.Ddd.Domain/Volo/Abp/Auditing/EntityHistorySelectorListExtensions.cs new file mode 100644 index 0000000000..51173856e7 --- /dev/null +++ b/framework/src/Volo.Abp.Ddd.Domain/Volo/Abp/Auditing/EntityHistorySelectorListExtensions.cs @@ -0,0 +1,20 @@ +using System.Linq; +using Volo.Abp.Domain.Entities; + +namespace Volo.Abp.Auditing +{ + public static class EntityHistorySelectorListExtensions + { + public const string AllEntitiesSelectorName = "Abp.Entities.All"; + + public static void AddAllEntities(this IEntityHistorySelectorList selectors) + { + if (selectors.Any(s => s.Name == AllEntitiesSelectorName)) + { + return; + } + + selectors.Add(new NamedTypeSelector(AllEntitiesSelectorName, t => typeof(IEntity).IsAssignableFrom(t))); + } + } +} diff --git a/framework/src/Volo.Abp.EntityFrameworkCore/Volo/Abp/EntityFrameworkCore/EntityHistory/EntityHistoryHelper.cs b/framework/src/Volo.Abp.EntityFrameworkCore/Volo/Abp/EntityFrameworkCore/EntityHistory/EntityHistoryHelper.cs index 6a5630d65b..1ea043fc77 100644 --- a/framework/src/Volo.Abp.EntityFrameworkCore/Volo/Abp/EntityFrameworkCore/EntityHistory/EntityHistoryHelper.cs +++ b/framework/src/Volo.Abp.EntityFrameworkCore/Volo/Abp/EntityFrameworkCore/EntityHistory/EntityHistoryHelper.cs @@ -24,19 +24,16 @@ namespace Volo.Abp.EntityFrameworkCore.EntityHistory protected IAuditingStore AuditingStore { get; } protected IJsonSerializer JsonSerializer { get; } - protected AuditingOptions Options { get; } + protected AbpAuditingOptions Options { get; } - private readonly IUnitOfWorkManager _unitOfWorkManager; private readonly IClock _clock; public EntityHistoryHelper( - IUnitOfWorkManager unitOfWorkManager, IAuditingStore auditingStore, - IOptions options, + IOptions options, IClock clock, IJsonSerializer jsonSerializer) { - _unitOfWorkManager = unitOfWorkManager; _clock = clock; AuditingStore = auditingStore; JsonSerializer = jsonSerializer; @@ -47,8 +44,6 @@ namespace Volo.Abp.EntityFrameworkCore.EntityHistory public virtual List CreateChangeList(ICollection entityEntries) { - //TODO: Check if auditing disabled (on at somewhere else)? - var list = new List(); foreach (var entry in entityEntries) @@ -234,6 +229,11 @@ namespace Volo.Abp.EntityFrameworkCore.EntityHistory return false; } + if (Options.EntityHistorySelectors.Any(selector => selector.Predicate(entityType))) + { + return true; + } + var properties = entityEntry.Metadata.GetProperties(); if (properties.Any(p => p.PropertyInfo?.IsDefined(typeof(AuditedAttribute)) ?? false)) { diff --git a/modules/identity/src/Volo.Abp.Identity.Domain/Volo/Abp/Identity/IdentityRole.cs b/modules/identity/src/Volo.Abp.Identity.Domain/Volo/Abp/Identity/IdentityRole.cs index 7b720862b0..8c5edd173f 100644 --- a/modules/identity/src/Volo.Abp.Identity.Domain/Volo/Abp/Identity/IdentityRole.cs +++ b/modules/identity/src/Volo.Abp.Identity.Domain/Volo/Abp/Identity/IdentityRole.cs @@ -3,6 +3,7 @@ using System.Collections.Generic; using System.Collections.ObjectModel; using System.Security.Claims; using JetBrains.Annotations; +using Volo.Abp.Auditing; using Volo.Abp.Domain.Entities; using Volo.Abp.Guids; using Volo.Abp.MultiTenancy; @@ -24,6 +25,7 @@ namespace Volo.Abp.Identity /// /// Gets or sets the normalized name for this role. /// + [DisableAuditing] public virtual string NormalizedName { get; protected internal set; } /// @@ -34,6 +36,7 @@ namespace Volo.Abp.Identity /// /// A random value that should change whenever a role is persisted to the store /// + [DisableAuditing] public virtual string ConcurrencyStamp { get; set; } /// diff --git a/modules/identity/src/Volo.Abp.Identity.Domain/Volo/Abp/Identity/IdentityUser.cs b/modules/identity/src/Volo.Abp.Identity.Domain/Volo/Abp/Identity/IdentityUser.cs index f0d5662397..a381ec66ba 100644 --- a/modules/identity/src/Volo.Abp.Identity.Domain/Volo/Abp/Identity/IdentityUser.cs +++ b/modules/identity/src/Volo.Abp.Identity.Domain/Volo/Abp/Identity/IdentityUser.cs @@ -5,6 +5,7 @@ using System.Linq; using System.Security.Claims; using JetBrains.Annotations; using Microsoft.AspNetCore.Identity; +using Volo.Abp.Auditing; using Volo.Abp.Data; using Volo.Abp.Domain.Entities; using Volo.Abp.Guids; @@ -24,6 +25,7 @@ namespace Volo.Abp.Identity /// /// Gets or sets the normalized user name for this user. /// + [DisableAuditing] public virtual string NormalizedUserName { get; protected internal set; } /// @@ -34,6 +36,7 @@ namespace Volo.Abp.Identity /// /// Gets or sets the normalized email address for this user. /// + [DisableAuditing] public virtual string NormalizedEmail { get; protected internal set; } /// @@ -45,16 +48,19 @@ namespace Volo.Abp.Identity /// /// Gets or sets a salted and hashed representation of the password for this user. /// + [DisableAuditing] public virtual string PasswordHash { get; protected internal set; } /// /// A random value that must change whenever a users credentials change (password changed, login removed) /// + [DisableAuditing] public virtual string SecurityStamp { get; protected internal set; } /// /// A random value that must change whenever a user is persisted to the store /// + [DisableAuditing] public virtual string ConcurrencyStamp { get; set; } ///