Skip to content

Instantly share code, notes, and snippets.

@Enteee
Last active August 5, 2019 22:26
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save Enteee/2679f6e7130946db9c54caff0d5eb294 to your computer and use it in GitHub Desktop.
Save Enteee/2679f6e7130946db9c54caff0d5eb294 to your computer and use it in GitHub Desktop.
FluentFlow Example: If you see within 2 seconds two invalid login attemps followed by a successful login from the same source, then alert.
const ff = require('fluentflow')
const $ = ff.RuleBuilder;
const _ = require('lodash');
const moment = require('moment')
/**
* Not interesting if older than 2 seconds
*/
function isInteresting(c, pc){
return moment.duration(
moment(c.moment).diff(
moment(pc.get('moment'))
)
).seconds() < 2;
}
/**
* If you see within 2 seconds two invalid login attemps followed by a successful login from the same source, then alert.
*/
const ffm = ff.Matcher(
$(
// not successful login
(o, p, c, pc, match) => {
c.moment = moment().format();
return match(!o.get('success'))
}
).followedBy(
// not successful login
(o, p, c, pc, match, forget) => {
c.moment = moment().format();
if (!isInteresting(c, pc)){
console.log('Forget', p.toJS());
return forget();
}
return match(
o.get('source') == p.get(0).get('source') && !o.get('success')
);
}
).followedBy(
// successful login
(o, p, c, pc, match, forget) => {
c.moment = moment().format();
if (!isInteresting(c, pc)){
console.log('Forget', p.toJS());
return forget();
}
return match(
o.get('source') == p.get(0).get('source') && o.get('success')
);
}
).then(
(objs, next) => next(console.log('ALERT!', objs.toJS()))
)
);
// generate and match new random events
id = 0;
setInterval(
() => {
const loginEvent = {
id: id++,
source: _.sample([
'User1', 'User2', 'User3'
]),
success: _.sample([true, false])
};
console.log('Event', loginEvent)
ffm(loginEvent)
},
100
)
$ node events.js
Event { id: 0, source: 'User2', success: false }
Event { id: 1, source: 'User3', success: false }
Event { id: 2, source: 'User1', success: false }
Event { id: 3, source: 'User1', success: true }
Event { id: 4, source: 'User2', success: true }
Event { id: 5, source: 'User2', success: true }
Event { id: 6, source: 'User1', success: false }
Event { id: 7, source: 'User2', success: true }
Event { id: 8, source: 'User2', success: true }
Event { id: 9, source: 'User2', success: true }
Event { id: 10, source: 'User3', success: true }
Event { id: 11, source: 'User2', success: false }
Event { id: 12, source: 'User2', success: true }
ALERT! [ { id: 12, source: 'User2', success: true },
{ id: 11, source: 'User2', success: false },
{ id: 0, source: 'User2', success: false } ]
Event { id: 13, source: 'User2', success: true }
ALERT! [ { id: 13, source: 'User2', success: true },
{ id: 11, source: 'User2', success: false },
{ id: 0, source: 'User2', success: false } ]
Event { id: 14, source: 'User1', success: true }
ALERT! [ { id: 14, source: 'User1', success: true },
{ id: 6, source: 'User1', success: false },
{ id: 2, source: 'User1', success: false } ]
Event { id: 15, source: 'User1', success: false }
Event { id: 16, source: 'User2', success: true }
ALERT! [ { id: 16, source: 'User2', success: true },
{ id: 11, source: 'User2', success: false },
{ id: 0, source: 'User2', success: false } ]
Event { id: 17, source: 'User2', success: false }
Forget [ { id: 0, source: 'User2', success: false } ]
Forget [ { id: 1, source: 'User3', success: false } ]
Forget [ { id: 2, source: 'User1', success: false } ]
Forget [ { id: 6, source: 'User1', success: false } ]
Forget [ { id: 6, source: 'User1', success: false },
{ id: 2, source: 'User1', success: false } ]
Event { id: 18, source: 'User2', success: false }
Event { id: 19, source: 'User1', success: false }
Event { id: 20, source: 'User1', success: false }
Event { id: 21, source: 'User2', success: false }
Event { id: 22, source: 'User1', success: true }
Event { id: 23, source: 'User1', success: false }
Event { id: 24, source: 'User3', success: false }
Event { id: 25, source: 'User2', success: true }
Event { id: 26, source: 'User2', success: false }
Event { id: 27, source: 'User2', success: true }
Event { id: 28, source: 'User1', success: true }
Event { id: 29, source: 'User3', success: true }
Event { id: 30, source: 'User3', success: false }
Event { id: 31, source: 'User3', success: true }
Event { id: 32, source: 'User2', success: true }
Event { id: 33, source: 'User2', success: true }
Event { id: 34, source: 'User1', success: true }
Event { id: 35, source: 'User1', success: true }
Event { id: 36, source: 'User1', success: true }
Event { id: 37, source: 'User3', success: true }
^C
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment