Пример #1
0
        /// <summary>
        /// Occurs before the action method is invoked.
        /// </summary>
        /// <param name="actionContext">The action context.</param>
        public override void OnActionExecuting(HttpActionContext actionContext)
        {
            var request        = actionContext.Request;
            var contextWrapper = new ContextWrapper(request);
            var auditAction    = new AuditApiAction
            {
                UserName         = actionContext.RequestContext?.Principal?.Identity?.Name,
                IpAddress        = contextWrapper.GetClientIp(),
                RequestUrl       = request.RequestUri?.AbsoluteUri,
                HttpMethod       = actionContext.Request.Method?.Method,
                FormVariables    = contextWrapper.GetFormVariables(),
                Headers          = IncludeHeaders ? ToDictionary(request.Headers) : null,
                ActionName       = actionContext.ActionDescriptor?.ActionName,
                ControllerName   = actionContext.ActionDescriptor?.ControllerDescriptor?.ControllerName,
                ActionParameters = actionContext.ActionArguments
            };
            var eventType = (EventTypeName ?? "{verb} {controller}/{action}").Replace("{verb}", auditAction.HttpMethod)
                            .Replace("{controller}", auditAction.ControllerName)
                            .Replace("{action}", auditAction.ActionName);
            // Create the audit scope
            var auditEventAction = new AuditEventWebApi()
            {
                Action = auditAction
            };
            var options = new AuditScopeOptions()
            {
                EventType     = eventType,
                AuditEvent    = auditEventAction,
                CallingMethod = (actionContext.ActionDescriptor as ReflectedHttpActionDescriptor)?.MethodInfo
            };
            var auditScope = AuditScope.Create(options);

            contextWrapper.Set(AuditApiActionKey, auditAction);
            contextWrapper.Set(AuditApiScopeKey, auditScope);
        }
Пример #2
0
        /// <summary>
        /// Creates the Audit scope asynchronously.
        /// </summary>
        public async Task <IAuditScope> CreateAuditScopeAsync(IAuditDbContext context, EntityFrameworkEvent efEvent)
        {
            var typeName     = context.GetType().Name;
            var eventType    = context.AuditEventType?.Replace("{context}", typeName).Replace("{database}", efEvent.Database) ?? typeName;
            var auditEfEvent = new AuditEventEntityFramework
            {
                EntityFrameworkEvent = efEvent
            };

            if (context.ExtraFields != null && context.ExtraFields.Count > 0)
            {
                auditEfEvent.CustomFields = new Dictionary <string, object>(context.ExtraFields);
            }
            var factory = context.AuditScopeFactory ?? Core.Configuration.AuditScopeFactory;
            var options = new AuditScopeOptions()
            {
                EventType       = eventType,
                CreationPolicy  = EventCreationPolicy.Manual,
                DataProvider    = context.AuditDataProvider,
                AuditEvent      = auditEfEvent,
                SkipExtraFrames = 3
            };
            var scope = await factory.CreateAsync(options);

            context.OnScopeCreated(scope);
            return(scope);
        }
Пример #3
0
        /// <summary>
        /// Occurs before the action method is invoked.
        /// </summary>
        /// <param name="actionContext">The action context.</param>
        public async Task BeforeExecutingAsync(HttpActionContext actionContext, IContextWrapper contextWrapper, bool includeHeaders, bool includeRequestBody, bool serializeParams, string eventTypeName)
        {
            var request     = actionContext.Request;
            var auditAction = new AuditApiAction
            {
                UserName         = actionContext.RequestContext?.Principal?.Identity?.Name,
                IpAddress        = contextWrapper.GetClientIp(),
                RequestUrl       = request.RequestUri?.AbsoluteUri,
                HttpMethod       = actionContext.Request.Method?.Method,
                FormVariables    = contextWrapper.GetFormVariables(),
                Headers          = includeHeaders ? ToDictionary(request.Headers) : null,
                ActionName       = actionContext.ActionDescriptor?.ActionName,
                ControllerName   = actionContext.ActionDescriptor?.ControllerDescriptor?.ControllerName,
                ActionParameters = GetActionParameters(actionContext.ActionArguments, serializeParams),
                RequestBody      = includeRequestBody ? GetRequestBody(contextWrapper) : null
            };
            var eventType = (eventTypeName ?? "{verb} {controller}/{action}").Replace("{verb}", auditAction.HttpMethod)
                            .Replace("{controller}", auditAction.ControllerName)
                            .Replace("{action}", auditAction.ActionName);
            // Create the audit scope
            var auditEventAction = new AuditEventWebApi()
            {
                Action = auditAction
            };
            var options = new AuditScopeOptions()
            {
                EventType     = eventType,
                AuditEvent    = auditEventAction,
                CallingMethod = (actionContext.ActionDescriptor as ReflectedHttpActionDescriptor)?.MethodInfo
            };
            var auditScope = await AuditScope.CreateAsync(options);

            contextWrapper.Set(AuditApiActionKey, auditAction);
            contextWrapper.Set(AuditApiScopeKey, auditScope);
        }
Пример #4
0
        /// <summary>
        /// Creates the Audit scope asynchronously.
        /// </summary>
        public async Task <IAuditScope> CreateAuditScopeAsync(IAuditDbContext context, EntityFrameworkEvent efEvent)
        {
            var typeName     = context.GetType().Name;
            var eventType    = context.AuditEventType?.Replace("{context}", typeName).Replace("{database}", efEvent.Database) ?? typeName;
            var auditEfEvent = new AuditEventEntityFramework
            {
                EntityFrameworkEvent = efEvent
            };
            var factory = context.AuditScopeFactory ?? Core.Configuration.AuditScopeFactory;
            var options = new AuditScopeOptions()
            {
                EventType       = eventType,
                CreationPolicy  = EventCreationPolicy.Manual,
                DataProvider    = context.AuditDataProvider,
                AuditEvent      = auditEfEvent,
                SkipExtraFrames = 3
            };
            var scope = await factory.CreateAsync(options);

            if (context.ExtraFields != null)
            {
                foreach (var field in context.ExtraFields)
                {
                    scope.SetCustomField(field.Key, field.Value);
                }
            }
            context.OnScopeCreated(scope);
            return(scope);
        }
        /// <inheritdoc />
        public virtual bool Exists(TKey id)
        {
            bool exists = DecoratedService.Exists(id);

            try
            {
                var options = new AuditScopeOptions
                {
                    EventType   = $"{EntityName}:Exists",
                    ExtraFields = new { Id = id, Exists = exists },
                    AuditEvent  = new AuditEvent {
                        Target = new AuditTarget()
                    }
                };

                using (var auditScope = AuditScope.Create(options))
                {
                    auditScope.Event.Environment.UserName = UserContext.CurrentUser;
                    auditScope.Event.Target.Type          = $"{EntityFullName}";
                }
            }
            catch (Exception e)
            {
                Logger.Warning(e, "Auditing failed for Exists of type {Entity} with ID {Id}.", EntityName, id);
            }

            return(exists);
        }
        /// <inheritdoc />
        public virtual int Count(Expression <Func <TEntity, bool> > filter = null)
        {
            int count = DecoratedService.Count(filter);

            try
            {
                var options = new AuditScopeOptions
                {
                    EventType   = $"{EntityName}:Count",
                    ExtraFields = new { Count = count },
                    AuditEvent  = new AuditEvent {
                        Target = new AuditTarget()
                    }
                };

                using (var auditScope = AuditScope.Create(options))
                {
                    auditScope.Event.Environment.UserName = UserContext.CurrentUser;
                    auditScope.Event.Target.Type          = $"{EntityFullName}";
                }
            }
            catch (Exception e)
            {
                Logger.Warning(e, "Auditing failed for Count of type {Entity}.", EntityName);
            }

            return(count);
        }
        /// <inheritdoc />
        public virtual IEnumerable <TEntity> Retrieve(
            Expression <Func <TEntity, bool> > filter = null,
            PagingContext pagingContext = null,
            Func <IQueryable <TEntity>, IOrderedQueryable <TEntity> > sortCondition = null,
            params Expression <Func <TEntity, object> >[] includes)
        {
            IEnumerable <TEntity> retrieved =
                DecoratedService.Retrieve(filter, pagingContext, sortCondition, includes).ToList();

            try
            {
                // Due to size constraints, only audit the number of objects retrieved rather than the objects themselves.
                var options = new AuditScopeOptions
                {
                    EventType   = $"{EntityName}:Retrieve+",
                    ExtraFields = new { Count = retrieved.Count() },
                    AuditEvent  = new AuditEvent {
                        Target = new AuditTarget()
                    }
                };

                using (var auditScope = AuditScope.Create(options))
                {
                    auditScope.Event.Environment.UserName = UserContext.CurrentUser;
                    auditScope.Event.Target.Type          = $"{EntityFullName}";
                }
            }
            catch (Exception e)
            {
                Logger.Warning(e, "Auditing failed for Retrieve+ of type {Entity}.", EntityName);
            }

            return(retrieved);
        }
Пример #8
0
        public override void OnActionExecuting(ActionExecutingContext filterContext)
        {
            var request     = filterContext.HttpContext.Request;
            var auditAction = new AuditAction()
            {
                UserName         = (request.IsAuthenticated) ? filterContext.HttpContext.User?.Identity.Name : "Anonymous",
                IpAddress        = request.ServerVariables?["HTTP_X_FORWARDED_FOR"] ?? request.UserHostAddress,
                RequestUrl       = request.RawUrl,
                HttpMethod       = request.HttpMethod,
                FormVariables    = ToDictionary(request.Form),
                Headers          = IncludeHeaders ? ToDictionary(request.Headers) : null,
                ActionName       = filterContext.ActionDescriptor?.ActionName,
                ControllerName   = filterContext.ActionDescriptor?.ControllerDescriptor?.ControllerName,
                ActionParameters = filterContext.ActionParameters?.ToDictionary(k => k.Key, v => v.Value)
            };
            var eventType = (EventTypeName ?? "{verb} {controller}/{action}").Replace("{verb}", auditAction.HttpMethod)
                            .Replace("{controller}", auditAction.ControllerName)
                            .Replace("{action}", auditAction.ActionName);
            // Create the audit scope
            var auditEventAction = new AuditEventMvcAction()
            {
                Action = auditAction
            };
            var options = new AuditScopeOptions()
            {
                EventType     = eventType,
                AuditEvent    = auditEventAction,
                CallingMethod = (filterContext.ActionDescriptor as ReflectedActionDescriptor)?.MethodInfo
            };
            var auditScope = AuditScope.Create(options);

            filterContext.HttpContext.Items[AuditActionKey] = auditAction;
            filterContext.HttpContext.Items[AuditScopeKey]  = auditScope;
            base.OnActionExecuting(filterContext);
        }
Пример #9
0
        public void Test_AuditScopeCreation_WithExistingAuditEvent_WithCustomFields()
        {
            var evs_onScopeCreated = new List <AuditEvent>();
            var evs_Provider       = new List <AuditEvent>();

            Audit.Core.Configuration.Setup()
            .AuditDisabled(false)
            .UseDynamicProvider(x => x
                                .OnInsertAndReplace(ev =>
            {
                evs_Provider.Add(AuditEvent.FromJson(ev.ToJson()));
            }))
            .WithCreationPolicy(EventCreationPolicy.InsertOnEnd)
            .WithAction(_ => _.OnScopeCreated(scope =>
            {
                evs_onScopeCreated.Add(AuditEvent.FromJson(scope.Event.ToJson()));
            }));

            var auditEvent = new AuditEvent()
            {
                EventType    = "test",
                CustomFields = new Dictionary <string, object>()
                {
                    { "FromCustomField", 1 }
                }
            };
            var options = new AuditScopeOptions()
            {
                AuditEvent  = auditEvent,
                ExtraFields = new { FromAnon = 2 }
            };

            using (var scope = AuditScope.Create(options))
            {
                scope.SetCustomField("FromScope", 3);
            }

            Assert.AreEqual(1, evs_onScopeCreated.Count);
            Assert.AreEqual(2, evs_onScopeCreated[0].CustomFields.Count);
            Assert.IsTrue(evs_onScopeCreated[0].CustomFields.ContainsKey("FromCustomField"));
            Assert.IsTrue(evs_onScopeCreated[0].CustomFields.ContainsKey("FromAnon"));
            Assert.AreEqual(1, evs_onScopeCreated[0].CustomFields["FromCustomField"]);
            Assert.AreEqual(2, evs_onScopeCreated[0].CustomFields["FromAnon"]);

            Assert.AreEqual(1, evs_Provider.Count);
            Assert.AreEqual(3, evs_Provider[0].CustomFields.Count);
            Assert.IsTrue(evs_Provider[0].CustomFields.ContainsKey("FromCustomField"));
            Assert.IsTrue(evs_Provider[0].CustomFields.ContainsKey("FromAnon"));
            Assert.IsTrue(evs_Provider[0].CustomFields.ContainsKey("FromScope"));
            Assert.AreEqual(1, evs_Provider[0].CustomFields["FromCustomField"]);
            Assert.AreEqual(2, evs_Provider[0].CustomFields["FromAnon"]);
            Assert.AreEqual(3, evs_Provider[0].CustomFields["FromScope"]);
        }
        /// <inheritdoc />
        public virtual async Task <IEnumerable <TEntity> > RetrieveAsync(
            Expression <Func <TEntity, bool> > filter = null,
            PagingContext pagingContext = null,
            Func <IQueryable <TEntity>, IOrderedQueryable <TEntity> > sortCondition = null,
            CancellationToken cancellationToken = default,
            params Expression <Func <TEntity, object> >[] includes)
        {
            IEnumerable <TEntity> entities = await DecoratedService.RetrieveAsync(
                filter,
                pagingContext,
                sortCondition,
                cancellationToken,
                includes);

            IEnumerable <TEntity> retrieved  = entities.ToList();
            AuditScope            auditScope = null;

            try
            {
                // Due to size constraints, only audit the number of objects retrieved rather than the objects
                // themselves.
                var options = new AuditScopeOptions
                {
                    EventType   = $"{EntityName}:Retrieve+",
                    ExtraFields = new { Count = retrieved.Count() },
                    AuditEvent  = new AuditEvent {
                        Target = new AuditTarget()
                    }
                };

                auditScope = await AuditScope.CreateAsync(options);

                auditScope.Event.Environment.UserName = UserContext.CurrentUser;
                auditScope.Event.Target.Type          = $"{EntityFullName}";
            }
            catch (Exception e)
            {
                Logger.Warning(e, "Auditing failed for RetrieveAsync+ of type {Entity}.", EntityName);
            }
            finally
            {
                if (auditScope != null)
                {
                    await auditScope.DisposeAsync();
                }
            }

            return(retrieved);
        }
Пример #11
0
        private async Task <IAuditScope> CreateAuditScopeAsync(AuditEventCommandEntityFramework cmdEvent)
        {
            var eventType = AuditEventType?
                            .Replace("{database}", cmdEvent.CommandEvent.Database)
                            .Replace("{method}", cmdEvent.CommandEvent.Method.ToString());
            var factory = Core.Configuration.AuditScopeFactory;
            var options = new AuditScopeOptions()
            {
                EventType       = eventType,
                AuditEvent      = cmdEvent,
                SkipExtraFrames = 3
            };

            return(await factory.CreateAsync(options));
        }
Пример #12
0
        public override void OnActionExecuting(ActionExecutingContext filterContext)
        {
            if (Configuration.AuditDisabled || IsActionIgnored(filterContext.ActionDescriptor))
            {
                base.OnActionExecuting(filterContext);
                return;
            }
            var request     = filterContext.HttpContext.Request;
            var auditAction = new AuditAction()
            {
                UserName  = (request.IsAuthenticated) ? filterContext.HttpContext.User?.Identity.Name : "Anonymous",
                IpAddress = request.ServerVariables?["HTTP_X_FORWARDED_FOR"] ?? request.UserHostAddress,
#if NET45
                RequestUrl    = request.Unvalidated.RawUrl,
                FormVariables = ToDictionary(request.Unvalidated.Form),
                Headers       = IncludeHeaders ? ToDictionary(request.Unvalidated.Headers) : null,
#else
                RequestUrl    = request.RawUrl,
                FormVariables = ToDictionary(request.Form),
                Headers       = IncludeHeaders ? ToDictionary(request.Headers) : null,
#endif
                RequestBody      = IncludeRequestBody ? GetRequestBody(filterContext.HttpContext) : null,
                HttpMethod       = request.HttpMethod,
                ActionName       = filterContext.ActionDescriptor?.ActionName,
                ControllerName   = filterContext.ActionDescriptor?.ControllerDescriptor?.ControllerName,
                ActionParameters = GetActionParameters(filterContext),
                TraceId          = null
            };
            var eventType = (EventTypeName ?? "{verb} {controller}/{action}").Replace("{verb}", auditAction.HttpMethod)
                            .Replace("{controller}", auditAction.ControllerName)
                            .Replace("{action}", auditAction.ActionName);
            // Create the audit scope
            var auditEventAction = new AuditEventMvcAction()
            {
                Action = auditAction
            };
            var options = new AuditScopeOptions()
            {
                EventType     = eventType,
                AuditEvent    = auditEventAction,
                CallingMethod = (filterContext.ActionDescriptor as ReflectedActionDescriptor)?.MethodInfo
            };
            var auditScope = AuditScope.Create(options);

            filterContext.HttpContext.Items[AuditActionKey] = auditAction;
            filterContext.HttpContext.Items[AuditScopeKey]  = auditScope;
            base.OnActionExecuting(filterContext);
        }
        /// <inheritdoc />
        public virtual async Task <int> CountAsync(
            Expression <Func <TEntity, bool> > filter = null,
            CancellationToken cancellationToken       = default)
        {
            int count = await DecoratedService.CountAsync(filter, cancellationToken);

            AuditScope auditScope = null;

            try
            {
                var options = new AuditScopeOptions
                {
                    EventType   = $"{EntityName}:Count",
                    ExtraFields = new { Count = count },
                    AuditEvent  = new AuditEvent {
                        Target = new AuditTarget()
                    }
                };

                auditScope = await AuditScope.CreateAsync(options);

                auditScope.Event.Environment.UserName = UserContext.CurrentUser;
                auditScope.Event.Target.Type          = $"{EntityFullName}";
            }
            catch (Exception e)
            {
                Logger.Warning(e, "Auditing failed for CountAsync of type {Entity}.", EntityName);
            }
            finally
            {
                if (auditScope != null)
                {
                    await auditScope.DisposeAsync();
                }
            }

            return(count);
        }
Пример #14
0
        public void Test_DataProviderFactory()
        {
            GetProviderCount = 0;
            var options = new AuditScopeOptions(_ => _.DataProvider(GetProvider).CreationPolicy(EventCreationPolicy.InsertOnStartReplaceOnEnd));

            Assert.AreEqual(0, GetProviderCount);
            using (var scope = AuditScope.Create(options))
            {
                Assert.AreEqual(1, GetProviderCount);
                scope.SetCustomField("custom", "value");
                scope.Save();
            }
            Assert.AreEqual(1, GetProviderCount);
            options = new AuditScopeOptions(_ => _.DataProvider(GetProvider).CreationPolicy(EventCreationPolicy.Manual));
            using (var scope = new AuditScope(options))
            {
                Assert.AreEqual(2, GetProviderCount);
                scope.Save();
                scope.Save();
            }
            Assert.AreEqual(2, GetProviderCount);
            Audit.Core.Configuration.DataProviderFactory = GetProvider;
            using (var scope = AuditScope.Create("Test", null, new { custom = "value" }))
            {
                Assert.AreEqual(3, GetProviderCount);
                scope.Discard();
            }
            Assert.AreEqual(3, GetProviderCount);

            Audit.Core.Configuration.Setup().UseFactory(GetProvider);
            using (var scope = AuditScope.Create("Test", null, new { custom = "value" }))
            {
                Assert.AreEqual(4, GetProviderCount);
                scope.Save();
            }
            Assert.AreEqual(4, GetProviderCount);
        }
        /// <inheritdoc />
        public virtual async Task <bool> ExistsAsync(TKey id, CancellationToken cancellationToken = default)
        {
            bool exists = await DecoratedService.ExistsAsync(id, cancellationToken);

            AuditScope auditScope = null;

            try
            {
                var options = new AuditScopeOptions
                {
                    EventType   = $"{EntityName}:Exists",
                    ExtraFields = new { Id = id, Exists = exists },
                    AuditEvent  = new AuditEvent {
                        Target = new AuditTarget()
                    }
                };

                auditScope = await AuditScope.CreateAsync(options);

                auditScope.Event.Environment.UserName = UserContext.CurrentUser;
                auditScope.Event.Target.Type          = $"{EntityFullName}";
            }
            catch (Exception e)
            {
                Logger.Warning(e, "Auditing failed for ExistsAsync of type {Entity} with ID {Id}.", EntityName, id);
            }
            finally
            {
                if (auditScope != null)
                {
                    await auditScope.DisposeAsync();
                }
            }

            return(exists);
        }
Пример #16
0
        public void Test_AuditScopeCreation_WithExistingAuditEvent_WithEventType()
        {
            var evs = new List <AuditEvent>();

            Audit.Core.Configuration.Setup()
            .AuditDisabled(false)
            .UseDynamicProvider(x => x
                                .OnInsertAndReplace(ev =>
            {
                evs.Add(AuditEvent.FromJson(ev.ToJson()));
            }))
            .WithCreationPolicy(EventCreationPolicy.InsertOnEnd);

            var auditEvent = new AuditEvent()
            {
                EventType = "test"
            };
            var options = new AuditScopeOptions()
            {
                EventType  = null, // NULL means do not override eventtype
                AuditEvent = auditEvent
            };

            // scope with pre-assigned event type
            using (var scope = AuditScope.Create(options))
            {
            }
            // scope with event type to override
            options.EventType = "override";
            using (var scope = AuditScope.Create(options))
            {
            }
            Assert.AreEqual(2, evs.Count);
            Assert.AreEqual("test", evs[0].EventType);
            Assert.AreEqual("override", evs[1].EventType);
        }
    /// <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();
    }