private static async Task AddEventByChecklist(AuditConfig config) { switch (config.int_Period.chr_RepeatPeriod) { case "o": await AddOnceEvents(config); ModifyConfigLastDate(config, 60 * 60 * 60); break; case "d": await AddWeeklyDailyEvents(config); ModifyConfigLastDate(config, 30); break; case "w": await AddWeeklyDailyEvents(config); ModifyConfigLastDate(config, 30); break; case "m": await AddMonthlyEvents(config); ModifyConfigLastDate(config, 240); break; case "q": await AddQuincEvents(config); ModifyConfigLastDate(config, 120); break; } }
private static async Task AddWeeklyDailyEvents(AuditConfig config) { try { var lastDate = (config.dte_LastDateCreated < DateTime.Now) ? DateTime.Now : config.dte_LastDateCreated; for (var day = lastDate; day <= lastDate.AddDays(30); day = day.AddDays(1)) { if (IsValidDay(day, config.int_Period)) { var usersInAudit = db.UsersAudits.Include(x => x.User).Where(x => x.AuditConfig.int_IdAuditConfig == config.int_IdAuditConfig).ToList(); foreach (var asotation in usersInAudit) { AddEvent(day, asotation.User, config); } await db.SaveChangesAsync(); } } } catch (Exception) { throw; } }
private static async Task AddMonthlyEvents(AuditConfig config) { try { var today = (config.dte_LastDateCreated < DateTime.Now) ? DateTime.Now : config.dte_LastDateCreated; var firstDayOfCurrentMonth = new DateTime(today.Year, today.Month, 1); for (var month = firstDayOfCurrentMonth; month <= firstDayOfCurrentMonth.AddMonths(6); month = month.AddMonths(1)) { for (var day = month; day <= month.AddMonths(1); day = day.AddDays(1)) { if (IsValidDay(day, config.int_Period) && day >= DateTime.Now) { var usersInAudit = db.UsersAudits.Include(x => x.User).Where(x => x.AuditConfig.int_IdAuditConfig == config.int_IdAuditConfig).ToList(); foreach (var asotation in usersInAudit) { AddEvent(day, asotation.User, config); } break; } } await db.SaveChangesAsync(); } } catch (Exception) { throw; } }
protected void Application_Start() { AreaRegistration.RegisterAllAreas(); FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters); RouteConfig.RegisterRoutes(RouteTable.Routes); BundleConfig.RegisterBundles(BundleTable.Bundles); AuditConfig.Configure(); }
public static async Task Run(TimerInfo myTimer, CloudTable configTbl, CloudTable statsTbl, CloudTable invalidTypesTbl, ICollector <string> outQueue, TraceWriter log) { _log = log; _outQueue = outQueue; log.Info("Starding subscription audit."); var invalidTagResourcesQuery = await invalidTypesTbl.ExecuteQuerySegmentedAsync(new TableQuery <InvalidTagResource>(), null); var auditConfigQuery = await configTbl.ExecuteQuerySegmentedAsync(new TableQuery <AuditConfig>(), null); // Init config table if new deployment if (auditConfigQuery.Results.Count == 0) { AuditConfig initConfig = new AuditConfig { SubscriptionId = "enter_valid_subscription_id", RowKey = Guid.NewGuid().ToString(), RequiredTags = "comma,separated,tag,list,here", PartitionKey = "init" }; TableOperation insertOperation = TableOperation.InsertOrReplace(initConfig); await configTbl.ExecuteAsync(insertOperation); log.Info("First run for new deployment. Please populate the AuditConfig table."); return; } foreach (var auditConfig in auditConfigQuery.Results) { try { AuditStats stats = new AuditStats { JobStart = DateTime.Now, PartitionKey = auditConfig.SubscriptionId, RowKey = Guid.NewGuid().ToString() }; IEnumerable <string> requiredTagsList = auditConfig.RequiredTags.Split(','); try { string token = await AuthenticationService.GetAccessTokenAsync(); _resourceManager = new ResourceManagerService(token); } catch (Exception ex) { log.Error("Unable to connect to the ARM API, Message: " + ex.Message); } await ProcessResourceGroups(requiredTagsList, invalidTagResourcesQuery.Results, auditConfig.SubscriptionId, stats); log.Info("Completed audit of subscription: " + auditConfig.SubscriptionId); stats.JobEnd = DateTime.Now; TableOperation insertOperation = TableOperation.InsertOrReplace(stats); await statsTbl.ExecuteAsync(insertOperation); } catch (Exception ex) { log.Error("Failure processing resource groups for auditConfig: " + auditConfig.RowKey); log.Error(ex.Message); } } }
public static IServiceCollection AddAutoAudit([NotNull] this IServiceCollection services, Action <IAuditConfigBuilder> configAction) { if (configAction is null) { throw new ArgumentNullException(nameof(configAction)); } AuditConfig.Configure(configAction); return(services); }
private static void AddEvent(DateTime scheduleDate, User user, AuditConfig config, int state = 0) { db.Events.Add(new Event() { chr_Title = "", dte_ScheduleDate = new DateTime(scheduleDate.Year, scheduleDate.Month, scheduleDate.Day), int_State = state, User = user, AuditConfig = config }); }
private void Init(IServiceProvider serviceProvider) { var userIdProvider = serviceProvider.GetService <IUserIdProvider>(); AuditConfig.Configure(builder => { builder.WithUserIdProvider(userIdProvider); builder.EnrichWithProperty("Application", ApplicationHelper.ApplicationName); builder.EnrichWithProperty("Host", Environment.MachineName); }); }
private void LoadConfig() { if (!File.Exists("Config.xml")) { auditConfig = new AuditConfig(); auditConfig.Encryption = EncryptionOptions.Normal; } else { auditConfig = AuditConfig.Load("Config.xml"); } }
static void DetectObsoleteConfiguration(AuditConfig auditConfig) { if (!string.IsNullOrWhiteSpace(auditConfig?.QueueName)) { Logger.Error($"The use of the {nameof(AuditConfig.QueueName)} attribute in the {nameof(AuditConfig)} configuration section is discouraged and will be removed in the next major version. Switch to the code API by using '{nameof(EndpointConfiguration)}.AuditProcessedMessagesTo' instead."); } if (auditConfig?.OverrideTimeToBeReceived != null) { Logger.Error($"The use of the {nameof(AuditConfig.OverrideTimeToBeReceived)} attribute in the {nameof(AuditConfig)} configuration section is discouraged and will be removed in the next major version. Switch to the code API by using '{nameof(EndpointConfiguration)}.AuditProcessedMessagesTo' instead."); } }
protected void Application_Start() { GlobalTrackingConfig.SetSoftDeletableCriteria <ISoftDeletable>(x => x.IsDeleted); EntityTracker.TrackAllProperties <ApplicationUser>(); Database.SetInitializer(new DropCreateDatabaseIfModelChanges <ApplicationDbContext>()); AreaRegistration.RegisterAllAreas(); FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters); RouteConfig.RegisterRoutes(RouteTable.Routes); BundleConfig.RegisterBundles(BundleTable.Bundles); AuditConfig.Configure(); }
static void Main(string[] args) { System.Console.CancelKeyPress += Console_CancelKeyPress; Console.WriteLine("SqlAuditor: Reading Config..."); var config = AuditConfig.Load("Config.xml"); auditor = new SqlAuditor(config); Console.WriteLine("SqlAuditor: Registering Observers..."); auditor.RegisterObserver(new GenericTraceObserverFactory((context) => new ConsoleTrace())); auditor.RegisterObserver(new GenericTraceObserverFactory((context) => new DBLogger())); auditor.Start(); Console.WriteLine("SqlAuditor: Started."); Console.WriteLine("Press CTR+C to exit."); auditor.WaitAll(); }
private void EFAuditConfig(IApplicationBuilder applicationBuilder) { var userIdProvider = applicationBuilder.ApplicationServices .GetRequiredService <IUserIdProvider>(); AuditConfig.Configure(builder => { builder .EnrichWithProperty(nameof(ApplicationHelper.ApplicationName), ApplicationHelper.ApplicationName) .EnrichWithProperty("Host", Environment.MachineName) .WithUserIdProvider(userIdProvider) .IgnoreEntity <OperationLog>() .WithHttpContextInfo(applicationBuilder.ApplicationServices.GetRequiredService <IHttpContextAccessor>()) ; }); }
private AuditConfig GetAuditConfig(DbEntityEntry dbEntry) { if (AuditConfigSetting.AuditInfo == null) { AuditConfigSetting.AuditInfo = new Dictionary <Type, AuditConfig>(); } var entityType = dbEntry.Entity.GetType(); if (!AuditConfigSetting.AuditInfo.ContainsKey(entityType)) { AuditConfig config = new AuditConfig(); var tableAttr = (TableAttribute)dbEntry.Entity.GetType().GetCustomAttributes(typeof(TableAttribute), true).SingleOrDefault(); var tableName = tableAttr != null ? tableAttr.Name : dbEntry.Entity.GetType().Name; var setBase = ((IObjectContextAdapter)this).ObjectContext.ObjectStateManager.GetObjectStateEntry(dbEntry.Entity).EntitySet; var keyNames = setBase.ElementType.KeyMembers.Select(k => k.Name).ToList(); config.TableName = tableName; config.KeyNames = keyNames; var propInfo = new Dictionary <string, Type>(); var fields = entityType.GetProperties().Select(p => new { p.Name, p.PropertyType }).ToList(); foreach (var propLoopVariable in fields) { var prop = propLoopVariable; if (AuditConfigSetting.IgnoreColumns.Contains(prop.Name)) { continue; } if (keyNames.Contains(prop.Name)) { continue; } propInfo.Add(prop.Name, prop.PropertyType); } config.Properties = propInfo; AuditConfigSetting.AuditInfo.Add(entityType, config); } return(AuditConfigSetting.AuditInfo[entityType]); }
private static void WalkQuincenalDays(DateTime startDay, DateTime finishDay, AuditConfig config) { for (var day = finishDay; day >= startDay; day = day.AddDays(-1)) { if (IsValidDay(day, config.int_Period) && day >= DateTime.Now) { var usersInAudit = db.UsersAudits.Include(x => x.User).Where(x => x.AuditConfig.int_IdAuditConfig == config.int_IdAuditConfig).ToList(); foreach (var asotation in usersInAudit) { AddEvent(day, asotation.User, config); } break; } } }
private static async Task AddOnceEvents(AuditConfig config) { try { var usersInAudit = db.UsersAudits.Include(x => x.User).Where(x => x.AuditConfig.int_IdAuditConfig == config.int_IdAuditConfig).ToList(); var today = DateTime.Now; foreach (var asotation in usersInAudit) { AddEvent(new DateTime(today.Year, today.Month, 1).AddMonths(1).AddDays(-1), asotation.User, config, 3); } await db.SaveChangesAsync(); } catch (Exception) { throw; } }
/// <summary> /// Añade eventos a la base de datos quincenalmente /// </summary> /// <param name="config"></param> /// <returns></returns> private static async Task AddQuincEvents(AuditConfig config) { try { var today = (config.dte_LastDateCreated < DateTime.Now) ? DateTime.Now : config.dte_LastDateCreated; var firstDayOfCurrentQuinc = new DateTime(today.Year, today.Month, 1); for (var month = firstDayOfCurrentQuinc; month <= firstDayOfCurrentQuinc.AddMonths(3); month = month.AddMonths(1)) { WalkQuincenalDays(new DateTime(month.Year, month.Month, 1), new DateTime(month.Year, month.Month, 16), config); WalkQuincenalDays(new DateTime(month.Year, month.Month, 1), new DateTime(month.Year, month.Month, 1).AddMonths(1).AddDays(-1), config); await db.SaveChangesAsync(); } } catch (Exception) { throw; } }
private static void AutoAuditTest() { // 审计配置 AuditConfig.Configure(builder => { builder // 配置操作用户获取方式 .WithUserIdProvider(EnvironmentAuditUserIdProvider.Instance.Value) //.WithUnModifiedProperty() // 保存未修改的属性,默认只保存发生修改的属性 // 保存更多属性 .EnrichWithProperty("MachineName", Environment.MachineName) .EnrichWithProperty(nameof(ApplicationHelper.ApplicationName), ApplicationHelper.ApplicationName) // 保存到自定义的存储 .WithStore <AuditFileStore>() .WithStore <AuditFileStore>("logs0.log") // 忽略指定实体 .IgnoreEntity <AuditRecord>() // 忽略指定实体的某个属性 .IgnoreProperty <TestEntity>(t => t.CreatedAt) // 忽略所有属性名称为 CreatedAt 的属性 .IgnoreProperty("CreatedAt") ; }); DependencyResolver.TryInvokeService <TestDbContext>(dbContext => { dbContext.Database.EnsureDeleted(); dbContext.Database.EnsureCreated(); var testEntity = new TestEntity() { Extra = new { Name = "Tom" }.ToJson(), CreatedAt = DateTimeOffset.UtcNow, }; dbContext.TestEntities.Add(testEntity); dbContext.SaveChanges(); testEntity.CreatedAt = DateTimeOffset.Now; testEntity.Extra = new { Name = "Jerry" }.ToJson(); dbContext.SaveChanges(); dbContext.Remove(testEntity); dbContext.SaveChanges(); var testEntity1 = new TestEntity() { Extra = new { Name = "Tom1" }.ToJson(), CreatedAt = DateTimeOffset.UtcNow, }; dbContext.TestEntities.Add(testEntity1); var testEntity2 = new TestEntity() { Extra = new { Name = "Tom2" }.ToJson(), CreatedAt = DateTimeOffset.UtcNow, }; dbContext.TestEntities.Add(testEntity2); dbContext.SaveChanges(); }); DependencyResolver.TryInvokeService <TestDbContext>(dbContext => { dbContext.Remove(new TestEntity() { Id = 2 }); dbContext.SaveChanges(); }); // disable audit AuditConfig.DisableAudit(); // enable audit // AuditConfig.EnableAudit(); }
public static async Task Run( [TimerTrigger("0 0 */4 * * *", RunOnStartup = false)] TimerInfo timer, [Table("AuditConfig")] CloudTable configTbl, [Table("AuditStats")] CloudTable statsTbl, [Table("ResourceTypes")] CloudTable resourceTypesTbl, [Queue("resources-to-tag")] ICollector <string> outQueue, TraceWriter log) { _log = log; _resourceTypesTbl = resourceTypesTbl; log.Info("Starding subscription audit."); var resourceTypesQuery = await resourceTypesTbl.ExecuteQuerySegmentedAsync(new TableQuery <ResourceType>(), null); _resourceTypes = resourceTypesQuery.Results; var auditConfigQuery = await configTbl.ExecuteQuerySegmentedAsync(new TableQuery <AuditConfig>(), null); // Init config table if new deployment if (auditConfigQuery.Results.Count == 0) { AuditConfig initConfig = new AuditConfig { SubscriptionId = "enter_valid_subscription_id", RowKey = Guid.NewGuid().ToString(), RequiredTags = "comma,separated,tag,list,here", PartitionKey = "init" }; TableOperation insertOperation = TableOperation.InsertOrReplace(initConfig); await configTbl.ExecuteAsync(insertOperation); log.Info("First run for new deployment. Please populate the AuditConfig table."); return; } foreach (var auditConfig in auditConfigQuery.Results) { try { AuditStats stats = new AuditStats { JobStart = DateTime.Now, PartitionKey = auditConfig.SubscriptionId, RowKey = Guid.NewGuid().ToString() }; IEnumerable <string> requiredTagsList = auditConfig.RequiredTags.Split(','); try { string token = AuthenticationService.GetAccessTokenAsync(); _resourceManager = new ResourceManagerService(token); } catch (Exception ex) { log.Error("Unable to connect to the ARM API, Message: " + ex.Message); } List <ResourceItem> tagUpdates = await ProcessResourceGroups(requiredTagsList, auditConfig.SubscriptionId, stats); foreach (ResourceItem resourceItem in tagUpdates) { string messageText = JsonConvert.SerializeObject(resourceItem); _log.Info("Requesting tags for: " + resourceItem.Id); outQueue.Add(messageText); } log.Info("Completed audit of subscription: " + auditConfig.SubscriptionId); stats.JobEnd = DateTime.Now; TableOperation insertOperation = TableOperation.InsertOrReplace(stats); await statsTbl.ExecuteAsync(insertOperation); } catch (Exception ex) { log.Error("Failure processing resource groups for auditConfig: " + auditConfig.RowKey); log.Error(ex.Message); } } }
public T GetConfiguration <T>() where T : class, new() { if (typeof(T) == typeof(UnicastBusConfig)) { Debug.WriteLine("Getting UnicastBusConfig"); var config = new UnicastBusConfig(); config.MessageEndpointMappings.Add(new MessageEndpointMapping { AssemblyName = "NSBUnityError.Commands", Namespace = "NSBUnityError.Commands", Endpoint = "NSBUnityError.Host" }); return(config as T); } if (typeof(T) == typeof(TransportConfig)) { Debug.WriteLine("Getting TransportConfig"); var config = new TransportConfig { MaximumConcurrencyLevel = 1, MaxRetries = 3 }; return(config as T); } if (typeof(T) == typeof(MessageForwardingInCaseOfFaultConfig)) { Debug.WriteLine("Getting MessageForwardingInCaseOfFaultConfig"); var config = new MessageForwardingInCaseOfFaultConfig { ErrorQueue = "error" }; return(config as T); } if (typeof(T) == typeof(SecondLevelRetriesConfig)) { Debug.WriteLine("Getting SecondLevelRetriesConfig"); var config = new SecondLevelRetriesConfig { Enabled = true, NumberOfRetries = 3, TimeIncrease = TimeSpan.FromSeconds(10) }; return(config as T); } if (typeof(T) == typeof(AuditConfig)) { Debug.WriteLine("Getting AuditConfig"); var config = new AuditConfig { QueueName = "audit" }; return(config as T); } if (typeof(T) == typeof(AzureServiceBusQueueConfig)) { Debug.WriteLine("Getting AzureServiceBusQueueConfig"); var config = new AzureServiceBusQueueConfig { ConnectionString = _serviceBusConnectionString }; return(config as T); } return(null); }
public static async Task Run( [TimerTrigger("0 0 */2 * * *")] TimerInfo myTimer, [Table("AuditConfig")] CloudTable configTbl, [Table("AuditStats")] CloudTable statsTbl, [Table("InvalidTagResources")] CloudTable invalidTypesTbl, [Queue("resources-to-tag")] ICollector <string> outQueue, TraceWriter log) { _log = log; _outQueue = outQueue; log.Info("Starding subscription audit."); var invalidTagResourcesQuery = await invalidTypesTbl.ExecuteQuerySegmentedAsync(new TableQuery <InvalidTagResource>(), null); var auditConfigQuery = await configTbl.ExecuteQuerySegmentedAsync(new TableQuery <AuditConfig>(), null); TokenCredentials tokenCredential; if (Environment.GetEnvironmentVariable("MSI_ENDPOINT") == null) { log.Info("Using service principal"); string appId = Environment.GetEnvironmentVariable("appId"); string appSecret = Environment.GetEnvironmentVariable("appSecret"); string tenantId = Environment.GetEnvironmentVariable("tenantId"); tokenCredential = AuthenticationService.GetAccessToken(appId, appSecret, tenantId); } else { log.Info("Using MSI"); var azureServiceTokenProvider = new AzureServiceTokenProvider(); string token = await azureServiceTokenProvider.GetAccessTokenAsync("https://management.core.windows.net/"); tokenCredential = new TokenCredentials(token); } try { _client = new ResourceManagementClient(tokenCredential); } catch (Exception ex) { log.Error("Unable to connect to the ARM API, Message: " + ex.Message); } // Init config table if new deployment if (auditConfigQuery.Results.Count == 0) { AuditConfig initConfig = new AuditConfig { SubscriptionId = "enter_valid_subscription_id", RowKey = Guid.NewGuid().ToString(), RequiredTags = "comma,separated,tag,list,here", PartitionKey = "init" }; TableOperation insertOperation = TableOperation.InsertOrReplace(initConfig); await configTbl.ExecuteAsync(insertOperation); log.Info("First run for new deployment. Please populate the AuditConfig table."); return; } foreach (var auditConfig in auditConfigQuery.Results) { try { AuditStats stats = new AuditStats { JobStart = DateTime.Now, PartitionKey = auditConfig.SubscriptionId, RowKey = Guid.NewGuid().ToString() }; IEnumerable <string> requiredTagsList = auditConfig.RequiredTags.Split(','); _client.SubscriptionId = auditConfig.SubscriptionId; IEnumerable <ResourceGroupInner> resourceGroups = await _client.ResourceGroups.ListAsync(); stats.ResourceGroupsTotal = resourceGroups.Count(); await ProcessResourceGroups(requiredTagsList, resourceGroups, invalidTagResourcesQuery.Results, auditConfig.SubscriptionId, stats); log.Info("Completed audit of subscription: " + auditConfig.SubscriptionId); stats.JobEnd = DateTime.Now; TableOperation insertOperation = TableOperation.InsertOrReplace(stats); await statsTbl.ExecuteAsync(insertOperation); } catch (Exception ex) { log.Error("Failure processing resource groups for auditConfig: " + auditConfig.RowKey); log.Error(ex.Message); } } }
private static void ModifyConfigLastDate(AuditConfig config, int daysAdded) { config.dte_LastDateCreated = DateTime.Now.AddDays(daysAdded); db.Entry(config).State = EntityState.Modified; db.SaveChanges(); }
public SqlAuditor(AuditConfig config) { this.config = config; observerFactories = new List <ITraceObserverFactory>(); auditors = new List <SqlInstanceAuditor>(); }
private List <AuditLog> GetAuditRecordsForChange(DbEntityEntry dbEntry, string userName) { List <AuditLog> logs = new List <AuditLog>(); DateTime eventTime = DateTime.Now; AuditConfig entityConfig = GetAuditConfig(dbEntry); var log = new AuditLog { UserName = userName, EventDate = eventTime, TableName = entityConfig.TableName, Entity = dbEntry }; foreach (var prop in entityConfig.Properties) { log.ColumnName = prop.Key; if (dbEntry.State == EntityState.Deleted) { if (!dbEntry.OriginalValues.PropertyNames.Contains(prop.Key)) { continue; } if (dbEntry.OriginalValues.GetValue <object>(prop.Key) == null) { continue; } logs.Add(new AuditLog { UserName = userName, EventDate = eventTime, EventType = (int)AuditLog.LogType.Deleted, ColumnName = prop.Key, TableName = entityConfig.TableName, OriginalValue = dbEntry.OriginalValues.GetValue <object>(prop.Key).ToString(), Entity = dbEntry, RecordId = dbEntry.OriginalValues.GetValue <object>(entityConfig.KeyNames[0]).ToString() }); continue; } if (!dbEntry.CurrentValues.PropertyNames.Contains(prop.Key)) { continue; } var propValue = dbEntry.CurrentValues.GetValue <object>(prop.Key); if (dbEntry.State == EntityState.Added) { if (propValue == null) { continue; } logs.Add(AddLog(AuditLog.LogType.Added, log)); } if (dbEntry.State != EntityState.Modified) { continue; } var originalValue = dbEntry.OriginalValues.GetValue <object>(prop.Key); if (Equals(originalValue, propValue)) { continue; } if (ReferenceEquals(prop.Value, typeof(decimal?)) || ReferenceEquals(prop.Value, typeof(decimal))) { if (originalValue != null && propValue != null && string.Format("{0:0.00}", Math.Truncate((decimal)originalValue * 100) / 100) == string.Format("{0:0.00}", Math.Truncate((decimal)propValue * 100) / 100)) { continue; } } else if (originalValue != null && propValue != null && originalValue.ToString().Trim() == propValue.ToString().Trim()) { continue; } logs.Add(AddLog(AuditLog.LogType.Modified, log)); } return(logs); }