Skip to content

Commit

Permalink
Changes for v27.0.1
Browse files Browse the repository at this point in the history
  • Loading branch information
thepirat000 committed Sep 4, 2024
1 parent f755ee6 commit 3405d81
Show file tree
Hide file tree
Showing 18 changed files with 203 additions and 48 deletions.
5 changes: 5 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,11 @@ All notable changes to Audit.NET and its extensions will be documented in this f

The format is based on [Keep a Changelog](http://keepachangelog.com/en/1.0.0/).

## [27.0.1] - 2024-09-05:
- Audit.EntityFramework.Core: Introducing the CommandSource property to the audit output for EF Core 6 and above, along with configurable options to determine whether to include reader events based on the command event data
- Audit.WCF: Allow configuring custom `IAuditScopeFactory` and `AuditDataProvider`.
- Audit.WCF.Client: Allow configuring custom `IAuditScopeFactory` and `AuditDataProvider`.

## [27.0.0] - 2024-09-03:
- Audit.NET: Introducing an `Items` collection in the `AuditScope` to store custom data accessible throughout the audit scope's lifecycle.
- Audit.NET: Refactoring `AuditScopeOptions` to eliminate the dependency on the static `Audit.Core.Configuration`.
Expand Down
2 changes: 1 addition & 1 deletion Directory.Build.props
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
<Project>
<PropertyGroup>
<Version>27.0.0</Version>
<Version>27.0.1</Version>
<PackageReleaseNotes></PackageReleaseNotes>
<CheckEolTargetFramework>false</CheckEolTargetFramework>
</PropertyGroup>
Expand Down
10 changes: 10 additions & 0 deletions src/Audit.EntityFramework/CommandEvent.cs
Original file line number Diff line number Diff line change
Expand Up @@ -16,14 +16,24 @@ public class CommandEvent : InterceptorEventBase
/// The command method (NonQuery, Scalar, Reader)
/// </summary>
public DbCommandMethod Method { get; set; }

/// <summary>
/// The command type (Text, StoredProcedure)
/// </summary>
public CommandType CommandType { get; set; }

#if NET6_0_OR_GREATER
/// <summary>
/// Indicates the source of the <see cref="T:System.Data.Common.DbCommand" /> being used to execute the command.
/// </summary>
public CommandSource CommandSource { get; set; }
#endif

/// <summary>
/// The command text
/// </summary>
public string CommandText { get; set; }

/// <summary>
/// The parameter values
/// </summary>
Expand Down
50 changes: 36 additions & 14 deletions src/Audit.EntityFramework/Interceptors/AuditCommandInterceptor.cs
Original file line number Diff line number Diff line change
@@ -1,16 +1,17 @@
#if EF_CORE_5_OR_GREATER
using Audit.Core;
using Audit.Core.Extensions;
using Microsoft.EntityFrameworkCore.Diagnostics;
using System;
using System.Collections.Generic;
using System.Data;
using System.Data.Common;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;

using Audit.Core;
using Audit.Core.Extensions;

using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Infrastructure;
using Microsoft.EntityFrameworkCore.Internal;
using Microsoft.EntityFrameworkCore.Diagnostics;

namespace Audit.EntityFramework.Interceptors
{
Expand All @@ -26,13 +27,20 @@ namespace Audit.EntityFramework.Interceptors
public class AuditCommandInterceptor : DbCommandInterceptor
{
/// <summary>
/// Boolean value to indicate whether to log the command parameter values. By default (when null) it will depend on EnableSensitiveDataLogging setting on the DbContext.
/// Boolean value to indicate whether to log the command parameter values. By default, (when null) it will depend on EnableSensitiveDataLogging setting on the DbContext.
/// </summary>
public bool? LogParameterValues { get; set; }

/// <summary>
/// Boolean value to indicate whether to exclude the events handled by ReaderExecuting. Default is false to include the ReaderExecuting events.
/// </summary>
public bool ExcludeReaderEvents { get; set; }

/// <summary>
/// Predicate to include the ReaderExecuting events based on the event data. By default, all the ReaderExecuting events are included.
/// This predicate is ignored if ExcludeReaderEvents is set to true.
/// </summary>
public Func<CommandEventData, bool> IncludeReaderEventsPredicate { get; set; }

/// <summary>
/// Boolean value to indicate whether to exclude the events handled by NonQueryExecuting. Default is false to include the NonQueryExecuting events.
Expand Down Expand Up @@ -61,10 +69,19 @@ public class AuditCommandInterceptor : DbCommandInterceptor
private readonly DbContextHelper _dbContextHelper = new DbContextHelper();
private IAuditScope _currentScope;

/// <summary>
/// Returns the current audit scope, if any
/// </summary>
/// <returns></returns>
protected IAuditScope GetAuditScope()
{
return _currentScope;
}

#region "Reader"
public override InterceptionResult<DbDataReader> ReaderExecuting(DbCommand command, CommandEventData eventData, InterceptionResult<DbDataReader> result)
{
if (Core.Configuration.AuditDisabled || ExcludeReaderEvents)
if (Core.Configuration.AuditDisabled || ExcludeReaderEvents || IncludeReaderEventsPredicate?.Invoke(eventData) == false)
{
return result;
}
Expand All @@ -78,7 +95,7 @@ public override InterceptionResult<DbDataReader> ReaderExecuting(DbCommand comma

public override DbDataReader ReaderExecuted(DbCommand command, CommandExecutedEventData eventData, DbDataReader result)
{
if (ExcludeReaderEvents)
if (_currentScope == null)
{
return result;
}
Expand All @@ -93,7 +110,7 @@ public override DbDataReader ReaderExecuted(DbCommand command, CommandExecutedEv

public override async ValueTask<InterceptionResult<DbDataReader>> ReaderExecutingAsync(DbCommand command, CommandEventData eventData, InterceptionResult<DbDataReader> result, CancellationToken cancellationToken = default)
{
if (Core.Configuration.AuditDisabled || ExcludeReaderEvents)
if (Core.Configuration.AuditDisabled || ExcludeReaderEvents || IncludeReaderEventsPredicate?.Invoke(eventData) == false)
{
return await base.ReaderExecutingAsync(command, eventData, result, cancellationToken);
}
Expand All @@ -107,7 +124,7 @@ public override async ValueTask<InterceptionResult<DbDataReader>> ReaderExecutin

public override async ValueTask<DbDataReader> ReaderExecutedAsync(DbCommand command, CommandExecutedEventData eventData, DbDataReader result, CancellationToken cancellationToken = default)
{
if (ExcludeReaderEvents)
if (_currentScope == null)
{
return await base.ReaderExecutedAsync(command, eventData, result, cancellationToken);
}
Expand Down Expand Up @@ -139,7 +156,7 @@ public override InterceptionResult<int> NonQueryExecuting(DbCommand command, Com

public override int NonQueryExecuted(DbCommand command, CommandExecutedEventData eventData, int result)
{
if (ExcludeNonQueryEvents)
if (_currentScope == null)
{
return result;
}
Expand All @@ -162,7 +179,7 @@ public override async ValueTask<InterceptionResult<int>> NonQueryExecutingAsync(
}
public override async ValueTask<int> NonQueryExecutedAsync(DbCommand command, CommandExecutedEventData eventData, int result, CancellationToken cancellationToken = default)
{
if (ExcludeNonQueryEvents)
if (_currentScope == null)
{
return await base.NonQueryExecutedAsync(command, eventData, result, cancellationToken);
}
Expand Down Expand Up @@ -190,14 +207,15 @@ public override InterceptionResult<object> ScalarExecuting(DbCommand command, Co

public override object ScalarExecuted(DbCommand command, CommandExecutedEventData eventData, object result)
{
if (ExcludeScalarEvents)
if (_currentScope == null)
{
return result;
}
UpdateExecutedEvent(eventData);
EndScope();
return result;
}

public override async ValueTask<InterceptionResult<object>> ScalarExecutingAsync(DbCommand command, CommandEventData eventData, InterceptionResult<object> result, CancellationToken cancellationToken = default)
{
if (Core.Configuration.AuditDisabled || ExcludeScalarEvents)
Expand All @@ -211,9 +229,10 @@ public override async ValueTask<InterceptionResult<object>> ScalarExecutingAsync
_currentScope = await CreateAuditScopeAsync(auditEvent, cancellationToken);
return await base.ScalarExecutingAsync(command, eventData, result, cancellationToken);
}

public override async ValueTask<object> ScalarExecutedAsync(DbCommand command, CommandExecutedEventData eventData, object result, CancellationToken cancellationToken = default)
{
if (ExcludeScalarEvents)
if (_currentScope == null)
{
return await base.ScalarExecutedAsync(command, eventData, result, cancellationToken);
}
Expand Down Expand Up @@ -248,6 +267,9 @@ protected virtual CommandEvent CreateAuditEvent(DbCommand command, CommandEventD
{
CommandText = command.CommandText,
CommandType = command.CommandType,
#if NET6_0_OR_GREATER
CommandSource = eventData.CommandSource,
#endif
ConnectionId = _dbContextHelper.GetClientConnectionId(command.Connection),
DbConnectionId = eventData.ConnectionId.ToString(),
Database = command.Connection?.Database,
Expand Down
4 changes: 3 additions & 1 deletion src/Audit.EntityFramework/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -271,6 +271,7 @@ optionsBuilder.AddInterceptors(new AuditCommandInterceptor()

- **LogParameterValues**: Boolean value to indicate whether to log the command parameter values. By default (when null) it will depend on EnableSensitiveDataLogging setting on the DbContext.
- **ExcludeReaderEvents**: Boolean value to indicate whether to exclude the events handled by ReaderExecuting. Default is false to include the ReaderExecuting events.
- **IncludeReaderEventsPredicate**: Predicate to include the ReaderExecuting events based on the event data. By default, all the ReaderExecuting events are included. This predicate is ignored if ExcludeReaderEvents is set to true.
- **ExcludeNonQueryEvents**: Boolean value to indicate whether to exclude the events handled by NonQueryExecuting. Default is false to include the NonQueryExecuting events.
- **ExcludeScalarEvents**: Boolean value to indicate whether to exclude the events handled by ScalarExecuting. Default is false to include the ScalarExecuting events.
- **AuditEventType**: To indicate the event type to use on the audit event. (Default is the execute method name). Can contain the following placeholders:
Expand Down Expand Up @@ -520,7 +521,8 @@ The following table describes the output fields for the low-level command interc
| **ConnectionId** | Guid | A unique identifier for the database connection. |
| **ContextId** | string | A unique identifier for the context instance and pool lease. |
| **Method** | string | The command method executed (NonQuery, Scalar, Reader) |
| **CommandType** | string | The command type (Text, StoredProcedure) |
| **CommandType** | [CommandType](https://learn.microsoft.com/en-us/dotnet/api/system.data.commandtype) | The command type (Text, StoredProcedure, etc) |
| **CommandSource** | [CommandSource](https://learn.microsoft.com/en-us/dotnet/api/microsoft.entityframeworkcore.diagnostics.commandsource) | The command source type (SaveChanges, LinqQuery, etc) |
| **CommandText** | string | The command text |
| **Parameters** | Dictionary | The parameter values, if any, when `EnableSensitiveDataLogging` is enabled |
| **IsAsync** | boolean | Indicates whether the call was asynchronous |
Expand Down
2 changes: 1 addition & 1 deletion src/Audit.FileSystem/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -74,7 +74,7 @@ By default content is not included.
- **InternalBufferSize**: Gets or sets the size (in bytes) of the [internal buffer](https://docs.microsoft.com/en-us/dotnet/api/system.io.filesystemwatcher.internalbuffersize?view=netstandard-2.0#System_IO_FileSystemWatcher_InternalBufferSize).
- **AuditDataProvider**: To indicate the Audit Data Provider to use. Default is NULL to use the [globally configured data provider](https://github.com/thepirat000/Audit.NET#data-provider).
- **CreationPolicy**: To indicate the event creation policy to use. Default is NULL to use the [globally configured creation policy](https://github.com/thepirat000/Audit.NET#creation-policy).
- **AuditScopeFactory**: Allows to set a specific audit scope factory. By default the general [`AuditScopeFactory`](https://github.com/thepirat000/Audit.NET/blob/master/src/Audit.NET/AuditScopeFactory.cs) is used.
- **AuditScopeFactory**: Allows to set a specific audit scope factory. By default the globally configured [`AuditScopeFactory`](https://github.com/thepirat000/Audit.NET/blob/master/src/Audit.NET/AuditScopeFactory.cs) is used.

## Output

Expand Down
2 changes: 1 addition & 1 deletion src/Audit.HttpClient/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -93,7 +93,7 @@ The `AuditHttpClientHandler` class allows to configure the following settings:
- **IncludeOptions**: Specifies which [HTTP Request Options](https://learn.microsoft.com/en-us/dotnet/api/system.net.http.httprequestmessage.options?view=net-8.0) should be included in the audit output. Useful to add contextual information to the HTTP Audit Event. By default, the options are not included.
- **CreationPolicy**: Allows to set a specific event creation policy. By default the globally configured creation policy is used. See [Audit.NET Event Creation Policy](https://github.com/thepirat000/Audit.NET#event-creation-policy) section for more information.
- **AuditDataProvider**: Allows to set a specific audit data provider. By default the globally configured data provider is used. See [Audit.NET Data Providers](https://github.com/thepirat000/Audit.NET/blob/master/README.md#data-providers) section for more information.
- **AuditScopeFactory**: Allows to set a specific audit scope factory. By default the general [`AuditScopeFactory`](https://github.com/thepirat000/Audit.NET/blob/master/src/Audit.NET/AuditScopeFactory.cs) is used.
- **AuditScopeFactory**: Allows to set a specific audit scope factory. By default the globally configured [`AuditScopeFactory`](https://github.com/thepirat000/Audit.NET/blob/master/src/Audit.NET/AuditScopeFactory.cs) is used.
## Output Details

Expand Down
2 changes: 1 addition & 1 deletion src/Audit.MongoClient/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -89,7 +89,7 @@ The `MongoAuditEventSubscriber` class allows to configure the following settings
- **CommandFilter**: Set a filter function to determine which command events to log depending on the command start information. By default all commands are logged.
- **CreationPolicy**: Allows to set a specific event creation policy. By default the globally configured creation policy is used. See [Audit.NET Event Creation Policy](https://github.com/thepirat000/Audit.NET#event-creation-policy) section for more information.
- **AuditDataProvider**: Allows to set a specific audit data provider. By default the globally configured data provider is used. See [Audit.NET Data Providers](https://github.com/thepirat000/Audit.NET/blob/master/README.md#data-providers) section for more information.
- **AuditScopeFactory**: Allows to set a specific audit scope factory. By default the general [`AuditScopeFactory`](https://github.com/thepirat000/Audit.NET/blob/master/src/Audit.NET/AuditScopeFactory.cs) is used.
- **AuditScopeFactory**: Allows to set a specific audit scope factory. By default the globally configured [`AuditScopeFactory`](https://github.com/thepirat000/Audit.NET/blob/master/src/Audit.NET/AuditScopeFactory.cs) is used.
You can customize these settings using the fluent API provided. Additionally, some settings can be set as functions of the
executed command, allowing you to adapt the behavior based on the specific command, such as including the reply only in specific cases.
Expand Down
2 changes: 1 addition & 1 deletion src/Audit.SignalR/AuditHubFilter.cs
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ public class AuditHubFilter : IHubFilter
public Func<SignalrEventConnect, bool> ConnectEventsFilter { get; set; }
public Func<SignalrEventDisconnect, bool> DisconnectEventsFilter { get; set; }

public AuditDataProvider AuditDataProvider { get; set; }
public AuditDataProvider? AuditDataProvider { get; set; }
public EventCreationPolicy? CreationPolicy { get; set; }
public string AuditEventType { get; set; }
public bool AuditDisabled { get; set; }
Expand Down
3 changes: 3 additions & 0 deletions src/Audit.WCF.Client/AuditBehavior.cs
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,9 @@

namespace Audit.Wcf.Client
{
/// <summary>
/// WCF client audit behavior configuration
/// </summary>
public class AuditBehavior : BehaviorExtensionElement
{
/// <summary>
Expand Down
13 changes: 12 additions & 1 deletion src/Audit.WCF.Client/AuditEndpointBehavior.cs
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
using System.ServiceModel.Description;
using System.ServiceModel.Dispatcher;
using Audit.Core;

namespace Audit.Wcf.Client
{
Expand All @@ -20,6 +21,16 @@ public class AuditEndpointBehavior : IEndpointBehavior
/// </summary>
public bool IncludeResponseHeaders { get; set; }

/// <summary>
/// The factory to create the audit scopes. Default is NULL to use the globally configured AuditScopeFactory.
/// </summary>
public IAuditScopeFactory AuditScopeFactory { get; set; }

/// <summary>
/// The data provider to use. Default is NULL to use the globally configured AuditDataProvider.
/// </summary>
public AuditDataProvider AuditDataProvider { get; set; }

public AuditEndpointBehavior()
{
}
Expand All @@ -36,7 +47,7 @@ public void AddBindingParameters(ServiceEndpoint endpoint, System.ServiceModel.C
}
public void ApplyClientBehavior(ServiceEndpoint endpoint, ClientRuntime clientRuntime)
{
clientRuntime.ClientMessageInspectors.Add(new AuditMessageInspector(EventType, IncludeRequestHeaders, IncludeResponseHeaders));
clientRuntime.ClientMessageInspectors.Add(new AuditMessageInspector(EventType, IncludeRequestHeaders, IncludeResponseHeaders, AuditScopeFactory, AuditDataProvider));
}
public void ApplyDispatchBehavior(ServiceEndpoint endpoint, EndpointDispatcher endpointDispatcher)
{
Expand Down
14 changes: 11 additions & 3 deletions src/Audit.WCF.Client/AuditMessageInspector.cs
Original file line number Diff line number Diff line change
Expand Up @@ -16,16 +16,21 @@ public class AuditMessageInspector : IClientMessageInspector
private readonly string _eventType = "{action}";
private readonly bool _includeRequestHeaders;
private readonly bool _includeResponseHeaders;
private readonly IAuditScopeFactory _auditScopeFactory;
private readonly AuditDataProvider _auditDataProvider;

public AuditMessageInspector()
{
}

public AuditMessageInspector(string eventType, bool includeRequestHeaders, bool includeResponseHeaders)
public AuditMessageInspector(string eventType, bool includeRequestHeaders, bool includeResponseHeaders, IAuditScopeFactory auditScopeFactory,
AuditDataProvider auditDataProvider)
{
_eventType = eventType ?? "{action}";
_includeRequestHeaders = includeRequestHeaders;
_includeResponseHeaders = includeResponseHeaders;
_auditScopeFactory = auditScopeFactory;
_auditDataProvider = auditDataProvider;
}

public object BeforeSendRequest(ref Message request, IClientChannel channel)
Expand All @@ -39,12 +44,15 @@ public object BeforeSendRequest(ref Message request, IClientChannel channel)
WcfClientEvent = auditWcfEvent
};

var auditScopeFactory = _auditScopeFactory ?? Configuration.AuditScopeFactory;

// Create the audit scope
var auditScope = Configuration.AuditScopeFactory.Create(new AuditScopeOptions()
var auditScope = auditScopeFactory.Create(new AuditScopeOptions()
{
EventType = eventType,
AuditEvent = auditEventWcf,
SkipExtraFrames = 8
SkipExtraFrames = 8,
DataProvider = _auditDataProvider
});
return auditScope;
}
Expand Down
Loading

0 comments on commit 3405d81

Please sign in to comment.