mirror of https://github.com/MISP/MISP
new: [object] Allows updating from an unknown object templates
parent
b6f5844350
commit
a7834a291b
|
@ -376,13 +376,14 @@ class ObjectsController extends AppController
|
|||
'ObjectTemplateElement'
|
||||
)
|
||||
));
|
||||
if (empty($template) && !$this->_isRest()) {
|
||||
$this->Flash->error('Object cannot be edited, no valid template found.');
|
||||
if (empty($template) && !$this->_isRest() && !$update_template_available) {
|
||||
$this->Flash->error('Object cannot be edited, no valid template found. ', ['params' => ['url' => sprintf('/objects/edit/%s/1/0', $id), 'urlName' => __('Force update anyway')]]);
|
||||
$this->redirect(array('controller' => 'events', 'action' => 'view', $object['Object']['event_id']));
|
||||
}
|
||||
$templateData = $this->MispObject->resolveUpdatedTemplate($template, $object, $update_template_available);
|
||||
$this->set('updateable_attribute', $templateData['updateable_attribute']);
|
||||
$this->set('not_updateable_attribute', $templateData['not_updateable_attribute']);
|
||||
$this->set('original_template_unkown', $templateData['original_template_unkown']);
|
||||
if (!empty($this->Session->read('object_being_created')) && !empty($this->params['named']['cur_object_tmp_uuid'])) {
|
||||
$revisedObjectData = $this->Session->read('object_being_created');
|
||||
if ($this->params['named']['cur_object_tmp_uuid'] == $revisedObjectData['cur_object_tmp_uuid']) { // ensure that the passed session data is for the correct object
|
||||
|
|
|
@ -1233,64 +1233,90 @@ class MispObject extends AppModel
|
|||
'updateable_attribute' => false,
|
||||
'not_updateable_attribute' => false,
|
||||
'newer_template_version' => false,
|
||||
'original_template_unkown' => false,
|
||||
'template' => $template
|
||||
);
|
||||
if (!empty($template)) {
|
||||
$newer_template = $this->ObjectTemplate->find('first', array(
|
||||
'conditions' => array(
|
||||
'ObjectTemplate.uuid' => $object['Object']['template_uuid'],
|
||||
'ObjectTemplate.version >' => $object['Object']['template_version'],
|
||||
),
|
||||
'recursive' => -1,
|
||||
'contain' => array(
|
||||
'ObjectTemplateElement'
|
||||
),
|
||||
'order' => array('ObjectTemplate.version DESC')
|
||||
));
|
||||
if (!empty($newer_template)) {
|
||||
$toReturn['newer_template_version'] = $newer_template['ObjectTemplate']['version'];
|
||||
// ignore IDs for comparison
|
||||
$cur_template_temp = Hash::remove(Hash::remove($template['ObjectTemplateElement'], '{n}.id'), '{n}.object_template_id');
|
||||
$newer_template_temp = Hash::remove(Hash::remove($newer_template['ObjectTemplateElement'], '{n}.id'), '{n}.object_template_id');
|
||||
$newer_template = $this->ObjectTemplate->find('first', array(
|
||||
'conditions' => array(
|
||||
'ObjectTemplate.uuid' => $object['Object']['template_uuid'],
|
||||
'ObjectTemplate.version >' => $object['Object']['template_version'],
|
||||
),
|
||||
'recursive' => -1,
|
||||
'contain' => array(
|
||||
'ObjectTemplateElement'
|
||||
),
|
||||
'order' => array('ObjectTemplate.version DESC')
|
||||
));
|
||||
$template_difference = array();
|
||||
if (!empty($newer_template)) {
|
||||
$toReturn['newer_template_version'] = !$newer_template['ObjectTemplate']['version'];
|
||||
$newer_template_temp = Hash::remove(Hash::remove($newer_template['ObjectTemplateElement'], '{n}.id'), '{n}.object_template_id');
|
||||
if (!empty($template)) {
|
||||
// ignore IDs for comparison
|
||||
$cur_template_temp = Hash::remove(Hash::remove($template['ObjectTemplateElement'], '{n}.id'), '{n}.object_template_id');
|
||||
|
||||
$template_difference = array();
|
||||
// check how current template is included in the newer
|
||||
foreach ($cur_template_temp as $cur_obj_rel) {
|
||||
$flag_sim = false;
|
||||
foreach ($newer_template_temp as $newer_obj_rel) {
|
||||
$tmp = Hash::diff($cur_obj_rel, $newer_obj_rel);
|
||||
if (count($tmp) == 0) {
|
||||
$flag_sim = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!$flag_sim) {
|
||||
$template_difference[] = $cur_obj_rel;
|
||||
}
|
||||
}
|
||||
|
||||
$toReturn['updateable_attribute'] = $object['Attribute'];
|
||||
$toReturn['not_updateable_attribute'] = array();
|
||||
} else {
|
||||
$toReturn['newer_template_version'] = false;
|
||||
}
|
||||
if (!empty($template_difference)) { // older template not completely embeded in newer
|
||||
foreach ($template_difference as $temp_diff_element) {
|
||||
foreach ($object['Attribute'] as $i => $attribute) {
|
||||
if (
|
||||
$attribute['object_relation'] == $temp_diff_element['object_relation']
|
||||
&& $attribute['type'] == $temp_diff_element['type']
|
||||
) { // This attribute cannot be merged automatically
|
||||
$attribute['merge-possible'] = false;
|
||||
$toReturn['not_updateable_attribute'][] = $attribute;
|
||||
unset($toReturn['updateable_attribute'][$i]);
|
||||
// check how current template is included in the newer
|
||||
foreach ($cur_template_temp as $cur_obj_rel) {
|
||||
$flag_sim = false;
|
||||
foreach ($newer_template_temp as $newer_obj_rel) {
|
||||
$tmp = Hash::diff($cur_obj_rel, $newer_obj_rel);
|
||||
if (count($tmp) == 0) {
|
||||
$flag_sim = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!$flag_sim) {
|
||||
$template_difference[] = $cur_obj_rel;
|
||||
}
|
||||
}
|
||||
} else { // original template unkown
|
||||
$toReturn['original_template_unkown'] = true;
|
||||
$unmatched_attributes = array();
|
||||
foreach ($object['Attribute'] as $i => $attribute) {
|
||||
$flag_match = false;
|
||||
foreach ($newer_template_temp as $newer_obj_rel) {
|
||||
if (
|
||||
$newer_obj_rel['object_relation'] == $attribute['object_relation'] &&
|
||||
$newer_obj_rel['type'] == $attribute['type']
|
||||
) {
|
||||
$flag_match = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!$flag_match) {
|
||||
$unmatched_attributes[] = $attribute;
|
||||
}
|
||||
}
|
||||
|
||||
// simulate unkown template from the attribute
|
||||
foreach ($unmatched_attributes as $unmatched_attribute) {
|
||||
$template_difference[] = [
|
||||
'object_relation' => $unmatched_attribute['object_relation'],
|
||||
'type' => $unmatched_attribute['type']
|
||||
];
|
||||
}
|
||||
}
|
||||
$toReturn['updateable_attribute'] = $object['Attribute'];
|
||||
$toReturn['not_updateable_attribute'] = array();
|
||||
} else {
|
||||
$toReturn['newer_template_version'] = false;
|
||||
}
|
||||
if (!empty($template_difference)) { // older template not completely embeded in newer
|
||||
foreach ($template_difference as $temp_diff_element) {
|
||||
foreach ($object['Attribute'] as $i => $attribute) {
|
||||
if (
|
||||
$attribute['object_relation'] == $temp_diff_element['object_relation']
|
||||
&& $attribute['type'] == $temp_diff_element['type']
|
||||
) { // This attribute cannot be merged automatically
|
||||
$attribute['merge-possible'] = false;
|
||||
$toReturn['not_updateable_attribute'][] = $attribute;
|
||||
unset($toReturn['updateable_attribute'][$i]);
|
||||
}
|
||||
}
|
||||
}
|
||||
if ($update_template_available) { // template version bump requested
|
||||
$toReturn['template'] = $newer_template; // bump the template version
|
||||
}
|
||||
}
|
||||
if ($update_template_available) { // template version bump requested
|
||||
$toReturn['template'] = $newer_template; // bump the template version
|
||||
}
|
||||
return $toReturn;
|
||||
}
|
||||
|
|
|
@ -208,7 +208,7 @@
|
|||
<span style="margin-left: 5px; display: inline-block; font-size: large;"><?php echo __('Current Object state on older template version'); ?></span>
|
||||
</div>
|
||||
<div class="row" style="max-height: 800px; max-width: 800px; overflow: auto; padding: 15px;">
|
||||
<div style="border: 1px solid #3465a4 ; border-radius: 5px; overflow: hidden;" class="span5">
|
||||
<div style="border: 1px solid #3465a4 ; border-radius: 5px; overflow: auto;" class="span5">
|
||||
<div class="blueElement" style="padding: 4px 5px;">
|
||||
<div>
|
||||
<span class="bold"><?php echo __('ID') . ':'; ?></span>
|
||||
|
@ -229,9 +229,22 @@
|
|||
<div style="background-color: #fcf8e3; color: black; padding: 2px; border-radius: 3px;">
|
||||
<span class="bold"><?php echo __('Template version') . ':'; ?></span>
|
||||
<span><?php echo h($object['Object']['template_version']); ?></span>
|
||||
<?php if ($original_template_unkown): ?>
|
||||
<span class="label label-important" title="<?= __('The original object\'s template is unkown and some attributes might be lost. Please review carefully'); ?>">
|
||||
<?= __('Unkown original template'); ?>
|
||||
</span>
|
||||
<?php endif; ?>
|
||||
</div>
|
||||
</div>
|
||||
<table class="table table-striped table-condensed" style="margin-bottom: 0px;">
|
||||
<thead>
|
||||
<tr>
|
||||
<th><?= __('Obj. rel.') ?></th>
|
||||
<th><?= __('Categ.') ?></th>
|
||||
<th><?= __('Type') ?></th>
|
||||
<th><?= __('Value') ?></th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<?php foreach ($not_updateable_attribute as $attribute): ?>
|
||||
<tr class="error" title="<?php echo __('Can not be merged automatically'); ?>">
|
||||
|
@ -245,7 +258,7 @@
|
|||
</td>
|
||||
<td><?php echo h($attribute['category']); ?></td>
|
||||
<td><?php echo h($attribute['type']); ?></td>
|
||||
<td><?php echo h($attribute['value']); ?></td>
|
||||
<td style="max-width:100px;" class="ellipsis-overflow"><?php echo h($attribute['value']); ?></td>
|
||||
</tr>
|
||||
<?php if (!$attribute['merge-possible']): ?>
|
||||
<?php
|
||||
|
@ -275,7 +288,7 @@
|
|||
<td style="white-space: nowrap;"><?php echo h($attribute['object_relation']); ?></td>
|
||||
<td><?php echo h($attribute['category']); ?></td>
|
||||
<td><?php echo h($attribute['type']); ?></td>
|
||||
<td><?php echo h($attribute['value']); ?></td>
|
||||
<td style="max-width:100px;" class="ellipsis-overflow"><?php echo h($attribute['value']); ?></td>
|
||||
</tr>
|
||||
<?php endforeach; ?>
|
||||
</tbody>
|
||||
|
@ -401,6 +414,7 @@
|
|||
$value_field.val(revised_value);
|
||||
$clicked.removeClass('fa-sign-in-alt fa-flip-horizontal').addClass('fa-trash-restore');
|
||||
}
|
||||
$matching_row.find('input[type="checkbox"][name$="[save]').first().prop('checked', true).prop('disabled', false)
|
||||
$matching_row[0].scrollIntoView(false);
|
||||
$matching_row.children().effect('highlight', { queue: false, color: $value_field.val() === selected_value ? '#468847' : '#b94a48' }, 2500, function() { $(this).css('background-color', 'unset'); });
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue