new: Extended event first iteration added

- when adding/editing an event, add another event's UUID as an extended event UUID to extend the targeted event with the current
- extender events can be viewed in the merged event view
pull/3148/head
iglocska 2018-04-10 18:43:09 +02:00
parent 9ba1af9645
commit caf53e0c7f
12 changed files with 283 additions and 30 deletions

View File

@ -845,10 +845,16 @@ class EventsController extends AppController {
if (isset($this->params['named']['focus'])) {
$this->set('focus', $this->params['named']['focus']);
}
$conditions = array('eventid' => $id);
if (isset($this->params['named']['extended'])) {
$conditions['extended'] = 1;
$this->set('extended', 1);
} else {
$this->set('extended', 0);
}
if (!empty($this->params['named']['overrideLimit'])) {
$conditions['overrideLimit'] = 1;
}
$conditions = array('eventid' => $id);
if (isset($this->params['named']['deleted']) && $this->params['named']['deleted']) {
$conditions['deleted'] = 1;
}
@ -1071,6 +1077,18 @@ class EventsController extends AppController {
$this->set($variable, $currentModel->{$variable});
}
}
$extensionParams = array(
'conditions' => array(
'Event.extends_uuid' => $event['Event']['uuid']
)
);
$extensions = $this->Event->fetchSimpleEvents($this->Auth->user(), $extensionParams);
$this->set('extensions', $extensions);
if (!empty($event['Event']['extends_uuid'])) {
$extendedEvent = $this->Event->fetchSimpleEvents($this->Auth->user(), array('conditions' => array('Event.uuid' => $event['Event']['extends_uuid'])));
if (empty($extendedEvent)) $extendedEvent = $event['Event']['extends_uuid'];
$this->set('extendedEvent', $extendedEvent);
}
if (Configure::read('MISP.delegation')) {
$this->loadModel('EventDelegation');
$delegationConditions = array('EventDelegation.event_id' => $event['Event']['id']);
@ -1149,6 +1167,12 @@ class EventsController extends AppController {
if (!empty($this->params['named']['overrideLimit']) && !$this->_isRest()) {
$conditions['overrideLimit'] = 1;
}
if (!empty($this->params['named']['extended'])) {
$conditions['extended'] = 1;
$this->set('extended', 1);
} else {
$this->set('extended', 0);
}
$conditions['includeFeedCorrelations'] = true;
$results = $this->Event->fetchEvent($this->Auth->user(), $conditions);
if (empty($results)) throw new NotFoundException('Invalid event');
@ -1308,6 +1332,11 @@ class EventsController extends AppController {
if (!isset($this->request->data['Event']['date'])) {
$this->request->data['Event']['date'] = date('Y-m-d');
}
if (!empty($this->request->data['Event']['extends_uuid']) && !Validation::uuid($this->request->data['Event']['extends_uuid'])) {
if (!$this->Event->checkIfAuthorised($this->Auth->user(), $this->request->data['Event']['extends_uuid'])) {
throw new MethodNotAllowedException('Invalid ID given for the event that is to be extended. Make sure that you pass the UUID of the correct event or the local ID of an existing event that you have access to.');
}
}
// If the distribution is set to sharing group, check if the id provided is really visible to the user, if not throw an error.
if ($this->request->data['Event']['distribution'] == 4) {
if ($this->userRole['perm_sync'] && $this->_isRest()) {
@ -1646,6 +1675,11 @@ class EventsController extends AppController {
// Workaround for different structure in XML/array than what CakePHP expects
if (isset($this->request->data['response'])) $this->request->data = $this->request->data['response'];
if (!isset($this->request->data['Event'])) $this->request->data = array('Event' => $this->request->data);
if (isset($this->request->data['Event']['extends_uuid']) && !Validation::uuid($this->request->data['Event']['extends_uuid'])) {
if (!$this->Event->checkIfAuthorised($this->Auth->user(), $this->request->data['Event']['extends_uuid'])) {
throw new MethodNotAllowedException('Invalid ID given for the event that is to be extended. Make sure that you pass the UUID of the correct event or the local ID of an existing event that you have access to.');
}
}
$result = $this->Event->_edit($this->request->data, $this->Auth->user(), $id);
if ($result === true) {
// REST users want to see the newly created event
@ -1677,7 +1711,7 @@ class EventsController extends AppController {
}
}
// say what fields are to be updated
$fieldList = array('date', 'threat_level_id', 'analysis', 'info', 'published', 'distribution', 'timestamp', 'sharing_group_id');
$fieldList = array('date', 'threat_level_id', 'analysis', 'info', 'published', 'distribution', 'timestamp', 'sharing_group_id', 'extends_uuid');
$this->Event->read();
// always force the org, but do not force it for admins
@ -1689,6 +1723,11 @@ class EventsController extends AppController {
$this->request->data['Event']['published'] = 0;
$date = new DateTime();
$this->request->data['Event']['timestamp'] = $date->getTimestamp();
if (isset($this->request->data['Event']['extends_uuid']) && !Validation::uuid($this->request->data['Event']['extends_uuid'])) {
if (!$this->Event->checkIfAuthorised($this->Auth->user(), $this->request->data['Event']['extends_uuid'])) {
throw new MethodNotAllowedException('Invalid ID given for the event that is to be extended. Make sure that you pass the UUID of the correct event or the local ID of an existing event that you have access to.');
}
}
if ($this->Event->save($this->request->data, true, $fieldList)) {
$this->Session->setFlash(__('The event has been saved'));
$this->redirect(array('action' => 'view', $id));

View File

@ -60,7 +60,7 @@ class AppModel extends Model {
);
public $db_changes = array(
1 => false, 2 => false, 3 => false, 4 => true, 5 => false
1 => false, 2 => false, 3 => false, 4 => true, 5 => false, 6 => false
);
function afterSave($created, $options = array()) {
@ -898,6 +898,10 @@ class AppModel extends Model {
case 5:
$sqlArray[] = "ALTER TABLE `feeds` ADD `caching_enabled` BOOLEAN NOT NULL DEFAULT 0;";
break;
case 6:
$sqlArray[] = "ALTER TABLE `events` ADD `extends_uuid` varchar(40) COLLATE utf8_bin DEFAULT '';";
$indexArray[] = array('events', 'extends_uuid');
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;';

View File

@ -230,13 +230,8 @@ class Event extends AppModel {
),
'user_id' => array(
'numeric' => array(
'rule' => array('numeric'),
//'message' => 'Your custom message here',
//'allowEmpty' => false,
//'required' => false,
//'last' => false, // Stop validation after this rule
//'on' => 'create', // Limit validation to 'create' or 'update' operations
),
'rule' => array('numeric')
)
),
'published' => array(
'boolean' => array(
@ -254,6 +249,13 @@ class Event extends AppModel {
'message' => 'Please provide a valid UUID'
),
),
'extends_uuid' => array(
'uuid' => array(
'rule' => array('custom', '/^[a-fA-F0-9]{8}-[a-fA-F0-9]{4}-[a-fA-F0-9]{4}-[a-fA-F0-9]{4}-[a-fA-F0-9]{12}$/'),
'message' => 'Please provide a valid UUID',
'allowEmpty' => true
)
)
);
public function __construct($id = false, $table = null, $ds = null) {
@ -1406,7 +1408,7 @@ class Event extends AppModel {
// includeAttachments: true will attach the attachments to the attributes in the data field
public function fetchEvent($user, $options = array(), $useCache = false) {
if (isset($options['Event.id'])) $options['eventid'] = $options['Event.id'];
$possibleOptions = array('eventid', 'idList', 'tags', 'from', 'to', 'last', 'to_ids', 'includeAllTags', 'includeAttachments', 'event_uuid', 'distribution', 'sharing_group_id', 'disableSiteAdmin', 'metadata', 'includeGalaxy', 'enforceWarninglist', 'sgReferenceOnly', 'flatten', 'blockedAttributeTags');
$possibleOptions = array('eventid', 'idList', 'tags', 'from', 'to', 'last', 'to_ids', 'includeAllTags', 'includeAttachments', 'event_uuid', 'distribution', 'sharing_group_id', 'disableSiteAdmin', 'metadata', 'includeGalaxy', 'enforceWarninglist', 'sgReferenceOnly', 'flatten', 'blockedAttributeTags', 'eventsExtendingUuid', 'extended');
if (!isset($options['excludeGalaxy']) || !$options['excludeGalaxy']) {
$this->GalaxyCluster = ClassRegistry::init('GalaxyCluster');
}
@ -1416,6 +1418,33 @@ class Event extends AppModel {
} else {
$conditions = array();
}
if ($options['eventsExtendingUuid']) {
if (!is_array($options['eventsExtendingUuid'])) {
$options['eventsExtendingUuid'] = array($options['eventsExtendingUuid']);
}
foreach ($options['eventsExtendingUuid'] as $extendedEvent) {
$extendedUuids = array();
if (!Validation::uuid($extendedEvent)) {
$eventUuid = $this->find('first', array(
'recursive' => -1,
'conditions' => array('Event.id' => $extendedEvent),
'fields' => array('Event.uuid')
));
if (!empty($eventUuid)) {
$extendedUuids[] = $eventUuid['Event']['uuid'];
}
} else {
$extendedUuids[] = $extendedEvent;
}
}
if (!empty($extendedUuids)) {
$conditions['AND'][] = array('Event.extends_uuid' => $extendedUuids);
} else {
// We've set as a search pattern any event that extends an event and didn't find anything
// valid, make sure we don't get everything thrown in our face that the user can see.
$conditions['AND'][] = array('Event.id' => -1);
}
}
if (!isset($user['org_id'])) {
throw new Exception('There was an error with the user account.');
}
@ -1532,7 +1561,7 @@ class Event extends AppModel {
// $conditions['AND'][] = array('Event.published =' => 1);
// do not expose all the data ...
$fields = array('Event.id', 'Event.orgc_id', 'Event.org_id', 'Event.date', 'Event.threat_level_id', 'Event.info', 'Event.published', 'Event.uuid', 'Event.attribute_count', 'Event.analysis', 'Event.timestamp', 'Event.distribution', 'Event.proposal_email_lock', 'Event.user_id', 'Event.locked', 'Event.publish_timestamp', 'Event.sharing_group_id', 'Event.disable_correlation');
$fields = array('Event.id', 'Event.orgc_id', 'Event.org_id', 'Event.date', 'Event.threat_level_id', 'Event.info', 'Event.published', 'Event.uuid', 'Event.attribute_count', 'Event.analysis', 'Event.timestamp', 'Event.distribution', 'Event.proposal_email_lock', 'Event.user_id', 'Event.locked', 'Event.publish_timestamp', 'Event.sharing_group_id', 'Event.disable_correlation', 'Event.extends_uuid');
$fieldsAtt = array('Attribute.id', 'Attribute.type', 'Attribute.category', 'Attribute.value', 'Attribute.to_ids', 'Attribute.uuid', 'Attribute.event_id', 'Attribute.distribution', 'Attribute.timestamp', 'Attribute.comment', 'Attribute.sharing_group_id', 'Attribute.deleted', 'Attribute.disable_correlation', 'Attribute.object_id', 'Attribute.object_relation');
$fieldsObj = array('*');
$fieldsShadowAtt = array('ShadowAttribute.id', 'ShadowAttribute.type', 'ShadowAttribute.category', 'ShadowAttribute.value', 'ShadowAttribute.to_ids', 'ShadowAttribute.uuid', 'ShadowAttribute.event_uuid', 'ShadowAttribute.event_id', 'ShadowAttribute.old_id', 'ShadowAttribute.comment', 'ShadowAttribute.org_id', 'ShadowAttribute.proposal_to_delete', 'ShadowAttribute.timestamp');
@ -1783,9 +1812,35 @@ class Event extends AppModel {
$event['Event']['event_creator_email'] = $UserEmail;
}
}
if ($options['extended']) {
foreach ($results as $k => $result) {
$results[$k] = $this->__mergeExtensions($user, $result['Event']['uuid'], $result);
}
}
return $results;
}
private function __mergeExtensions($user, $uuid, $event) {
$extensions = $this->fetchEvent($user, array('eventsExtendingUuid' => $uuid));
$thingsToMerge = array('Attribute', 'Object', 'ShadowAttribute', 'EventTag', 'Galaxy', 'RelatedEvent');
foreach ($extensions as $k2 => $extensionEvent) {
$eventMeta = array(
'id' => $extensionEvent['Event']['id'],
'info' => $extensionEvent['Event']['info'],
'Orgc' => array(
'id' => $extensionEvent['Orgc']['id'],
'name' => $extensionEvent['Orgc']['name'],
'uuid' => $extensionEvent['Orgc']['uuid']
)
);
$event['Event']['extensionEvents'][$eventMeta['id']] = $eventMeta;
foreach ($thingsToMerge as $thingToMerge) {
$event[$thingToMerge] = array_merge($event[$thingToMerge], $extensionEvent[$thingToMerge]);
}
}
return $event;
}
private function __attachSharingGroups($doAttach, $data, $sharingGroupData) {
foreach ($data as $k => $v) {
if ($v['distribution'] == 4) {
@ -2537,7 +2592,8 @@ class Event extends AppModel {
'distribution',
'sharing_group_id',
'locked',
'disable_correlation'
'disable_correlation',
'extends_uuid'
),
'Attribute' => array(
'event_id',
@ -2725,7 +2781,8 @@ class Event extends AppModel {
'distribution',
'timestamp',
'sharing_group_id',
'disable_correlation'
'disable_correlation',
'extends_uuid'
);
$saveResult = $this->save(array('Event' => $data['Event']), array('fieldList' => $fieldList));
$this->Log = ClassRegistry::init('Log');

View File

@ -2,6 +2,11 @@
$tr_class = '';
$linkClass = 'blue';
$otherColour = 'blue';
if ($event['Event']['id'] != $object['event_id']) {
if (!$isSiteAdmin && $event['extensionEvents'][$object['event_id']]['Orgc']['id'] != $me['org_id']) {
$mayModify = false;
}
}
$editScope = ($isSiteAdmin || $mayModify) ? 'Attribute' : 'ShadowAttribute';
if (!empty($child)) {
if ($child === 'last' && empty($object['ShadowAttribute'])) {
@ -27,10 +32,16 @@
?>
<tr id = "Attribute_<?php echo h($object['id']); ?>_tr" class="<?php echo $tr_class; ?>" tabindex="0">
<?php
if ($mayModify):
if ($mayModify || $extended):
?>
<td style="width:10px;" data-position="<?php echo h($object['objectType']) . '_' . h($object['id']); ?>">
<input id = "select_<?php echo $object['id']; ?>" class="select_attribute row_checkbox" type="checkbox" data-id="<?php echo $object['id'];?>" />
<?php
if ($mayModify):
?>
<input id = "select_<?php echo $object['id']; ?>" class="select_attribute row_checkbox" type="checkbox" data-id="<?php echo $object['id'];?>" />
<?php
endif;
?>
</td>
<?php
endif;
@ -44,7 +55,26 @@
<td class="short">
<?php echo date('Y-m-d', $object['timestamp']); ?>
</td>
<?php
if ($extended):
?>
<td class="short">
<?php echo '<a href="' . $baseurl . '/events/view/' . h($object['event_id']) . '">' . h($object['event_id']) . '</a>'; ?>
</td>
<?php
endif;
?>
<td class="short">
<?php
if ($extended):
if ($object['event_id'] != $event['Event']['id']):
$extensionOrg = $event['extensionEvents'][$object['event_id']]['Orgc'];
echo $this->OrgImg->getOrgImg(array('name' => $extensionOrg['name'], 'id' => $extensionOrg['id'], 'size' => 24));
else:
echo $this->OrgImg->getOrgImg(array('name' => $event['Orgc']['name'], 'id' => $event['Orgc']['id'], 'size' => 24));
endif;
endif;
?>
&nbsp;
</td>
<td class="short">

View File

@ -3,6 +3,11 @@
$linkClass = 'white';
$currentType = 'denyForm';
$tr_class = 'tableHighlightBorderTop borderBlue';
if ($event['Event']['id'] != $object['event_id']) {
if (!$isSiteAdmin && $event['extensionEvents'][$object['event_id']]['Orgc']['id'] != $me['org_id']) {
$mayModify = false;
}
}
if ($object['deleted']) $tr_class .= ' lightBlueRow';
else $tr_class .= ' blueRow';
if (!empty($k)) {
@ -11,10 +16,16 @@
?>
<tr id = "Object_<?php echo $object['id']; ?>_tr" class="<?php echo $tr_class; ?>" tabindex="0">
<?php
if ($mayModify):
if ($mayModify || $extended):
?>
<td style="width:10px;" data-position="<?php echo h($object['objectType']) . '_' . h($object['id']); ?>">
<input id = "select_object_<?php echo $object['id']; ?>" class="select_object row_checkbox" type="checkbox" data-id="<?php echo $object['id'];?>" />
<?php
if ($mayModify):
?>
<input id = "select_object_<?php echo $object['id']; ?>" class="select_object row_checkbox" type="checkbox" data-id="<?php echo $object['id'];?>" />
<?php
endif;
?>
</td>
<?php
endif;
@ -25,9 +36,31 @@
<td class="short context hidden">
<?php echo h($object['uuid']); ?>
</td>
<td class="short" colspan="2">
<td class="short">
<?php echo date('Y-m-d', $object['timestamp']); ?>
</td>
<?php
if ($extended):
?>
<td class="short">
<?php echo '<a href="' . $baseurl . '/events/view/' . h($object['event_id']) . '" class="white">' . h($object['event_id']) . '</a>'; ?>
</td>
<?php
endif;
?>
<td class="short">
<?php
if ($extended):
if ($object['event_id'] != $event['Event']['id']):
$extensionOrg = $event['extensionEvents'][$object['event_id']]['Orgc'];
echo $this->OrgImg->getOrgImg(array('name' => $extensionOrg['name'], 'id' => $extensionOrg['id'], 'size' => 24));
else:
echo $this->OrgImg->getOrgImg(array('name' => $event['Orgc']['name'], 'id' => $event['Orgc']['id'], 'size' => 24));
endif;
endif;
?>
&nbsp;
</td>
<td colspan="4">
<span class="bold"><?php echo __('Name: ');?></span><?php echo h($object['name']);?>
<span class="fa fa-expand useCursorPointer" title="<?php echo __('Expand or Collapse');?>" role="button" tabindex="0" aria-label="<?php echo __('Expand or Collapse');?>" data-toggle="collapse" data-target="#Object_<?php echo h($object['id']); ?>_collapsible"></span>

View File

@ -22,7 +22,18 @@
<?php
endif;
?>
<span class="fa fa-plus-square useCursorPointer" title="<?php echo __('Add reference');?>" role="button" tabindex="0" aria-label="<?php echo __('Add reference');?>" onClick="genericPopup('<?php echo '/objectReferences/add/' . h($object['id']);?>', '#popover_form');"></span>
<?php
if ($event['Event']['id'] != $object['event_id']) {
if (!$isSiteAdmin && $event['extensionEvents'][$object['event_id']]['Orgc']['id'] != $me['org_id']) {
$mayModify = false;
}
}
if ($mayModify):
?>
<span class="fa fa-plus-square useCursorPointer" title="<?php echo __('Add reference');?>" role="button" tabindex="0" aria-label="<?php echo __('Add reference');?>" onClick="genericPopup('<?php echo '/objectReferences/add/' . h($object['id']);?>', '#popover_form');"></span>
<?php
endif;
?>
<div id="Object_<?php echo $object['id']; ?>_references_collapsible" class="collapse">
<?php
foreach ($object['ObjectReference'] as $reference):

View File

@ -2,6 +2,11 @@
$tr_class = 'darkOrangeRow';
$linkClass = 'white';
$currentType = 'denyForm';
if ($event['Event']['id'] != $object['event_id']) {
if (!$isSiteAdmin && $event['extensionEvents'][$object['event_id']]['Orgc']['id'] != $me['org_id']) {
$mayModify = false;
}
}
if (!empty($objectContainer)) {
if (!empty($child)) {
if ($child === 'last') {
@ -52,12 +57,21 @@
?>
</div>
</td>
<?php
if ($extended):
?>
<td class="short">
<?php echo '<a href="' . $baseurl . '/events/view/' . h($object['event_id']) . '" class="white">' . h($object['event_id']) . '</a>'; ?>
</td>
<?php
endif;
?>
<td class="short">
<?php
<?php
if (isset($object['Org']['name'])) {
echo $this->OrgImg->getOrgImg(array('name' => $object['Org']['name'], 'id' => $object['Org']['id'], 'size' => 24));
}
?>
?>
</td>
<td class="short">
<div id = "<?php echo $currentType . '_' . $object['id'] . '_category_placeholder'; ?>" class = "inline-field-placeholder"></div>

View File

@ -50,7 +50,24 @@
<td class="short context hidden">
<?php echo h($object['uuid']); ?>
</td>
<td colspan="<?php echo $fieldCount+2; ?>" style="font-weight:bold;text-align:left;width:100%;">DELETE</td>
<td style="font-weight:bold;text-align:left;">DELETE</td>
<?php
if ($extended):
?>
<td class="short">
<?php echo '<a href="' . $baseurl . '/events/view/' . h($object['event_id']) . '" class="white">' . h($object['event_id']) . '</a>'; ?>
</td>
<?php
endif;
?>
<td class="short">
<?php
if (isset($object['Org']['name'])) {
echo $this->OrgImg->getOrgImg(array('name' => $object['Org']['name'], 'id' => $object['Org']['id'], 'size' => 24));
}
?>
</td>
<td colspan="<?php echo $fieldCount; ?>">&nbsp;</td>
<td class="short action-links">
<?php
if (($event['Orgc']['id'] == $me['org_id'] && $mayModify) || $isSiteAdmin) {

View File

@ -120,12 +120,20 @@
<span id="attribute-replace-button" title="Replace all attributes of a category/type combination within the event" role="button" tabindex="0" aria-label="Replace all attributes of a category/type combination within the event" class="icon-random useCursorPointer" onClick="getPopup(<?php echo $event['Event']['id']; ?>, 'attributes', 'attributeReplace');"></span>
<?php endif; ?>
</div>
<?php
$target = h($event['Event']['id']);
if ($extended) $target .= '/extended:1';
?>
<div class="tabMenu tabMenuFiltersBlock noPrint" style="padding-right:0px !important;">
<span id="filter_header" class="attribute_filter_header">Filters: </span>
<div id="filter_all" title="Show all attributes" role="button" tabindex="0" aria-label="Show all attributes" class="attribute_filter_text<?php if ($attributeFilter == 'all') echo '_active'; ?>" onClick="filterAttributes('all', '<?php echo h($event['Event']['id']); ?>');">All</div>
<?php foreach ($typeGroups as $group): ?>
<div id="filter_<?php echo h($group); ?>" title="Only show <?php echo $group; ?> related attributes" role="button" tabindex="0" aria-label="Only show <?php echo h($group); ?> related attributes" class="attribute_filter_text<?php if ($attributeFilter == $group) echo '_active'; ?>" onClick="filterAttributes('<?php echo $group; ?>', '<?php echo h($event['Event']['id']); ?>');"><?php echo ucfirst($group); ?></div>
<?php endforeach; ?>
<div id="filter_all" title="Show all attributes" role="button" tabindex="0" aria-label="Show all attributes" class="attribute_filter_text<?php if ($attributeFilter == 'all') echo '_active'; ?>" onClick="filterAttributes('all', '<?php echo $target; ?>');">All</div>
<?php
foreach ($typeGroups as $group):
?>
<div id="filter_<?php echo h($group); ?>" title="Only show <?php echo $group; ?> related attributes" role="button" tabindex="0" aria-label="Only show <?php echo h($group); ?> related attributes" class="attribute_filter_text<?php if ($attributeFilter == $group) echo '_active'; ?>" onClick="filterAttributes('<?php echo $group; ?>', '<?php echo $target; ?>');"><?php echo ucfirst($group); ?></div>
<?php
endforeach;
?>
<div id="filter_proposal" title="Only show proposals" role="button" tabindex="0" aria-label="Only show proposals" class="attribute_filter_text<?php if ($attributeFilter == 'proposal') echo '_active'; ?>" onClick="filterAttributes('proposal', '<?php echo h($event['Event']['id']); ?>');">Proposal</div>
<div id="filter_correlation" title="Only show correlating attributes" role="button" tabindex="0" aria-label="Only show correlating attributes" class="attribute_filter_text<?php if ($attributeFilter == 'correlation') echo '_active'; ?>" onClick="filterAttributes('correlation', '<?php echo h($event['Event']['id']); ?>');">Correlation</div>
<div id="filter_warning" title="Only show potentially false positive attributes" role="button" tabindex="0" aria-label="Only show potentially false positive attributes" class="attribute_filter_text<?php if ($attributeFilter == 'warning') echo '_active'; ?>" onClick="filterAttributes('warning', '<?php echo h($event['Event']['id']); ?>');">Warnings</div>
@ -145,7 +153,7 @@
<table class="table table-striped table-condensed">
<tr>
<?php
if ($mayModify && !empty($event['objects'])):
if ($extended || ($mayModify && !empty($event['objects']))):
$fieldCount += 1;
?>
<th><input class="select_all" type="checkbox" title="Select all" role="button" tabindex="0" aria-label="Select all attributes/proposals on current page" onClick="toggleAllAttributeCheckboxes();" /></th>
@ -155,6 +163,13 @@
<th class="context hidden"><?php echo $this->Paginator->sort('id');?></th>
<th class="context hidden">UUID</th>
<th><?php echo $this->Paginator->sort('timestamp', 'Date');?></th>
<?php
if ($extended):
?>
<th class="event_id"><?php echo $this->Paginator->sort('event_id', 'Event');?></th>
<?php
endif;
?>
<th><?php echo $this->Paginator->sort('Org.name', 'Org'); ?>
<th><?php echo $this->Paginator->sort('category');?></th>
<th><?php echo $this->Paginator->sort('type');?></th>

View File

@ -48,6 +48,12 @@
'class' => 'form-control span6',
'placeholder' => __('Quick Event Description or Tracking Info')
));
echo $this->Form->input('extends_uuid', array(
'label' => __('Extends event'),
'div' => 'clear',
'class' => 'form-control span6',
'placeholder' => __('Event UUID or ID. Leave blank if not applicable.')
));
echo $this->Form->input('Event.submittedgfi', array(
'label' => '<b>GFI sandbox</b>',
'type' => 'file',

View File

@ -46,7 +46,12 @@ $mayPublish = ($isAclPublish && $event['Event']['orgc_id'] == $me['org_id']);
'class' => 'form-control span6',
'placeholder' => __('Quick Event Description or Tracking Info')
));
echo $this->Form->input('extends_uuid', array(
'label' => __('Extends event'),
'div' => 'clear',
'class' => 'form-control span6',
'placeholder' => __('Event UUID or ID. Leave blank if not applicable.')
));
?>
</fieldset>
<?php

View File

@ -46,7 +46,7 @@
?>
<div class="row-fluid">
<div class="span8">
<h2><?php echo nl2br($title); ?></h2>
<h2><?php echo ($extended ? '[' . __('Extended view') . '] ' : '') . nl2br($title); ?></h2>
<dl>
<dt><?php echo __('Event ID');?></dt>
<dd>
@ -169,6 +169,28 @@
<?php echo date('Y/m/d h:i:s', $event['Event']['timestamp']);; ?>
&nbsp;
</dd>
<dt><?php echo __('Extends');?></dt>
<dd style="word-wrap: break-word;">
<?php
if (!empty($extendedEvent)) {
echo sprintf('<span>%s (<a href="%s">%s</a>): %s</span>', __('Event'), $baseurl . '/events/view/' . h($extendedEvent[0]['Event']['id']), h($extendedEvent[0]['Event']['id']), h($extendedEvent[0]['Event']['info']));
echo '&nbsp;<a href="' . $baseurl . '/events/view/' . $extendedEvent[0]['Event']['id'] . '/extended:1"><span class="icon-search"></span></a>';
} else {
echo h($event['Event']['extends_uuid']);
}
?>&nbsp;
</dd>
<dt><?php echo __('Extended by');?></dt>
<dd style="word-wrap: break-word;">
<?php
foreach ($extensions as $extension) {
echo sprintf('<span>%s (<a href="%s">%s</a>): %s</span>', __('Event'), $baseurl . '/events/view/' . h($extension['Event']['id']), h($extension['Event']['id']), h($extension['Event']['info'])) . '<br />';
}
if (!empty($extensions)) {
echo __('Currently in ' . ($extended ? 'extended' : 'atomic') . ' view.') . ' <a href="' . $baseurl . '/events/view/' . $event['Event']['id'] . ($extended ? '' : '/extended:1') . '"><span class="icon-refresh"></span></a>';
}
?>&nbsp;
</dd>
<dt><?php echo __('Sightings');?></dt>
<dd style="word-wrap: break-word;">
<span id="eventSightingCount" class="bold sightingsCounter" data-toggle="popover" data-trigger="hover" data-content="<?php echo $sightingPopover; ?>"><?php echo count($event['Sighting']); ?></span>