def onAggregation(self, agg): username = agg['value'] events = agg['events'] cfg = agg['config'] query = locality.wrap_query(self.es) journal = locality.wrap_journal(self.es) locs_from_evts = list( filter(lambda state: state is not None, map(locality.from_event, events))) entry_from_es = locality.find(query, username, cfg.localities.es_index) new_state = locality.State('locality', username, locs_from_evts) if entry_from_es is None: entry_from_es = locality.Entry( '', locality.State('locality', username, [])) cleaned = locality.remove_outdated(entry_from_es.state, cfg.localities.valid_duration_days) # Determine if we should trigger an alert before updating the state. new_alert = alert.alert(cleaned.state.username, new_state.localities, cleaned.state.localities) updated = locality.update(cleaned.state, new_state) if updated.did_update: entry_from_es = locality.Entry(entry_from_es.identifier, updated.state) journal(entry_from_es, cfg.localities.es_index) if new_alert is not None: summary = '{} seen in {},{}'.format( username, new_alert.hops[0].origin.city, new_alert.hops[0].origin.country) for hop in new_alert.hops: summary += ' then {},{}'.format(hop.destination.city, hop.destination.country) alert_dict = self.createAlertDict(summary, 'geomodel', ['geomodel'], events, 'INFO') # TODO: When we update to Python 3.7+, change to asdict(alert_produced) alert_dict['details'] = { 'username': new_alert.username, 'hops': [dict(hop._asdict()) for hop in new_alert.hops] } return alert_dict return None
def onAggregation(self, agg): username = agg['value'] events = agg['events'] cfg = agg['config'] query = locality.wrap_query(self.es) journal = locality.wrap_journal(self.es) def _utctimestamp(event): source = event.get('_source', {}) utctimestamp = source.get('utctimestamp', datetime.utcnow()) return toUTC(utctimestamp) sorted_events = sorted(events, key=_utctimestamp, reverse=True) locs_from_evts = list( filter(lambda state: state is not None, map(locality.from_event, sorted_events))) entry_from_es = locality.find(query, username, cfg.localities.es_index) new_state = locality.State.new(username, locs_from_evts) if entry_from_es is None: entry_from_es = locality.Entry.new(locality.State.new( username, [])) cleaned = locality.remove_outdated(entry_from_es.state, cfg.localities.valid_duration_days) # Determine if we should trigger an alert before updating the state. new_alert = alert.alert(cleaned.state.username, new_state.localities, cleaned.state.localities) updated = locality.update(cleaned.state, new_state) if updated.did_update: entry_from_es = locality.Entry(entry_from_es.identifier, updated.state) journal(entry_from_es, cfg.localities.es_index) if new_alert is not None: modded_alert = factors.pipe(new_alert, self.factor_pipeline) summary = alert.summary(modded_alert) alert_dict = self.createAlertDict(summary, 'geomodel', ['geomodel'], events, modded_alert.severity.value) # The IP that the user is acting from is the one they hopped to. # TODO: When we update to Python 3.7+, change to asdict(alert_produced) alert_dict['details'] = { 'username': modded_alert.username, 'hops': [hop.to_json() for hop in new_alert.hops], 'sourceipaddress': new_alert.hops[-1].destination.ip, 'sourceipv4address': new_alert.hops[-1].destination.ip, 'factors': modded_alert.factors } return alert_dict return None