mirror of https://github.com/MISP/misp-dashboard
				
				
				
			Updated ranking level decision + updated support of message for zmq + Updated badge acquisition display to match data in DB
							parent
							
								
									1550f25b30
								
							
						
					
					
						commit
						a3c853e490
					
				| 
						 | 
				
			
			@ -91,17 +91,18 @@ class Contributor_helper:
 | 
			
		|||
            else:
 | 
			
		||||
                requirement_fulfilled.append(i)
 | 
			
		||||
                final_rank += 1
 | 
			
		||||
        num_of_previous_req_not_fulfilled = len([x for x in requirement_not_fulfilled if x<final_rank])
 | 
			
		||||
        final_rank = final_rank -  num_of_previous_req_not_fulfilled
 | 
			
		||||
        #num_of_previous_req_not_fulfilled = len([x for x in requirement_not_fulfilled if x<final_rank])
 | 
			
		||||
        #final_rank = final_rank -  num_of_previous_req_not_fulfilled
 | 
			
		||||
        final_rank = len(requirement_fulfilled)
 | 
			
		||||
        return {'final_rank': final_rank, 'req_fulfilled': requirement_fulfilled, 'req_not_fulfilled': requirement_not_fulfilled}
 | 
			
		||||
 | 
			
		||||
    def giveContribRankToOrg(self, org, rankNum):
 | 
			
		||||
        keyname = 'CONTRIB_ORG:{org}:{orgCateg}'
 | 
			
		||||
        self.serv_redis_db.set(keyname.format(org=orgName, orgCateg='CONTRIB_REQ_'+str(rankNum)), 1)
 | 
			
		||||
        self.serv_redis_db.set(keyname.format(org=org, orgCateg='CONTRIB_REQ_'+str(rankNum)), 1)
 | 
			
		||||
 | 
			
		||||
    def removeContribRankFromOrg(self, org, rankNum):
 | 
			
		||||
        keyname = 'CONTRIB_ORG:{org}:{orgCateg}'
 | 
			
		||||
        self.serv_redis_db.delete(keyname.format(org=orgName, orgCateg='CONTRIB_REQ_'+str(rankNum)))
 | 
			
		||||
        self.serv_redis_db.delete(keyname.format(org=org, orgCateg='CONTRIB_REQ_'+str(rankNum)))
 | 
			
		||||
 | 
			
		||||
    # 1 for fulfilled, 0 for not fulfilled, -1 for not relevant
 | 
			
		||||
    def getCurrentContributionStatus(self, org):
 | 
			
		||||
| 
						 | 
				
			
			@ -119,16 +120,38 @@ class Contributor_helper:
 | 
			
		|||
                to_ret[i] = -1
 | 
			
		||||
        return {'rank': final_rank, 'status': to_ret, 'totPoints': self.getOrgContributionTotalPoints(org)}
 | 
			
		||||
 | 
			
		||||
    def updateOrgContributionRank(self, orgName, pnts_to_add, contribType, eventTime, isLabeled):
 | 
			
		||||
    def updateOrgContributionRank(self, orgName, pnts_to_add, action, contribType, eventTime, isLabeled):
 | 
			
		||||
        keyname = 'CONTRIB_ORG:{org}:{orgCateg}'
 | 
			
		||||
        #update total points
 | 
			
		||||
        # update total points
 | 
			
		||||
        totOrgPnts = self.serv_redis_db.incrby(keyname.format(org=orgName, orgCateg='points'), pnts_to_add)
 | 
			
		||||
 | 
			
		||||
        # update date variables
 | 
			
		||||
        if contribType == 'Attribute':
 | 
			
		||||
            attributeWeekCount = self.serv_redis_db.incrby(keyname.format(org=orgName, orgCateg='ATTR_WEEK_COUNT'), 1)
 | 
			
		||||
            self.serv_redis_db.expire(keyname.format(org=orgName, orgCateg='ATTR_WEEK_COUNT'), util.ONE_DAY*7)
 | 
			
		||||
 | 
			
		||||
        if contribType == 'Proposal':
 | 
			
		||||
            proposalWeekCount = self.serv_redis_db.incrby(keyname.format(org=orgName, orgCateg='PROP_WEEK_COUNT'), 1)
 | 
			
		||||
            self.serv_redis_db.expire(keyname.format(org=orgName, orgCateg='PROP_WEEK_COUNT'), util.ONE_DAY*7)
 | 
			
		||||
 | 
			
		||||
        if contribType == 'Sighting':
 | 
			
		||||
            sightingWeekCount = self.serv_redis_db.incrby(keyname.format(org=orgName, orgCateg='SIGHT_WEEK_COUNT'), 1)
 | 
			
		||||
            self.serv_redis_db.expire(keyname.format(org=orgName, orgCateg='SIGHT_WEEK_COUNT'), util.ONE_DAY*7)
 | 
			
		||||
 | 
			
		||||
        if contribType == 'Event':
 | 
			
		||||
            eventWeekCount = self.serv_redis_db.incrby(keyname.format(org=orgName, orgCateg='EVENT_WEEK_COUNT'), 1)
 | 
			
		||||
            self.serv_redis_db.expire(keyname.format(org=orgName, orgCateg='EVENT_WEEK_COUNT'), util.ONE_DAY*7)
 | 
			
		||||
 | 
			
		||||
            eventMonthCount = self.serv_redis_db.incrby(keyname.format(org=orgName, orgCateg='EVENT_MONTH_COUNT'), 1)
 | 
			
		||||
            self.serv_redis_db.expire(keyname.format(org=orgName, orgCateg='EVENT_MONTH_COUNT'), util.ONE_DAY*7)
 | 
			
		||||
 | 
			
		||||
        # getRequirement parameters
 | 
			
		||||
        heavilyCount = self.heavilyCount
 | 
			
		||||
        recentDays = self.recentDays
 | 
			
		||||
        regularlyDays = self.regularlyDays
 | 
			
		||||
        isRecent = (datetime.datetime.now() - eventTime).days > recentDays
 | 
			
		||||
 | 
			
		||||
        print("contribType: {}, action: {}".format(contribType, action))
 | 
			
		||||
        print("isLabeled: {}, isRecent: {}, totOrgPnts".format(isLabeled, isRecent, totOrgPnts))
 | 
			
		||||
        #update contribution Requirement
 | 
			
		||||
        contrib = [] #[[contrib_level, contrib_ttl], [], ...]
 | 
			
		||||
| 
						 | 
				
			
			@ -145,9 +168,9 @@ class Contributor_helper:
 | 
			
		|||
            contrib.append([5, util.ONE_DAY*recentDays])
 | 
			
		||||
        if totOrgPnts >= self.org_rank_requirement_pnts[6] and contribType == 'Event':
 | 
			
		||||
            contrib.append([6, util.ONE_DAY*365])
 | 
			
		||||
        if totOrgPnts >= self.org_rank_requirement_pnts[7] and contribType == 'Event':
 | 
			
		||||
        if totOrgPnts >= self.org_rank_requirement_pnts[7] and contribType == 'Event' and eventMonthCount>=1:
 | 
			
		||||
            contrib.append([7, util.ONE_DAY*recentDays])
 | 
			
		||||
        if totOrgPnts >= self.org_rank_requirement_pnts[8] and contribType == 'Event':
 | 
			
		||||
        if totOrgPnts >= self.org_rank_requirement_pnts[8] and contribType == 'Event' and eventWeekCount>=1:
 | 
			
		||||
            contrib.append([8, util.ONE_DAY*regularlyDays])
 | 
			
		||||
        if totOrgPnts >= self.org_rank_requirement_pnts[9] and contribType == 'Event' and isLabeled:
 | 
			
		||||
            contrib.append([9, util.ONE_DAY*regularlyDays])
 | 
			
		||||
| 
						 | 
				
			
			@ -179,11 +202,11 @@ class Contributor_helper:
 | 
			
		|||
 | 
			
		||||
    def giveBadgeToOrg(self, org, badgeNum):
 | 
			
		||||
        keyname = 'CONTRIB_ORG:{org}:{orgCateg}'
 | 
			
		||||
        self.serv_redis_db.set(keyname.format(org=orgName, orgCateg='BADGE_'+str(badgeNum)), 1)
 | 
			
		||||
        self.serv_redis_db.set(keyname.format(org=org, orgCateg='BADGE_'+str(badgeNum)), 1)
 | 
			
		||||
 | 
			
		||||
    def removeBadgeFromOrg(self, org, badgeNum):
 | 
			
		||||
        keyname = 'CONTRIB_ORG:{org}:{orgCateg}'
 | 
			
		||||
        self.serv_redis_db.delete(keyname.format(org=orgName, orgCateg='BADGE_'+str(badgeNum)))
 | 
			
		||||
        self.serv_redis_db.delete(keyname.format(org=org, orgCateg='BADGE_'+str(badgeNum)))
 | 
			
		||||
 | 
			
		||||
    ''' MONTHLY CONTRIBUTION '''
 | 
			
		||||
    def getOrgPntFromRedis(self, org, date):
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -324,6 +324,46 @@ function addLastContributor(datatable, data, update) {
 | 
			
		|||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
function updateProgressBar(org) {
 | 
			
		||||
    if(currOrg != org)
 | 
			
		||||
        return;
 | 
			
		||||
    $.getJSON( url_getOrgRank+'?org='+org, function( data ) {
 | 
			
		||||
        var rank = Math.floor(data.rank);
 | 
			
		||||
        var rankDec = data.rank-rank;
 | 
			
		||||
        var popoverRank = $('#btnCurrRank').data('bs.popover');
 | 
			
		||||
        popoverRank.options.content = generateRankingSheet(rank, rankDec, data.stepPts, data.points, data.remainingPts);
 | 
			
		||||
        $('#orgRankDiv').html(getMonthlyRankIcon(rank, 40, true));
 | 
			
		||||
        $('#orgNextRankDiv').html(getMonthlyRankIcon(rank+1, 40, true));
 | 
			
		||||
        if (data.rank > 16){
 | 
			
		||||
            $('#progressBarDiv').width(1*150); //150 is empty bar width
 | 
			
		||||
        } else {
 | 
			
		||||
            $('#progressBarDiv').width((data.rank - rank)*150); //150 is empty bar width
 | 
			
		||||
        }
 | 
			
		||||
    });
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
function updateOvertakePnts() {
 | 
			
		||||
    var prevOrgName = "";
 | 
			
		||||
    var prevOrgPnts = 0;
 | 
			
		||||
    datatableTop.rows().every( function() {
 | 
			
		||||
        var row = this.node();
 | 
			
		||||
        var orgRowName = $(this.data()[5])[0].text; // contained in <a>
 | 
			
		||||
        var orgRowPnts = this.data()[0]
 | 
			
		||||
        if(orgRowName == currOrg) {
 | 
			
		||||
            if(prevOrgName == ""){ //already first
 | 
			
		||||
                $('#orgToOverTake').text(orgRowName);
 | 
			
		||||
                $('#pntsToOvertakeNext').text(0);
 | 
			
		||||
            } else {
 | 
			
		||||
                $('#orgToOverTake').text(prevOrgName);
 | 
			
		||||
                $('#pntsToOvertakeNext').text(parseInt(prevOrgPnts)-orgRowPnts);
 | 
			
		||||
            }
 | 
			
		||||
        } else {
 | 
			
		||||
            prevOrgName = orgRowName;
 | 
			
		||||
            prevOrgPnts = orgRowPnts;
 | 
			
		||||
        }
 | 
			
		||||
    });
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
function updateProgressHeader(org) {
 | 
			
		||||
    currOrg = org;
 | 
			
		||||
    // get Org rank
 | 
			
		||||
| 
						 | 
				
			
			@ -395,36 +435,16 @@ function updateProgressHeader(org) {
 | 
			
		|||
 | 
			
		||||
    // colorize badge if acquired
 | 
			
		||||
    $.getJSON( url_getHonorBadges+'?org='+org, function( data ) {
 | 
			
		||||
        for(var i=0; i<data.length; i++) {
 | 
			
		||||
            if (data[i] == 1) {
 | 
			
		||||
                $('#divBadge_'+(i+1)).addClass('circlBadgeAcquired');
 | 
			
		||||
            } else {
 | 
			
		||||
                $('#divBadge_'+(i+1)).removeClass('circlBadgeAcquired');
 | 
			
		||||
            }
 | 
			
		||||
        for(var i=0; i<numberOfBadges; i++) { // remove
 | 
			
		||||
            $('#divBadge_'+(i+1)).removeClass('circlBadgeAcquired');
 | 
			
		||||
        }
 | 
			
		||||
        for(var i=0; i<data.length; i++) { // add
 | 
			
		||||
            $('#divBadge_'+(data[i])).addClass('circlBadgeAcquired');
 | 
			
		||||
        }
 | 
			
		||||
    });
 | 
			
		||||
 | 
			
		||||
    //update overtake points
 | 
			
		||||
    var prevOrgName = "";
 | 
			
		||||
    var prevOrgPnts = 0;
 | 
			
		||||
    datatableTop.rows().every( function() {
 | 
			
		||||
        var row = this.node();
 | 
			
		||||
        var orgRowName = $(this.data()[5])[0].text; // contained in <a>
 | 
			
		||||
        var orgRowPnts = this.data()[0]
 | 
			
		||||
        if(orgRowName == currOrg) {
 | 
			
		||||
            if(prevOrgName == ""){ //already first
 | 
			
		||||
                $('#orgToOverTake').text(orgRowName);
 | 
			
		||||
                $('#pntsToOvertakeNext').text(0);
 | 
			
		||||
            } else {
 | 
			
		||||
                $('#orgToOverTake').text(prevOrgName);
 | 
			
		||||
                $('#pntsToOvertakeNext').text(parseInt(prevOrgPnts)-orgRowPnts);
 | 
			
		||||
            }
 | 
			
		||||
        } else {
 | 
			
		||||
            prevOrgName = orgRowName;
 | 
			
		||||
            prevOrgPnts = orgRowPnts;
 | 
			
		||||
        }
 | 
			
		||||
    });
 | 
			
		||||
 | 
			
		||||
    updateOvertakePnts();
 | 
			
		||||
    //Add new data to linechart
 | 
			
		||||
    $.getJSON( url_getOrgOvertime+'?org='+org, function( data ) {
 | 
			
		||||
        var toPlot = dataTop5Overtime.slice(0); //cloning data
 | 
			
		||||
| 
						 | 
				
			
			@ -531,7 +551,8 @@ $(document).ready(function() {
 | 
			
		|||
        var json = jQuery.parseJSON( event.data );
 | 
			
		||||
        addLastContributor(datatableLast, json, true);
 | 
			
		||||
        datatableLast.draw();
 | 
			
		||||
        updateProgressHeader(json.org)
 | 
			
		||||
        updateProgressBar(json.org);
 | 
			
		||||
        updateOvertakePnts();
 | 
			
		||||
        sec_before_reload = refresh_speed; //reset timer at each contribution
 | 
			
		||||
    };
 | 
			
		||||
});
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -397,6 +397,7 @@
 | 
			
		|||
        var categ_list = JSON.parse('{{ categ_list|safe }}');
 | 
			
		||||
        var org_rank_obj = JSON.parse('{{ org_rank_json|safe }}');
 | 
			
		||||
        var org_honor_badge_title = JSON.parse('{{ org_honor_badge_title|safe }}');
 | 
			
		||||
        var numberOfBadges = {{ org_honor_badge_title_list|length }};
 | 
			
		||||
 | 
			
		||||
    </script>
 | 
			
		||||
    <script src="{{ url_for('static', filename='js/contrib.js') }}"></script>
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -126,34 +126,39 @@ def getFields(obj, fields):
 | 
			
		|||
    except KeyError as e:
 | 
			
		||||
        return ""
 | 
			
		||||
 | 
			
		||||
def noSpaceLower(str):
 | 
			
		||||
    return str.lower().replace(' ', '_')
 | 
			
		||||
def noSpaceLower(text):
 | 
			
		||||
    return text.lower().replace(' ', '_')
 | 
			
		||||
 | 
			
		||||
#pntMultiplier if one contribution rewards more than others. (e.g. shighting may gives more points than editing)
 | 
			
		||||
def handleContribution(zmq_name, org, contribType, categ, action, pntMultiplier=1, eventTime=datetime.datetime.now(), isLabeled=False):
 | 
			
		||||
    if action in ['edit', None]:
 | 
			
		||||
        pass
 | 
			
		||||
        #return #not a contribution?
 | 
			
		||||
    # is a valid contribution
 | 
			
		||||
    try:
 | 
			
		||||
        pnts_to_add = DICO_PNTS_REWARD[noSpaceLower(categ)]
 | 
			
		||||
    except KeyError:
 | 
			
		||||
        pnts_to_add = DEFAULT_PNTS_REWARD
 | 
			
		||||
    pnts_to_add *= pntMultiplier
 | 
			
		||||
 | 
			
		||||
    push_to_redis_zset('CONTRIB_DAY', org, count=pnts_to_add)
 | 
			
		||||
    #CONTRIB_CATEG retain the contribution per category, not the point earned in this categ
 | 
			
		||||
    push_to_redis_zset('CONTRIB_CATEG', org, count=DEFAULT_PNTS_REWARD, endSubkey=':'+noSpaceLower(categ))
 | 
			
		||||
    serv_redis_db.sadd('CONTRIB_ALL_ORG', org)
 | 
			
		||||
 | 
			
		||||
    now = datetime.datetime.now()
 | 
			
		||||
    nowSec = int(time.time())
 | 
			
		||||
    pnts_to_add = DEFAULT_PNTS_REWARD
 | 
			
		||||
 | 
			
		||||
    # is a valid contribution
 | 
			
		||||
    if categ is not None:
 | 
			
		||||
        try:
 | 
			
		||||
            pnts_to_add = DICO_PNTS_REWARD[noSpaceLower(categ)]
 | 
			
		||||
        except KeyError:
 | 
			
		||||
            pnts_to_add = DEFAULT_PNTS_REWARD
 | 
			
		||||
        pnts_to_add *= pntMultiplier
 | 
			
		||||
 | 
			
		||||
        push_to_redis_zset('CONTRIB_DAY', org, count=pnts_to_add)
 | 
			
		||||
        #CONTRIB_CATEG retain the contribution per category, not the point earned in this categ
 | 
			
		||||
        push_to_redis_zset('CONTRIB_CATEG', org, count=DEFAULT_PNTS_REWARD, endSubkey=':'+noSpaceLower(categ))
 | 
			
		||||
        publish_log(zmq_name, 'CONTRIBUTION', {'org': org, 'categ': categ, 'action': action, 'epoch': nowSec }, channel=CHANNEL_LASTCONTRIB)
 | 
			
		||||
 | 
			
		||||
    serv_redis_db.sadd('CONTRIB_ALL_ORG', org)
 | 
			
		||||
 | 
			
		||||
    serv_redis_db.zadd('CONTRIB_LAST:'+util.getDateStrFormat(now), nowSec, org)
 | 
			
		||||
    serv_redis_db.expire('CONTRIB_LAST:'+util.getDateStrFormat(now), ONE_DAY) #expire after 1 day
 | 
			
		||||
 | 
			
		||||
    contributor_helper.updateOrgContributionRank(org, pnts_to_add, contribType, eventTime=datetime.datetime.now(), isLabeled=isLabeled)
 | 
			
		||||
    contributor_helper.updateOrgContributionRank(org, pnts_to_add, action, contribType, eventTime=datetime.datetime.now(), isLabeled=isLabeled)
 | 
			
		||||
 | 
			
		||||
    publish_log(zmq_name, 'CONTRIBUTION', {'org': org, 'categ': categ, 'action': action, 'epoch': nowSec }, channel=CHANNEL_LASTCONTRIB)
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
##############
 | 
			
		||||
| 
						 | 
				
			
			@ -173,6 +178,10 @@ def handler_keepalive(zmq_name, jsonevent):
 | 
			
		|||
    to_push = [ jsonevent['uptime'] ]
 | 
			
		||||
    publish_log(zmq_name, 'Keepalive', to_push)
 | 
			
		||||
 | 
			
		||||
def handler_object(zmq_name, jsondata):
 | 
			
		||||
    print('obj')
 | 
			
		||||
    return
 | 
			
		||||
 | 
			
		||||
def handler_sighting(zmq_name, jsondata):
 | 
			
		||||
    print('sending' ,'sighting')
 | 
			
		||||
    jsonsight = jsondata['Sighting']
 | 
			
		||||
| 
						 | 
				
			
			@ -199,6 +208,26 @@ def handler_event(zmq_name, jsonobj):
 | 
			
		|||
        else:
 | 
			
		||||
            handler_attribute(zmq_name, attributes)
 | 
			
		||||
 | 
			
		||||
    try:
 | 
			
		||||
        action = jsonobj['action']
 | 
			
		||||
    except KeyError:
 | 
			
		||||
        action = None
 | 
			
		||||
    try:
 | 
			
		||||
        eventLabeled = len(jsonobj['EventTag']) > 0
 | 
			
		||||
    except KeyError:
 | 
			
		||||
        eventLabeled = False
 | 
			
		||||
    try:
 | 
			
		||||
        org = jsonobj['Orgc']['name']
 | 
			
		||||
    except KeyError:
 | 
			
		||||
        org = None
 | 
			
		||||
 | 
			
		||||
    if org is not None:
 | 
			
		||||
        handleContribution(zmq_name, org,
 | 
			
		||||
                        'Event',
 | 
			
		||||
                        None,
 | 
			
		||||
                        action,
 | 
			
		||||
                        isLabeled=eventLabeled)
 | 
			
		||||
 | 
			
		||||
def handler_attribute(zmq_name, jsonobj, hasAlreadyBeenContributed=False):
 | 
			
		||||
    # check if jsonattr is an attribute object
 | 
			
		||||
    if 'Attribute' in jsonobj:
 | 
			
		||||
| 
						 | 
				
			
			@ -267,6 +296,7 @@ dico_action = {
 | 
			
		|||
        "misp_json_event":          handler_event,
 | 
			
		||||
        "misp_json_self":           handler_keepalive,
 | 
			
		||||
        "misp_json_attribute":      handler_attribute,
 | 
			
		||||
        "misp_json_object":         handler_object,
 | 
			
		||||
        "misp_json_sighting":       handler_sighting,
 | 
			
		||||
        "misp_json_organisation":   handler_log,
 | 
			
		||||
        "misp_json_user":           handler_log,
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
		Reference in New Issue