mirror of https://github.com/MISP/misp-dashboard
Manage map from classes + Added more event info in zmq feed
parent
7ddd9bb092
commit
89fd7268db
|
@ -105,7 +105,7 @@ def event_stream_log():
|
||||||
def event_stream_maps():
|
def event_stream_maps():
|
||||||
for msg in subscriber_map.listen():
|
for msg in subscriber_map.listen():
|
||||||
content = msg['data'].decode('utf8')
|
content = msg['data'].decode('utf8')
|
||||||
print('sending map', content)
|
print(content)
|
||||||
yield 'data: {}\n\n'.format(content)
|
yield 'data: {}\n\n'.format(content)
|
||||||
|
|
||||||
if __name__ == '__main__':
|
if __name__ == '__main__':
|
||||||
|
|
|
@ -1,24 +1,117 @@
|
||||||
var maxNumCoord = 100;
|
const MAXNUMCOORD = 100;
|
||||||
var max_img_rotation = 10;
|
const MAXIMGROTATION = 10;
|
||||||
var rotation_time = 1000*10; //10s
|
const ROTATIONWAITTIME = 1000*10; //10s
|
||||||
|
|
||||||
var mymap = L.map('feedDivMap1').setView([51.505, -0.09], 13);;
|
const OSMURL='http://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png';
|
||||||
var osmUrl='http://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png';
|
const OSMATTRIB='Map data © <a href="http://openstreetmap.org">OpenStreetMap</a> contributors';
|
||||||
var osmAttrib='Map data © <a href="http://openstreetmap.org">OpenStreetMap</a> contributors';
|
|
||||||
var osm = new L.TileLayer(osmUrl, {minZoom: 3, maxZoom: 17, attribution: osmAttrib}).addTo(mymap);
|
|
||||||
|
|
||||||
var coord_to_change = 0;
|
var myOpenStreetMap = L.map('feedDivMap1').setView([0, 0], 1);
|
||||||
var coord_array = [];
|
var osm = new L.TileLayer(OSMURL, {minZoom: 0, maxZoom: 17, attribution: OSMATTRIB}).addTo(myOpenStreetMap);
|
||||||
var first_map = true;
|
|
||||||
var map_lat, map_lon; //current lat and lon shown in openStreetMap pannel
|
|
||||||
|
|
||||||
/* MAP */
|
class MapEvent {
|
||||||
var mapObj;
|
constructor(json, marker) {
|
||||||
var curNumMarker = 0;
|
this.coord = json.coord;
|
||||||
var allMarker = [];
|
this.marker = marker;
|
||||||
|
this.categ = json.categ;
|
||||||
|
this.value = json.value;
|
||||||
|
this.text = this.categ + ": " + this.value;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
function marker_animation(x, y, curNumMarker) {
|
class MapEventManager {
|
||||||
var markerColor = mapObj.markers[curNumMarker].element.config.style.current.fill;
|
constructor() {
|
||||||
|
this._mapEventArray = [];
|
||||||
|
this._nextEventToShow = 0;
|
||||||
|
this._first_map = true;
|
||||||
|
this._coordSet = new Set();
|
||||||
|
//current lat and lon shown in worldMap
|
||||||
|
this._latToPing;
|
||||||
|
this._lonToPing;
|
||||||
|
//Markers on the worldMap
|
||||||
|
this._allMarkers = [];
|
||||||
|
this._curMarkerNum = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
addMapEvent(mapevent) {
|
||||||
|
if(this._mapEventArray.length >= MAXIMGROTATION) {
|
||||||
|
var toDel = this._mapEventArray[0];
|
||||||
|
toDel._marker.remove(); // remove marker
|
||||||
|
this._coordSet.delete(toDel.text);
|
||||||
|
this._mapEventArray.slice(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
if(!this._coordSet.has(mapevent.text)) { // avoid duplicate map
|
||||||
|
this._mapEventArray.push(mapevent);
|
||||||
|
this._coordSet.add(mapevent.text);
|
||||||
|
this.popupCoord(mapevent.coord);
|
||||||
|
} else {
|
||||||
|
console.log('Duplicate coordinates');
|
||||||
|
}
|
||||||
|
|
||||||
|
if(this._first_map) { // remove no_map pic
|
||||||
|
this.rotateMap();
|
||||||
|
this.ping();
|
||||||
|
this._first_map = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
getNumberOfEvent() {
|
||||||
|
return this._mapEventArray.length
|
||||||
|
}
|
||||||
|
|
||||||
|
getNextEventToShow() {
|
||||||
|
var toShow = this._mapEventArray[this._nextEventToShow];
|
||||||
|
this._nextEventToShow = this._nextEventToShow == this._mapEventArray.length-1 ? 0 : this._nextEventToShow+1;
|
||||||
|
return toShow;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Perform the roration of the map in the openStreetMap pannel
|
||||||
|
rotateMap() {
|
||||||
|
var mapEvent = this.getNextEventToShow();
|
||||||
|
this._latToPing = mapEvent.coord.lat;
|
||||||
|
this._lonToPing = mapEvent.coord.lon;
|
||||||
|
var marker = mapEvent.marker;
|
||||||
|
myOpenStreetMap.flyTo([mapEvent.coord.lat, mapEvent.coord.lon], 17);
|
||||||
|
|
||||||
|
$("#textMap1").fadeOut(400, function(){ $(this).text(mapEvent.text); }).fadeIn(400);
|
||||||
|
setTimeout(function(){ mapEventManager.rotateMap(); }, ROTATIONWAITTIME);
|
||||||
|
}
|
||||||
|
|
||||||
|
ping() {
|
||||||
|
var pnts = openStreetMapObj.latLngToPoint(this._latToPing, this._lonToPing);
|
||||||
|
if (pnts != false) { //sometimes latLngToPoint return false
|
||||||
|
$("#feedDiv2").append(
|
||||||
|
$('<div class="marker_animation"></div>')
|
||||||
|
.css({'left': pnts.x-15 + 'px'}) /* HACK to center the effect */
|
||||||
|
.css({'top': pnts.y-15 + 'px'})
|
||||||
|
.css({ 'background-color': 'orange' })
|
||||||
|
.animate({ opacity: 0, scale: 1, height: '80px', width:'80px', margin: '-25px' }, 400, 'linear', function(){$(this).remove(); })
|
||||||
|
);
|
||||||
|
}
|
||||||
|
setTimeout(function(){ mapEventManager.ping(); }, ROTATIONWAITTIME/5);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Add and Manage markers on the map + make Animation
|
||||||
|
popupCoord(coord) {
|
||||||
|
var coord = [coord.lat, coord.lon];
|
||||||
|
var value = Math.random()*180;
|
||||||
|
var pnts = openStreetMapObj.latLngToPoint(coord[0], coord[1])
|
||||||
|
if (pnts != false) { //sometimes latLngToPoint return false
|
||||||
|
openStreetMapObj.addMarker(this._curMarkerNum, coord, [value]);
|
||||||
|
this._allMarkers.push(this._curMarkerNum)
|
||||||
|
marker_animation(pnts.x, pnts.y, this._curMarkerNum);
|
||||||
|
this._curMarkerNum = this._curMarkerNum >= MAXNUMCOORD ? 0 : this._curMarkerNum+1;
|
||||||
|
if (this._allMarkers.length >= MAXNUMCOORD) {
|
||||||
|
to_remove = this._allMarkers[0];
|
||||||
|
openStreetMapObj.removeMarkers([to_remove]);
|
||||||
|
this._allMarkers = this._allMarkers.slice(1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function marker_animation(x, y, markerNum) {
|
||||||
|
var markerColor = openStreetMapObj.markers[markerNum].element.config.style.current.fill;
|
||||||
$("#feedDiv2").append(
|
$("#feedDiv2").append(
|
||||||
$('<div class="marker_animation"></div>')
|
$('<div class="marker_animation"></div>')
|
||||||
.css({'left': x-15 + 'px'}) /* HACK to center the effect */
|
.css({'left': x-15 + 'px'}) /* HACK to center the effect */
|
||||||
|
@ -28,56 +121,8 @@ function marker_animation(x, y, curNumMarker) {
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Add makers on the map
|
var mapEventManager = new MapEventManager();
|
||||||
function popupCoord(coord) {
|
var openStreetMapObj;
|
||||||
var coord = [coord['lat'], coord['lon']];
|
|
||||||
var value = Math.random()*180;
|
|
||||||
pnts = mapObj.latLngToPoint(coord[0], coord[1])
|
|
||||||
if (pnts != false) { //sometimes latLngToPoint return false
|
|
||||||
mapObj.addMarker(curNumMarker, coord, [value]);
|
|
||||||
allMarker.push(curNumMarker)
|
|
||||||
marker_animation(pnts.x, pnts.y, curNumMarker);
|
|
||||||
curNumMarker = curNumMarker>=maxNumCoord ? 0 : curNumMarker+1;
|
|
||||||
if (allMarker.length >= maxNumCoord) {
|
|
||||||
to_remove = allMarker[0];
|
|
||||||
mapObj.removeMarkers([to_remove]);
|
|
||||||
allMarker = allMarker.slice(1);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Makes an animation on the marker concerned by the map shown in the openStreetMap pannel
|
|
||||||
function ping() {
|
|
||||||
pnts = mapObj.latLngToPoint(map_lat, map_lon);
|
|
||||||
if (pnts != false) { //sometimes latLngToPoint return false
|
|
||||||
$("#feedDiv2").append(
|
|
||||||
$('<div class="marker_animation"></div>')
|
|
||||||
.css({'left': pnts.x-15 + 'px'}) /* HACK to center the effect */
|
|
||||||
.css({'top': pnts.y-15 + 'px'})
|
|
||||||
.css({ 'background-color': 'orange' })
|
|
||||||
.animate({ opacity: 0, scale: 1, height: '80px', width:'80px', margin: '-25px' }, 400, 'linear', function(){$(this).remove(); })
|
|
||||||
);
|
|
||||||
}
|
|
||||||
setTimeout(function(){ ping(); }, rotation_time/4);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Perform the roration of the map in the openStreetMap pannel
|
|
||||||
function rotate_map() {
|
|
||||||
var to_switch = coord_array[coord_to_change];
|
|
||||||
var coord = to_switch[0];
|
|
||||||
map_lat = coord.lat;
|
|
||||||
map_lon = coord.lon;
|
|
||||||
var marker = to_switch[1];
|
|
||||||
var headerTxt = to_switch[2];
|
|
||||||
mymap.setView([coord.lat, coord.lon], 17);
|
|
||||||
|
|
||||||
$("#textMap1").fadeOut(400, function(){ $(this).text(headerTxt); }).fadeIn(400);
|
|
||||||
coord_to_change = coord_to_change == coord_array.length-1 ? 0 : coord_to_change+1;
|
|
||||||
|
|
||||||
setTimeout(function(){ rotate_map(); }, rotation_time);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
$(function(){
|
$(function(){
|
||||||
$('#feedDiv2').vectorMap({
|
$('#feedDiv2').vectorMap({
|
||||||
|
@ -93,28 +138,17 @@ $(function(){
|
||||||
}],
|
}],
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
mapObj = $("#feedDiv2").vectorMap('get','mapObject');
|
openStreetMapObj = $("#feedDiv2").vectorMap('get','mapObject');
|
||||||
});
|
});
|
||||||
|
|
||||||
// Subscribe to the flask eventStream
|
// Subscribe to the flask eventStream
|
||||||
var source_map = new EventSource(urlForMaps);
|
var source_map = new EventSource(urlForMaps);
|
||||||
source_map.onmessage = function(event) {
|
source_map.onmessage = function(event) {
|
||||||
var json = jQuery.parseJSON( event.data );
|
var json = jQuery.parseJSON( event.data );
|
||||||
popupCoord(json.coord);
|
var marker = L.marker([json.coord.lat, json.coord.lon]).addTo(myOpenStreetMap);
|
||||||
var img2 = linkForDefaultMap.replace(/\/[^\/]+$/, "/"+json.path);
|
var mapEvent = new MapEvent(json, marker);
|
||||||
|
mapEventManager.addMapEvent(mapEvent);
|
||||||
if (coord_array.len >= max_img_rotation) {
|
|
||||||
coord_array[0][1].remove() // remove marker
|
|
||||||
coord_array.slice(1)
|
|
||||||
}
|
|
||||||
var marker = L.marker([json.coord.lat, json.coord.lon]).addTo(mymap);
|
|
||||||
coord_array.push([json.coord, marker, ""+json.coord.lat+", "+json.coord.lon]);
|
|
||||||
|
|
||||||
if (first_map) { // remove no_map pic
|
|
||||||
rotate_map();
|
|
||||||
ping();
|
|
||||||
first_map = false;
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
source_map.onopen = function(){
|
source_map.onopen = function(){
|
||||||
console.log('connection is opened. '+source_map.readyState);
|
console.log('connection is opened. '+source_map.readyState);
|
||||||
|
|
|
@ -99,7 +99,7 @@ small {
|
||||||
<!--<div id="panelbody" class="panel-body" style="height: 37vh; width:100%;">
|
<!--<div id="panelbody" class="panel-body" style="height: 37vh; width:100%;">
|
||||||
<div id="feedDiv1A" style="width:50%; height: calc(100% - 30px); position: relative; float: left;"></div>
|
<div id="feedDiv1A" style="width:50%; height: calc(100% - 30px); position: relative; float: left;"></div>
|
||||||
<div id="feedDiv1B" style="width:50%; height: calc(100% - 30px); position: relative; float: left;"></div>-->
|
<div id="feedDiv1B" style="width:50%; height: calc(100% - 30px); position: relative; float: left;"></div>-->
|
||||||
<div id="textMap1" class="panel-heading bg-info"> No map
|
<div id="textMap1" class="panel-heading bg-info" style="font-weight: bold;"> No map
|
||||||
<i class="fa fa-bar-chart-o fa-fw"></i>
|
<i class="fa fa-bar-chart-o fa-fw"></i>
|
||||||
</div>
|
</div>
|
||||||
<div id="panelbody" class="panel-body" style="height: 93%; padding: 5px">
|
<div id="panelbody" class="panel-body" style="height: 93%; padding: 5px">
|
||||||
|
|
|
@ -88,23 +88,27 @@ def default_attribute(jsonattr):
|
||||||
|
|
||||||
#try to get coord
|
#try to get coord
|
||||||
if jsonattr['category'] == "Network activity":
|
if jsonattr['category'] == "Network activity":
|
||||||
handleCoord(jsonattr['value'])
|
handleCoord(jsonattr['value'], jsonattr['category'])
|
||||||
|
|
||||||
to_send = { 'name': 'Attribute', 'log': json.dumps(to_push) }
|
to_send = { 'name': 'Attribute', 'log': json.dumps(to_push) }
|
||||||
redis_server.publish(channel, json.dumps(to_send))
|
redis_server.publish(channel, json.dumps(to_send))
|
||||||
|
|
||||||
def handleCoord(value):
|
def handleCoord(supposed_ip, categ):
|
||||||
try:
|
try:
|
||||||
coord = ip_to_coord(value)
|
coord = ip_to_coord(supposed_ip)
|
||||||
coord_dic = {'lat': coord['lat'], 'lon': coord['lon']}
|
coord_dic = {'lat': coord['lat'], 'lon': coord['lon']}
|
||||||
coord_list = [coord['lat'], coord['lon']]
|
coord_list = [coord['lat'], coord['lon']]
|
||||||
print(coord_list)
|
print(coord_list)
|
||||||
now = datetime.datetime.now()
|
now = datetime.datetime.now()
|
||||||
today_str = str(now.year)+str(now.month)+str(now.day)
|
today_str = str(now.year)+str(now.month)+str(now.day)
|
||||||
keyname = 'GEO_' + today_str
|
keyname = 'GEO_' + today_str
|
||||||
#serv_coord.zincrby(keyname, coord_list)
|
serv_coord.zincrby(keyname, coord_list)
|
||||||
serv_coord.publish(channel_disp, json.dumps({ "coord": coord }))
|
to_send = {
|
||||||
print('coord sent')
|
"coord": coord,
|
||||||
|
"categ": categ,
|
||||||
|
"value": supposed_ip
|
||||||
|
}
|
||||||
|
serv_coord.publish(channel_disp, json.dumps(to_send))
|
||||||
except ValueError:
|
except ValueError:
|
||||||
print("can't resolve ip")
|
print("can't resolve ip")
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue