private void OnNewIncident(IIncidentLog log) { if(NewIncident != null) NewIncident(this, new IncidentEventArgs(log)); var triggers = MatchTriggers(log.Type, log.SubType); foreach(var tr in triggers) { tr.OnNewIncident(log); } }
private void OnNewIncident(IIncidentLog log) { if (NewIncident != null) { NewIncident(this, new IncidentEventArgs(log)); } var triggers = MatchTriggers(log.Type, log.SubType); foreach (var tr in triggers) { tr.OnNewIncident(log); } }
public override void OnNewIncident(IIncidentLog newEntry) { //if login failed with user name that matches a login in database, we log this loginId in KeyId1 var failedUserName = newEntry.Key1; if(string.IsNullOrWhiteSpace(failedUserName)) return; var tenantId = newEntry.KeyId2; var utcNow = _app.TimeService.UtcNow; var session = _app.OpenSystemSession(); var fromDate = utcNow.Subtract(Settings.TimeWindow); var strLoginFailed = LoginEventType.LoginFailed.ToString(); var qryRecentFailures = from lg in session.EntitySet<IIncidentLog>() where lg.CreatedOn >= fromDate && lg.Key1 == failedUserName && lg.Type == LoginModule.LoginIncidentType && lg.SubType == strLoginFailed select lg; //Note: currently LINQ translator does not handle correctly comparing nullable values, so adding this separately if(tenantId != null) qryRecentFailures = qryRecentFailures.Where(lg => lg.KeyId2 == tenantId.Value); var failCount = qryRecentFailures.Count(); if(failCount < Settings.FailureCount) return; //not yet // We have repeated login failures in short period of time; this might be an attack - suspend account(s) for several minutes // find Login(s) - might be more than one - we may have the same username for different tenants var loginSet = session.EntitySet<ILogin>(); var loginQuery = from lg in loginSet where lg.UserName == failedUserName select lg; if(tenantId != null) loginQuery = loginQuery.Where(lg => lg.TenantId == tenantId.Value); var logins = loginQuery.ToList(); if(logins.Count == 0) return; //it might happen if user name is not known //Suspend login var suspendedUntil = utcNow.Add(Settings.SuspensionPeriod); var loginLogService = _app.GetService<ILoginLogService>(); var msg = StringHelper.SafeFormat("{0} login failures. Login {1} suspended until {2}", failCount, failedUserName, suspendedUntil); var loginModule = _app.GetModule<LoginModule>(); foreach(var lg in logins) { // if already suspended or disabled, do not suspend again if(lg.Flags.IsSet(LoginFlags.Disabled | LoginFlags.Suspended)) continue; lg.Flags |= LoginFlags.Suspended; lg.SuspendedUntil = suspendedUntil; //raise event - it will log to login log loginModule.OnLoginEvent(session.Context, LoginEventType.LoginSuspended, lg, msg, failedUserName); } session.SaveChanges(); var incService = _app.GetService<IIncidentLogService>(); incService.LogIncident(LoginModule.LoginIncidentType, msg, LoginEventType.LoginSuspended.ToString(), key1: failedUserName, keyId2: tenantId); }
public static IncidentData ToModel(this IIncidentLog log, bool withDetails = false) { if (log == null) { return(null); } var data = new IncidentData() { Type = log.Type, SubType = log.SubType, Message = log.Message, Key1 = log.Key1, Key2 = log.Key2, KeyId1 = log.KeyId1, KeyId2 = log.KeyId2, LongKey3 = log.LongKey3, LongKey4 = log.LongKey4 }; data.AssignCommon(log); if (withDetails) { data.Notes = log.Notes; } return(data); }
public virtual void OnNewIncident(IIncidentLog newEntry) { }
public override void OnNewIncident(IIncidentLog newEntry) { //if login failed with user name that matches a login in database, we log this loginId in KeyId1 var failedUserName = newEntry.Key1; if (string.IsNullOrWhiteSpace(failedUserName)) { return; } var tenantId = newEntry.KeyId2; var utcNow = _app.TimeService.UtcNow; var session = _app.OpenSystemSession(); var fromDate = utcNow.Subtract(Settings.TimeWindow); var strLoginFailed = LoginEventType.LoginFailed.ToString(); var qryRecentFailures = from lg in session.EntitySet <IIncidentLog>() where lg.CreatedOn >= fromDate && lg.Key1 == failedUserName && lg.Type == LoginModule.LoginIncidentType && lg.SubType == strLoginFailed select lg; //Note: currently LINQ translator does not handle correctly comparing nullable values, so adding this separately if (tenantId != null) { qryRecentFailures = qryRecentFailures.Where(lg => lg.KeyId2 == tenantId.Value); } var failCount = qryRecentFailures.Count(); if (failCount < Settings.FailureCount) { return; //not yet } // We have repeated login failures in short period of time; this might be an attack - suspend account(s) for several minutes // find Login(s) - might be more than one - we may have the same username for different tenants var loginSet = session.EntitySet <ILogin>(); var loginQuery = from lg in loginSet where lg.UserName == failedUserName select lg; if (tenantId != null) { loginQuery = loginQuery.Where(lg => lg.TenantId == tenantId.Value); } var logins = loginQuery.ToList(); if (logins.Count == 0) { return; //it might happen if user name is not known } //Suspend login var suspendedUntil = utcNow.Add(Settings.SuspensionPeriod); var loginLogService = _app.GetService <ILoginLogService>(); var msg = StringHelper.SafeFormat("{0} login failures. Login {1} suspended until {2}", failCount, failedUserName, suspendedUntil); var loginModule = _app.GetModule <LoginModule>(); foreach (var lg in logins) { // if already suspended or disabled, do not suspend again if (lg.Flags.IsSet(LoginFlags.Disabled | LoginFlags.Suspended)) { continue; } lg.Flags |= LoginFlags.Suspended; lg.SuspendedUntil = suspendedUntil; //raise event - it will log to login log loginModule.OnLoginEvent(session.Context, LoginEventType.LoginSuspended, lg, msg, failedUserName); } session.SaveChanges(); var incService = _app.GetService <IIncidentLogService>(); incService.LogIncident(LoginModule.LoginIncidentType, msg, LoginEventType.LoginSuspended.ToString(), key1: failedUserName, keyId2: tenantId); }
public IncidentEventArgs(IIncidentLog incident) { Incident = incident; }