/// <summary> /// Ends the event for asynchronous interceptions. /// </summary> private static void EndAsyncAuditInterceptEvent(Task task, IInvocation invocation, InterceptEvent intEvent, AuditScope scope, object result) { intEvent.AsyncStatus = task.Status.ToString(); if (task.Status == TaskStatus.Faulted) { intEvent.Exception = task.Exception?.GetExceptionInfo(); } else if (task.Status == TaskStatus.RanToCompletion) { SuccessAuditInterceptEvent(invocation, intEvent, result); } scope.Save(); }
/// <summary> /// Intercept an asynchronous operation that returns a Task. /// </summary> private static async Task InterceptAsync(Task task, IInvocation invocation, InterceptEvent intEvent, AuditScope scope) { try { await task.ConfigureAwait(false); } catch { EndAsyncAuditInterceptEvent(task, invocation, intEvent, scope, null); throw; } EndAsyncAuditInterceptEvent(task, invocation, intEvent, scope, "Void"); }
/// <summary> /// Intercept an asynchronous operation that returns a Task Of[T]. /// </summary> private static async Task <T> InterceptAsync <T>(Task <T> task, IInvocation invocation, InterceptEvent intEvent, AuditScope scope) { T result; try { result = await task.ConfigureAwait(false); } catch { EndAsyncAuditInterceptEvent(task, invocation, intEvent, scope, null); throw; } EndAsyncAuditInterceptEvent(task, invocation, intEvent, scope, result); return(result); }
/// <summary> /// Called after the audit scope is created. /// Override to specify custom logic. /// </summary> /// <param name="auditScope">The audit scope.</param> public virtual void OnScopeCreated(AuditScope auditScope) { }
/// <summary> /// Gets the Entity Framework Event portion of the Audit Event on the given scope. /// </summary> /// <param name="auditScope">The audit scope.</param> public static HttpAction GetHttpAction(this AuditScope auditScope) { return(auditScope?.Event.GetHttpAction()); }
public override void OnScopeSaving(AuditScope auditScope) { try { // ... custom log saving ... UnitOfWork _uow = new UnitOfWork(); var date = DateTime.Now; var entryList = auditScope.Event.GetEntityFrameworkEvent().Entries; //TODO: Revisar nombre devuelto en servidor var userName = /*auditScope.Event.Environment.DomainName + "\\" +*/ auditScope.Event.Environment.UserName; foreach (var entry in entryList.Where(x => x.Action == "Update")) { List <AuditChangeModel> changeModelList = new List <AuditChangeModel>(); foreach (var change in entry.Changes) { if (change != null && change.NewValue != null && change.OriginalValue != null && !change.NewValue.Equals(change.OriginalValue) && !ignoredColumns.Contains(change.ColumnName)) { AuditChangeModel changeModel = new AuditChangeModel { ColumnName = change.ColumnName, OldValue = change.OriginalValue, NewValue = change.NewValue }; changeModelList.Add(changeModel); } } if (changeModelList.Count > 0) { _uow.AuditoriaRepository.Create(new Auditoria() { UserName = userName, Date = date, Entity = entry.Table, EntityId = entry.PrimaryKey[entry.Table + "Id"].ToString(), Action = entry.Action, Value = JsonConvert.SerializeObject(changeModelList), TransactionId = auditScope.Event.GetEntityFrameworkEvent().TransactionId, Descripcion = "Se actualizó el registro ID " + entry.PrimaryKey[entry.Table + "Id"].ToString() + " de la tabla " + entry.Table }); } } var entitiesCreatedList = entryList.Where(x => x.Action == "Insert").Select(x => x.Table).Distinct(); foreach (var table in entitiesCreatedList) { foreach (var entry in entryList.Where(x => x.Action == "Insert" && x.Table == table)) { var entriesDeleted = entryList.Where(x => x.Action == "Delete").Select(x => x.PrimaryKey); if (!DictionaryContains(entriesDeleted, entry.PrimaryKey)) { Auditoria auditoria = new Auditoria { UserName = userName, Date = date, Entity = entry.Table, Action = entry.Action, TransactionId = auditScope.Event.GetEntityFrameworkEvent().TransactionId, Descripcion = "Nuevo registro en la tabla " + entry.Table }; auditoria.Value = JsonConvert.SerializeObject((dynamic)entry.Entity, Formatting.Indented, new JsonSerializerSettings { ReferenceLoopHandling = ReferenceLoopHandling.Ignore }); _uow.AuditoriaRepository.Create(auditoria); } } } var entitiesDeletedList = entryList.Where(x => x.Action == "Delete").Select(x => x.Table).Distinct(); foreach (var table in entitiesDeletedList) { foreach (var entry in entryList.Where(x => x.Action == "Delete" && x.Table == table)) { var entriesCreated = entryList.Where(x => x.Action == "Insert").Select(x => x.PrimaryKey); if (!DictionaryContains(entriesCreated, entry.PrimaryKey)) { _uow.AuditoriaRepository.Create(new Auditoria() { UserName = userName, Date = date, Entity = entry.Table, //EntityId = entry.PrimaryKey[entry.Table + "Id"].ToString(), Action = entry.Action, Value = JsonConvert.SerializeObject((dynamic)entry.Entity, Formatting.None, new JsonSerializerSettings { ReferenceLoopHandling = ReferenceLoopHandling.Ignore }), TransactionId = auditScope.Event.GetEntityFrameworkEvent().TransactionId, Descripcion = "Registro eliminado de la tabla " + entry.Table }); } } } _uow.Save(); } catch { // Rollback call is not mandatory. If exception thrown, the transaction won't get commited Database.CurrentTransaction.Rollback(); throw; } Database.CurrentTransaction.Commit(); }
public override void OnScopeCreated(AuditScope auditScope) { Database.BeginTransaction(); }
/// <summary> /// Saves the scope. /// </summary> private void SaveScope(AuditScope scope, EntityFrameworkEvent @event) { (scope.Event as AuditEventEntityFramework).EntityFrameworkEvent = @event; OnScopeSaving(scope); scope.Save(); }
/// <summary> /// Gets the Entity Framework Event portion of the Audit Event on the given scope. /// </summary> /// <param name="auditScope">The audit scope.</param> public static EntityFrameworkEvent GetEntityFrameworkEvent(this AuditScope auditScope) { return(auditScope?.Event.GetEntityFrameworkEvent()); }
/// <summary> /// Intercepts the specified invocation. /// </summary> public void Intercept(IInvocation invocation) { var intEvent = CreateAuditInterceptEvent(invocation); if (intEvent == null) { // bypass invocation.Proceed(); return; } var method = invocation.MethodInvocationTarget; var eventTypeAttribute = method.GetCustomAttribute(typeof(EventTypeAttribute), false); var eventType = eventTypeAttribute != null ? ((EventTypeAttribute)eventTypeAttribute).EventType : Settings.EventType?.Replace("{class}", intEvent.ClassName).Replace("{method}", intEvent.MethodName); var isAsync = method.GetCustomAttribute(typeof(AsyncStateMachineAttribute)) != null; intEvent.IsAsync = isAsync; var auditEventIntercept = new AuditEventIntercept() { InterceptEvent = intEvent }; var scopeOptions = new AuditScopeOptions() { EventType = eventType, CreationPolicy = Settings.EventCreationPolicy, DataProvider = Settings.AuditDataProvider, AuditEvent = auditEventIntercept }; var scope = AuditScope.Create(scopeOptions); AuditProxy.CurrentScope = scope; // Call the intercepted method (sync part) try { invocation.Proceed(); } catch (Exception ex) { intEvent.Exception = ex.GetExceptionInfo(); scope.Dispose(); throw; } // Handle async calls var returnType = method.ReturnType; if (isAsync) { if (typeof(Task).IsAssignableFrom(returnType)) { invocation.ReturnValue = InterceptAsync((dynamic)invocation.ReturnValue, invocation, intEvent, scope); return; } } // Is a Sync method (or an Async method that does not returns a Task or Task<>). // Avoid Task and Task<T> serialization (i.e. when a sync method returns a Task) object returnValue = typeof(Task).IsAssignableFrom(returnType) ? null : invocation.ReturnValue; SuccessAuditInterceptEvent(invocation, intEvent, returnValue); if (!isAsync) { AuditProxy.CurrentScope = null; } scope.Dispose(); }
/// <summary> /// Gets the Dynamic Interception Event portion of the Audit Event for the given scope. /// </summary> /// <param name="auditScope">The audit scope.</param> public static InterceptEvent GetAuditInterceptEvent(this AuditScope auditScope) { return(auditScope?.Event.GetAuditInterceptEvent()); }
/// <summary> /// Gets the Web API Event portion of the Audit Event for a given scope. /// </summary> /// <param name="auditScope">The audit scope.</param> public static AuditApiAction GetWebApiAuditAction(this AuditScope auditScope) { return(auditScope?.Event.GetWebApiAuditAction()); }
/// <summary> /// Initializes a <see cref="AuditableAttribute"/> class. /// </summary> /// <param name="auditScope">The audit scope.</param> public AuditableAttribute(AuditScope auditScope) { AuditScope = auditScope; }
public void Redis_Errors() { //string var key = Guid.NewGuid().ToString(); Core.Configuration.Setup() .UseRedis(redis => redis .ConnectionString(RedisCnnString) .AsString(_ => { })) .WithCreationPolicy(EventCreationPolicy.InsertOnEnd); try { using (var scope = AuditScope.Create(new AuditScopeOptions() { EventType = $"Redis_Errors" })) {} } catch (ArgumentException ae) { Assert.IsTrue(ae.Message.ToLower().Contains("redis key")); } //hash key = DateTime.UtcNow.ToString("yyyyMMddHHmmssfff"); Core.Configuration.Setup() .UseRedis(redis => redis .ConnectionString(RedisCnnString) .AsHash(_ => _.Key("petete"))) .WithCreationPolicy(EventCreationPolicy.InsertOnEnd); try { using (var scope = AuditScope.Create(new AuditScopeOptions() { EventType = $"Redis_Errors" })){} } catch (ArgumentException ae) { Assert.IsTrue(ae.Message.ToLower().Contains("hash field")); } //ss key = DateTime.UtcNow.ToString("yyyyMMddHHmmssfff"); Core.Configuration.Setup() .UseRedis(redis => redis .ConnectionString(RedisCnnString) .AsSortedSet(_ => _.Key("potato"))) .WithCreationPolicy(EventCreationPolicy.InsertOnEnd); try { using (var scope = AuditScope.Create(new AuditScopeOptions() { EventType = $"Redis_Errors" })) { } } catch (ArgumentException ae) { Assert.IsTrue(ae.Message.ToLower().Contains("score builder")); } //pubsub key = DateTime.UtcNow.ToString("yyyyMMddHHmmssfff"); Core.Configuration.Setup() .UseRedis(redis => redis .ConnectionString(RedisCnnString) .AsPubSub(_ => { })) .WithCreationPolicy(EventCreationPolicy.InsertOnEnd); try { using (var scope = AuditScope.Create(new AuditScopeOptions() { EventType = $"Redis_Errors" })) { } } catch (ArgumentException ae) { Assert.IsTrue(ae.Message.ToLower().Contains("channel")); } }
/// <summary> /// Gets the WCF Event portion of the Audit Event for a given scope. /// </summary> /// <param name="auditScope">The audit scope.</param> public static WcfEvent GetWcfAuditAction(this AuditScope auditScope) { return(auditScope?.Event.GetWcfAuditAction()); }
/// <summary> /// Saves the scope. /// </summary> public void SaveScope(IAuditDbContext context, AuditScope scope, EntityFrameworkEvent @event) { (scope.Event as AuditEventEntityFramework).EntityFrameworkEvent = @event; context.OnScopeSaving(scope); scope.Save(); }
public override void OnScopeCreated(AuditScope auditScope) { auditScope.Event.GetEntityFrameworkEvent().TransactionId = Guid.NewGuid().ToString(); Database.BeginTransaction(); }
/// <summary> /// Saves the scope. /// </summary> private void SaveScope(AuditScope scope, EntityFrameworkEvent @event) { scope.SetCustomField("EntityFrameworkEvent", @event); OnScopeSaving(scope); scope.Save(); }
public async Task TestUpdateAsync() { var order = DbCreateOrder(); var reasonText = "the order was updated because ..."; var eventType = "Order:Update"; var ev = (AuditEvent)null; var ids = new List <object>(); Audit.Core.Configuration.ResetCustomActions(); Audit.Core.Configuration.AddCustomAction(ActionType.OnEventSaved, scope => { ids.Add(scope.EventId); }); //struct using (var a = await AuditScope.CreateAsync(eventType, () => new TestStruct() { Id = 123, Order = order }, new { ReferenceId = order.OrderId })) { ev = a.Event; a.SetCustomField("$TestGuid", Guid.NewGuid()); a.SetCustomField("$null", (string)null); a.SetCustomField("$array.dicts", new[] { new Dictionary <string, string>() { { "some.dots", "hi!" } } }); order = DbOrderUpdateStatus(order, OrderStatus.Submitted); await a.DisposeAsync(); } var dpType = Configuration.DataProvider.GetType().Name; var evFromApi = (dpType == "UdpDataProvider" || dpType == "EventLogDataProvider" || dpType == "AzureTableDataProvider") ? ev : await Audit.Core.Configuration.DataProvider.GetEventAsync(ids[0]); Assert.AreEqual(2, ids.Count); Assert.AreEqual(ids[0], ids[1]); Assert.AreEqual(ev.EventType, evFromApi.EventType); Assert.AreEqual(ev.StartDate.ToUniversalTime().ToString("yyyyMMddHHmmss"), evFromApi.StartDate.ToUniversalTime().ToString("yyyyMMddHHmmss")); Assert.AreEqual(ev.EndDate.Value.ToUniversalTime().ToString("yyyyMMddHHmmss"), evFromApi.EndDate.Value.ToUniversalTime().ToString("yyyyMMddHHmmss")); Assert.AreEqual(ev.CustomFields["ReferenceId"], evFromApi.CustomFields["ReferenceId"]); if (dpType != "ElasticsearchDataProvider") { Assert.AreEqual((int)OrderStatus.Created, (int)((dynamic)ev.Target.SerializedOld).Order.Status); Assert.AreEqual((int)OrderStatus.Submitted, (int)((dynamic)ev.Target.SerializedNew).Order.Status); } else { Assert.AreEqual(OrderStatus.Created, JsonConvert.DeserializeObject <TestStruct>(ev.Target.SerializedOld.ToString()).Order.Status); Assert.AreEqual(OrderStatus.Submitted, JsonConvert.DeserializeObject <TestStruct>(ev.Target.SerializedNew.ToString()).Order.Status); } Assert.AreEqual(order.OrderId, ev.CustomFields["ReferenceId"]); order = DbCreateOrder(); //audit multiple using (var a = await AuditScope.CreateAsync(eventType, () => new TestStruct() { Id = 123, Order = order }, new { ReferenceId = order.OrderId })) { ev = a.Event; order = DbOrderUpdateStatus(order, OrderStatus.Submitted); } Assert.AreEqual(order.OrderId, ev.CustomFields["ReferenceId"]); order = DbCreateOrder(); using (var audit = await AuditScope.CreateAsync("Order:Update", () => new TestStruct() { Id = 123, Order = order }, new { ReferenceId = order.OrderId })) { ev = audit.Event; audit.SetCustomField("Reason", reasonText); audit.SetCustomField("ItemsBefore", order.OrderItems); audit.SetCustomField("FirstItem", order.OrderItems.FirstOrDefault()); order = DbOrderUpdateStatus(order, IntegrationTests.OrderStatus.Submitted); audit.SetCustomField("ItemsAfter", order.OrderItems); audit.Comment("Status Updated to Submitted"); audit.Comment("Another Comment"); } Assert.AreEqual(order.OrderId, ev.CustomFields["ReferenceId"]); order = DbCreateOrder(); using (var audit = await AuditScope.CreateAsync(eventType, () => new TestStruct() { Id = 123, Order = order }, new { ReferenceId = order.OrderId })) { ev = audit.Event; audit.SetCustomField("Reason", "reason"); ExecuteStoredProcedure(order, IntegrationTests.OrderStatus.Submitted); order.Status = IntegrationTests.OrderStatus.Submitted; audit.Comment("Status Updated to Submitted"); } Assert.AreEqual(order.OrderId, ev.CustomFields["ReferenceId"]); Audit.Core.Configuration.ResetCustomActions(); }
/// <summary> /// Called after the audit scope is created. /// Override to specify custom logic. /// </summary> /// <param name="auditScope">The audit scope.</param> protected virtual void OnScopeCreated(AuditScope auditScope) { }
public void TestUpdate() { var order = DbCreateOrder(); var reasonText = "the order was updated because ..."; var eventType = "Order:Update"; var ev = (AuditEvent)null; //struct using (var a = AuditScope.Create(eventType, () => new TestStruct() { Id = 123, Order = order }, new { ReferenceId = order.OrderId })) { ev = a.Event; a.SetCustomField("$TestGuid", Guid.NewGuid()); a.SetCustomField("$null", (string)null); a.SetCustomField("$array.dicts", new[] { new Dictionary <string, string>() { { "some.dots", "hi!" } } }); order = DbOrderUpdateStatus(order, OrderStatus.Submitted); } Assert.Equal(Configuration.DataProvider.Serialize(order.OrderId), ev.CustomFields["ReferenceId"]); order = DbCreateOrder(); //audit multiple using (var a = AuditScope.Create(eventType, () => new { OrderStatus = order.Status, Items = order.OrderItems }, new { ReferenceId = order.OrderId })) { ev = a.Event; order = DbOrderUpdateStatus(order, OrderStatus.Submitted); } Assert.Equal(Configuration.DataProvider.Serialize(order.OrderId), ev.CustomFields["ReferenceId"]); order = DbCreateOrder(); using (var audit = AuditScope.Create("Order:Update", () => order.Status, new { ReferenceId = order.OrderId })) { ev = audit.Event; audit.SetCustomField("Reason", reasonText); audit.SetCustomField("ItemsBefore", order.OrderItems); audit.SetCustomField("FirstItem", order.OrderItems.FirstOrDefault()); order = DbOrderUpdateStatus(order, IntegrationTests.OrderStatus.Submitted); audit.SetCustomField("ItemsAfter", order.OrderItems); audit.Comment("Status Updated to Submitted"); audit.Comment("Another Comment"); } Assert.Equal(Configuration.DataProvider.Serialize(order.OrderId), ev.CustomFields["ReferenceId"]); order = DbCreateOrder(); using (var audit = AuditScope.Create(eventType, () => order, new { ReferenceId = order.OrderId })) { ev = audit.Event; audit.SetCustomField("Reason", "reason"); ExecuteStoredProcedure(order, IntegrationTests.OrderStatus.Submitted); order.Status = IntegrationTests.OrderStatus.Submitted; audit.Comment("Status Updated to Submitted"); } Assert.Equal(Configuration.DataProvider.Serialize(order.OrderId), ev.CustomFields["ReferenceId"]); }
/// <summary> /// Called after the EF operation execution and before the AuditScope saving. /// Override to specify custom logic. /// </summary> /// <param name="auditScope">The audit scope.</param> protected virtual void OnScopeSaving(AuditScope auditScope) { }
/// <summary> /// Called after the EF operation execution and before the AuditScope saving. /// Override to specify custom logic. /// </summary> /// <param name="auditScope">The audit scope.</param> public virtual void OnScopeSaving(AuditScope auditScope) { }
private void SaveAuditScope(AuditScope auditScope, WcfEvent auditWcfEvent) { (auditScope.Event as AuditEventWcfAction).WcfEvent = auditWcfEvent; auditScope.Save(); }