/* Enter a unique ExecutionPlan */
@Plan:name('ISAnalytics-ConfigureSuspiciousLoginDetection-ConfigureSuspiciousLoginDetection-realtime1')

/* Enter a unique description for ExecutionPlan */
-- @Plan:description('ExecutionPlan')

/* define streams/tables and write queries here ... */
@Import('org.wso2.is.analytics.stream.OverallAuthentication:1.0.0')
define stream AuthStream (meta_tenantId int, contextId string, eventId string, eventType string, authenticationSuccess bool, username string, localUsername string, userStoreDomain string, tenantDomain string, remoteIp string, region string, inboundAuthType string, serviceProvider string, rememberMeEnabled bool, forceAuthEnabled bool, passiveAuthEnabled bool, rolesCommaSeparated string, authenticationStep string, identityProvider string, authStepSuccess bool, stepAuthenticator string, isFirstLogin bool, identityProviderType string, _timestamp long);

@Export('org.wso2.is.analytics.stream.LoginSuccessAfterMultipleFailures:1.0.0')
define stream LoginAlertStream (meta_tenantId int, username string, severity int, msg string, tenantDomain string, _timestamp long);

@Export('org.wso2.is.analytics.allISAlertsStream:1.0.0')
define stream alert_allISAlertsStream (meta_tenantId int, type string, tenantDomain string, msg string, severity int, alertTimestamp long, userReadableTime string);

/* Query for detecting login attempts with same username*/
@info(name = 'detectEventsForSameUser')
from every(e1=AuthStream) -> e2=AuthStream[authStepSuccess == false AND e1.username == e2.username AND e1.userStoreDomain == e2.userStoreDomain AND e1.tenantDomain == e2.tenantDomain]<5:> ->  e3=AuthStream[authStepSuccess == true AND e2.username == e3.username AND e2.userStoreDomain == e3.userStoreDomain AND e2.tenantDomain == e3.tenantDomain]
within 1 min
select e2[last].meta_tenantId, e2[last].username, 1 as severity, str:concat('Successful login attempt after multiple login failures with same username detected at: ', time:dateFormat(e3[last]._timestamp,'yyyy-MM-dd HH:mm:ss'), '.') as msg, e2[last].tenantDomain, e3[last]._timestamp, e2[last].serviceProvider
output first every 1 min
insert into LoginAlertStreamSameUsername;

@info(name = 'sendingSameUserEventsToLoginAlertStream')
from LoginAlertStreamSameUsername
select meta_tenantId, username, severity, msg, tenantDomain, _timestamp
insert into LoginAlertStream;

@info(name = 'sendingSameUserEventsToAllISAlertsStream')
from LoginAlertStreamSameUsername
select meta_tenantId, "SuspiciousLoginAlert" as type, tenantDomain, str:concat('Successful login attempt after multiple login failures from same username: ', username, ' detected at: ', time:dateFormat(e3[last]._timestamp,'yyyy-MM-dd HH:mm:ss'), '.') as msg, severity, (time:timestampInMilliseconds()) as alertTimestamp, time:dateFormat((time:timestampInMilliseconds()),'yyyy-MM-dd HH:mm:ss') as userReadableTime
insert into alert_allISAlertsStream;