mirror of https://github.com/MISP/MISP
new: First iteration of the improved sightings
parent
c8a0b0d870
commit
4e41b55572
|
@ -748,6 +748,8 @@ class EventsController extends AppController {
|
|||
$this->set('attributeFilter', isset($this->params['named']['attributeFilter']) ? $this->params['named']['attributeFilter'] : 'all');
|
||||
$this->disableCache();
|
||||
$this->layout = 'ajax';
|
||||
$this->loadModel('Sighting');
|
||||
$this->set('sightingTypes', $this->Sighting->type);
|
||||
$this->set('currentUri', $this->params->here);
|
||||
$this->render('/Elements/eventattribute');
|
||||
}
|
||||
|
@ -859,6 +861,8 @@ class EventsController extends AppController {
|
|||
}
|
||||
$this->set('contributors', $contributors);
|
||||
$this->set('typeGroups', array_keys($this->Event->Attribute->typeGroupings));
|
||||
$this->loadModel('Sighting');
|
||||
$this->set('sightingTypes', $this->Sighting->type);
|
||||
}
|
||||
|
||||
public function view($id = null, $continue=false, $fromEvent=null) {
|
||||
|
|
|
@ -28,6 +28,8 @@ class SightingsController extends AppController {
|
|||
if ($result['success']) {
|
||||
$result['data'] = json_decode($result['data'], true);
|
||||
$timestamp = isset($result['data']['timestamp']) ? strtotime($result['data']['timestamp']) : $now;
|
||||
$type = '0';
|
||||
$source = '';
|
||||
if (isset($result['data']['values'])) $values = $result['data']['values'];
|
||||
else $error = 'No valid values found could be extracted from the sightings document.';
|
||||
} $error = $result['message'];
|
||||
|
@ -38,8 +40,10 @@ class SightingsController extends AppController {
|
|||
if (isset($this->request->data['value'])) $this->request->data['values'] = array($this->request->data['value']);
|
||||
$values = isset($this->request->data['values']) ? $this->request->data['values'] : false;
|
||||
if (!$id && isset($this->request->data['id'])) $id = $this->request->data['id'];
|
||||
$type = isset($this->request->data['type']) ? $this->request->data['type'] : '0';
|
||||
$source = isset($this->request->data['type']) ? $this->request->data['type'] : '';
|
||||
}
|
||||
if (!$error) $result = $this->Sighting->saveSightings($id, $values, $timestamp, $this->Auth->user());
|
||||
if (!$error) $result = $this->Sighting->saveSightings($id, $values, $timestamp, $this->Auth->user(), $type, $source);
|
||||
if ($result == 0) $error = 'No valid attributes found that would match the sighting criteria.';
|
||||
|
||||
if ($this->request->is('ajax')) {
|
||||
|
@ -47,13 +51,13 @@ class SightingsController extends AppController {
|
|||
$error_message = 'Could not add the Sighting. Reason: ' . $error;
|
||||
return new CakeResponse(array('body'=> json_encode(array('saved' => false, 'errors' => $error_message)), 'status' => 200));
|
||||
} else {
|
||||
return new CakeResponse(array('body'=> json_encode(array('saved' => true, 'success' => $result . ' sighting' . (($result == 1) ? '' : 's') . ' added.')), 'status' => 200));
|
||||
return new CakeResponse(array('body'=> json_encode(array('saved' => true, 'success' => $result . ' ' . $this->Sighting->type[$type] . (($result == 1) ? '' : 's') . ' added.')), 'status' => 200));
|
||||
}
|
||||
} else {
|
||||
if ($error) {
|
||||
return $this->RestResponse->saveFailResponse('Sighting', 'add', $id, $error);
|
||||
} else {
|
||||
return $this->RestResponse->saveSuccessResponse('Sighting', 'add', $id, false, $result . ' sighting' . (($result == 1) ? '' : 's') . ' successfuly added.');
|
||||
return $this->RestResponse->saveSuccessResponse('Sighting', 'add', $id, false, $result . ' ' . $this->Sighting->type[$type] . (($result == 1) ? '' : 's') . ' successfuly added.');
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -41,7 +41,7 @@ class AppModel extends Model {
|
|||
42 => false, 44 => false, 45 => false, 49 => true, 50 => false,
|
||||
51 => false, 52 => false, 55 => true, 56 => true, 57 => true,
|
||||
58 => false, 59 => false, 60 => false, 61 => false, 62 => false,
|
||||
63 => false
|
||||
63 => false, 64 => false
|
||||
)
|
||||
)
|
||||
);
|
||||
|
@ -78,6 +78,11 @@ class AppModel extends Model {
|
|||
case '2.4.55':
|
||||
$this->updateDatabase('addSightings');
|
||||
break;
|
||||
case '2.4.64':
|
||||
$this->updateDatabase('2.4.64');
|
||||
$this->Sighting = Classregistry::init('Sighting');
|
||||
$this->Sighting->addUuids();
|
||||
break;
|
||||
default:
|
||||
$this->updateDatabase($command);
|
||||
break;
|
||||
|
@ -576,6 +581,11 @@ class AppModel extends Model {
|
|||
$sqlArray[] = 'ALTER TABLE events DROP COLUMN orgc;';
|
||||
$sqlArray[] = 'ALTER TABLE event_blacklists CHANGE comment comment TEXT CHARACTER SET utf8 COLLATE utf8_unicode_ci;';
|
||||
break;
|
||||
case '2.4.64':
|
||||
$sqlArray[] = 'ALTER TABLE sightings ADD COLUMN uuid varchar(255) COLLATE utf8_bin DEFAULT "";';
|
||||
$sqlArray[] = 'ALTER TABLE sightings ADD COLUMN source varchar(255) COLLATE utf8_bin DEFAULT "";';
|
||||
$sqlArray[] = 'ALTER TABLE sightings ADD COLUMN type int(11) DEFAULT 0;';
|
||||
break;
|
||||
case 'fixNonEmptySharingGroupID':
|
||||
$sqlArray[] = 'UPDATE `events` SET `sharing_group_id` = 0 WHERE `distribution` != 4;';
|
||||
$sqlArray[] = 'UPDATE `attributes` SET `sharing_group_id` = 0 WHERE `distribution` != 4;';
|
||||
|
|
|
@ -28,12 +28,21 @@ class Sighting extends AppModel {
|
|||
),
|
||||
);
|
||||
|
||||
public $type = array(
|
||||
0 => 'sighting',
|
||||
1 => 'false-positive',
|
||||
2 => 'expiration'
|
||||
);
|
||||
|
||||
public function beforeValidate($options = array()) {
|
||||
parent::beforeValidate();
|
||||
$date = date('Y-m-d H:i:s');
|
||||
if (empty($this->data['Sighting']['id']) && empty($this->data['Sighting']['date_sighting'])) {
|
||||
$this->data['Sighting']['date_sighting'] = $date;
|
||||
}
|
||||
if (empty($this->data['Sighting']['uuid'])) {
|
||||
$this->data['Sighting']['uuid'] = CakeText::uuid();
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -81,7 +90,7 @@ class Sighting extends AppModel {
|
|||
return $sightings;
|
||||
}
|
||||
|
||||
public function saveSightings($id, $values, $timestamp, $user) {
|
||||
public function saveSightings($id, $values, $timestamp, $user, $type = false, $source = false) {
|
||||
$conditions = array();
|
||||
if ($id && $id !== 'stix') {
|
||||
if (strlen($id) == 36) $conditions = array('Attribute.uuid' => $id);
|
||||
|
@ -106,6 +115,8 @@ class Sighting extends AppModel {
|
|||
'event_id' => $attribute['Attribute']['event_id'],
|
||||
'org_id' => $user['org_id'],
|
||||
'date_sighting' => $timestamp,
|
||||
'type' => $type,
|
||||
'source' => $source
|
||||
);
|
||||
$sightingsAdded += $this->save($sighting) ? 1 : 0;
|
||||
}
|
||||
|
@ -139,4 +150,13 @@ class Sighting extends AppModel {
|
|||
public function generateRandomFileName() {
|
||||
return (new RandomTool())->random_str(FALSE, 12);
|
||||
}
|
||||
|
||||
public function addUuids() {
|
||||
$sightings = $this->find('all', array(
|
||||
'recursive' => -1,
|
||||
'conditions' => array('uuid' => '')
|
||||
));
|
||||
$this->saveMany($sightings);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -15,49 +15,38 @@
|
|||
$attributeSightings = array();
|
||||
$attributeOwnSightings = array();
|
||||
$attributeSightingsPopover = array();
|
||||
if (isset($event['Sighting']) && !empty($event['Sighting'])) {
|
||||
$sightingsData = array();
|
||||
if (!empty($event['Sighting'])) {
|
||||
foreach ($event['Sighting'] as $sighting) {
|
||||
$attributeSightings[$sighting['attribute_id']][] = $sighting;
|
||||
if (isset($sighting['org_id']) && $sighting['org_id'] == $me['org_id']) {
|
||||
if (isset($attributeOwnSightings[$sighting['attribute_id']])) {
|
||||
$attributeOwnSightings[$sighting['attribute_id']]['count']++;
|
||||
if (!isset($attributeOwnSightings[$sighting['attribute_id']]['date']) || $attributeOwnSightings[$sighting['attribute_id']]['date'] < $sighting['date_sighting']) {
|
||||
$attributeOwnSightings[$sighting['attribute_id']]['date'] = $sighting['date_sighting'];
|
||||
}
|
||||
} else {
|
||||
$attributeOwnSightings[$sighting['attribute_id']]['count'] = 1;
|
||||
$attributeOwnSightings[$sighting['attribute_id']]['date'] = $sighting['date_sighting'];
|
||||
}
|
||||
$type = $sightingTypes[$sighting['type']];
|
||||
if (!isset($sightingsData[$sighting['attribute_id']][$type])) {
|
||||
$sightingsData[$sighting['attribute_id']][$type] = array('count' => 0);
|
||||
}
|
||||
if (isset($sighting['org_id'])) {
|
||||
if (isset($attributeSightingsPopover[$sighting['attribute_id']][$sighting['Organisation']['name']])) {
|
||||
$attributeSightingsPopover[$sighting['attribute_id']][$sighting['Organisation']['name']]['count']++;
|
||||
if (!isset($attributeSightingsPopover[$sighting['attribute_id']][$sighting['Organisation']['name']]['date']) || $attributeSightingsPopover[$sighting['attribute_id']][$sighting['Organisation']['name']]['date'] < $sighting['date_sighting']) {
|
||||
$attributeSightingsPopover[$sighting['attribute_id']][$sighting['Organisation']['name']]['date'] = $sighting['date_sighting'];
|
||||
}
|
||||
} else {
|
||||
$attributeSightingsPopover[$sighting['attribute_id']][$sighting['Organisation']['name']]['count'] = 1;
|
||||
$attributeSightingsPopover[$sighting['attribute_id']][$sighting['Organisation']['name']]['date'] = $sighting['date_sighting'];
|
||||
}
|
||||
$sightingsData[$sighting['attribute_id']][$type]['count']++;
|
||||
$orgName = isset($sighting['Organisation']['name']) ? $sighting['Organisation']['name'] : 'Others';
|
||||
if (!isset($sightingsData[$sighting['attribute_id']][$type]['orgs'][$orgName])) {
|
||||
$sightingsData[$sighting['attribute_id']][$type]['orgs'][$orgName] = array('count' => 1, 'date' => $sighting['date_sighting']);
|
||||
} else {
|
||||
if (isset($attributeSightingsPopover[$sighting['attribute_id']]['Other organisations'])) {
|
||||
$attributeSightingsPopover[$sighting['attribute_id']]['Other organisations']['count']++;
|
||||
if (!isset($attributeSightingsPopover[$sighting['attribute_id']]['Other organisations']['date']) || $attributeSightingsPopover[$sighting['attribute_id']]['Other organisations']['date'] < $sighting['date_sighting']) {
|
||||
$attributeSightingsPopover[$sighting['attribute_id']]['Other organisations']['date'] = $sighting['date_sighting'];
|
||||
}
|
||||
} else {
|
||||
$attributeSightingsPopover[$sighting['attribute_id']]['Other organisations']['count'] = 1;
|
||||
$attributeSightingsPopover[$sighting['attribute_id']]['Other organisations']['date'] = $sighting['date_sighting'];
|
||||
$sightingsData[$sighting['attribute_id']][$type]['orgs'][$orgName]['count']++;
|
||||
if ($sightingsData[$sighting['attribute_id']][$type]['orgs'][$orgName]['date'] < $sighting['date_sighting']) {
|
||||
$sightingsData[$sighting['attribute_id']][$type]['orgs'][$orgName]['date'] = $sighting['date_sighting'];
|
||||
}
|
||||
}
|
||||
}
|
||||
if (!empty($attributeSightingsPopover)) {
|
||||
$attributeSightingsPopoverText = array();
|
||||
foreach ($attributeSightingsPopover as $aid => &$attribute) {
|
||||
$attributeSightingsPopoverText[$aid] = '';
|
||||
foreach ($attribute as $org => $data) {
|
||||
$attributeSightingsPopoverText[$aid] .= '<span class=\'bold\'>' . h($org) . '</span>: <span class=\'green bold\'>' . h($data['count']) . ' (' . date('Y-m-d H:i:s', $data['date']) . ')</span><br />';
|
||||
foreach ($sightingsData as $aid => $data) {
|
||||
$sightingsData[$aid]['html'] = '';
|
||||
foreach ($data as $type => $typeData) {
|
||||
$name = (($type != 'expiration') ? Inflector::pluralize($type) : $type);
|
||||
$sightingsData[$aid]['html'] .= '<span class=\'blue bold\'>' . ucfirst(h($name)) . '</span><br />';
|
||||
foreach ($typeData['orgs'] as $org => $orgData) {
|
||||
$extra = (($org == $me['Organisation']['name']) ? " class= 'bold'" : "");
|
||||
if ($type == 'expiration') {
|
||||
$sightingsData[$aid]['html'] .= '<span ' . $extra . '>' . h($org) . '</span>: <span class=\'orange bold\'>' . date('Y-m-d H:i:s', $orgData['date']) . '</span><br />';
|
||||
} else {
|
||||
$sightingsData[$aid]['html'] .= '<span ' . $extra . '>' . h($org) . '</span>: <span class=\'' . (($type == 'sighting') ? 'green' : 'red') . ' bold\'>' . h($orgData['count']) . ' (' . date('Y-m-d H:i:s', $orgData['date']) . ')</span><br />';
|
||||
}
|
||||
}
|
||||
$sightingsData[$aid]['html'] .= '<br />';
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -452,20 +441,27 @@
|
|||
endif;
|
||||
if (Configure::read('Plugin.Sightings_enable') !== false):
|
||||
?>
|
||||
<td class="short <?php echo $extra;?>">
|
||||
<td class="shortish <?php echo $extra;?>">
|
||||
<span id="sightingForm_<?php echo h($object['id']);?>">
|
||||
<?php
|
||||
if ($object['objectType'] == 0):
|
||||
echo $this->Form->create('Sighting', array('id' => 'Sighting_' . $object['id'], 'url' => '/sightings/add/' . $object['id'], 'style' => 'display:none;'));
|
||||
echo $this->Form->input('type', array('label' => false, 'id' => 'Sighting_' . $object['id'] . '_type'));
|
||||
echo $this->Form->end();
|
||||
?>
|
||||
</span>
|
||||
<span class="icon-thumbs-up useCursorPointer" onClick="addSighting('<?php echo h($object['id']); ?>', '<?php echo h($event['Event']['id']);?>', '<?php echo h($page); ?>');"> </span>
|
||||
<span id="sightingCount_<?php echo h($object['id']); ?>" class="bold sightingsCounter_<?php echo h($object['id']); ?>" data-placement="top" data-toggle="popover" data-trigger="hover" data-content="<?php echo isset($attributeSightingsPopoverText[$object['id']]) ? $attributeSightingsPopoverText[$object['id']] : ''; ?>">
|
||||
<?php echo (!empty($attributeSightings[$object['id']]) ? count($attributeSightings[$object['id']]) : 0); ?>
|
||||
<span class="icon-thumbs-up useCursorPointer" onClick="addSighting('0', '<?php echo h($object['id']); ?>', '<?php echo h($event['Event']['id']);?>', '<?php echo h($page); ?>');"> </span>
|
||||
<span class="icon-thumbs-down useCursorPointer" onClick="addSighting('1', '<?php echo h($object['id']); ?>', '<?php echo h($event['Event']['id']);?>', '<?php echo h($page); ?>');"> </span>
|
||||
<span class="icon-wrench useCursorPointer" onClick="addSighting('<?php echo h($object['id']); ?>', '<?php echo h($event['Event']['id']);?>', '<?php echo h($page); ?>');"> </span>
|
||||
<span id="sightingCount_<?php echo h($object['id']); ?>" class="bold sightingsCounter_<?php echo h($object['id']); ?>" data-placement="top" data-toggle="popover" data-trigger="hover" data-content="<?php echo isset($sightingsData[$object['id']]['html']) ? $sightingsData[$object['id']]['html'] : ''; ?>">
|
||||
<?php
|
||||
$s = (!empty($sightingsData[$object['id']]['sighting']['count']) ? $sightingsData[$object['id']]['sighting']['count'] : 0);
|
||||
$f = (!empty($sightingsData[$object['id']]['false-positive']['count']) ? $sightingsData[$object['id']]['false-positive']['count'] : 0);
|
||||
$e = (!empty($sightingsData[$object['id']]['expiration']['count']) ? $sightingsData[$object['id']]['expiration']['count'] : 0);
|
||||
?>
|
||||
</span>
|
||||
<span id="ownSightingCount_<?php echo h($object['id']); ?>" class="bold green sightingsCounter_<?php echo h($object['id']); ?>" data-placement="top" data-toggle="popover" data-trigger="hover" data-content="<?php echo isset($attributeSightingsPopoverText[$object['id']]) ? $attributeSightingsPopoverText[$object['id']] : ''; ?>">
|
||||
<?php echo '(' . (isset($attributeOwnSightings[$object['id']]['count']) ? $attributeOwnSightings[$object['id']]['count'] : 0) . ')'; ?>
|
||||
<span id="ownSightingCount_<?php echo h($object['id']); ?>" class="bold sightingsCounter_<?php echo h($object['id']); ?>" data-placement="top" data-toggle="popover" data-trigger="hover" data-content="<?php echo isset($sightingsData[$object['id']]['html']) ? $sightingsData[$object['id']]['html'] : ''; ?>">
|
||||
<?php echo '(<span class="green">' . h($s) . '</span>/<span class="red">' . h($f) . '</span>/<span class="orange">' . h($e) . '</span>)'; ?>
|
||||
</span>
|
||||
<?php
|
||||
endif;
|
||||
|
|
|
@ -340,7 +340,8 @@ function postActivationScripts(name, type, id, field, event) {
|
|||
$(name + '_solid').hide();
|
||||
}
|
||||
|
||||
function addSighting(attribute_id, event_id, $page) {
|
||||
function addSighting(type, attribute_id, event_id, page) {
|
||||
$('#Sighting_' + attribute_id + '_type').val(type);
|
||||
$.ajax({
|
||||
data: $('#Sighting_' + attribute_id).closest("form").serialize(),
|
||||
cache: false,
|
||||
|
|
Loading…
Reference in New Issue