mirror of https://github.com/MISP/MISP
Fixed an issue with the free-text import failing on more than ~100 parsed values, fixes #389
- Caused by a 1k variable / form limit imposed by php since 5.3.9 - Form data now collected by JS and passed as a single JSON in the POST request - Allows massive IOC lists to be imported - improved performancepull/400/head
parent
d89a266c85
commit
701160acd9
|
@ -2860,24 +2860,23 @@ class EventsController extends AppController {
|
|||
if (!$this->_isSiteAdmin() && !empty($event) && $event['Event']['orgc'] != $this->Auth->user('org')) throw new MethodNotAllowedException('Event not found or you don\'t have permissions to create attributes');
|
||||
$saved = 0;
|
||||
$failed = 0;
|
||||
foreach ($this->request->data['Attribute'] as $k => $attribute) {
|
||||
if ($attribute['save'] == '1') {
|
||||
if ($attribute['type'] == 'ip-src/ip-dst') {
|
||||
$types = array('ip-src', 'ip-dst');
|
||||
$attributes = json_decode($this->request->data['Attribute']['JsonObject'], true);
|
||||
foreach ($attributes as $k => $attribute) {
|
||||
if ($attribute['type'] == 'ip-src/ip-dst') {
|
||||
$types = array('ip-src', 'ip-dst');
|
||||
} else {
|
||||
$types = array($attribute['type']);
|
||||
}
|
||||
foreach ($types as $type) {
|
||||
$this->Event->Attribute->create();
|
||||
$attribute['type'] = $type;
|
||||
$attribute['distribution'] = $event['Event']['distribution'];
|
||||
if (empty($attribute['comment'])) $attribute['comment'] = 'Imported via the freetext import.';
|
||||
$attribute['event_id'] = $id;
|
||||
if ($this->Event->Attribute->save($attribute)) {
|
||||
$saved++;
|
||||
} else {
|
||||
$types = array($attribute['type']);
|
||||
}
|
||||
foreach ($types as $type) {
|
||||
$this->Event->Attribute->create();
|
||||
$attribute['type'] = $type;
|
||||
$attribute['distribution'] = $event['Event']['distribution'];
|
||||
if (empty($attribute['comment'])) $attribute['comment'] = 'Imported via the freetext import.';
|
||||
$attribute['event_id'] = $id;
|
||||
if ($this->Event->Attribute->save($attribute)) {
|
||||
$saved++;
|
||||
} else {
|
||||
$failed++;
|
||||
}
|
||||
$failed++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,6 +1,16 @@
|
|||
<div class="index">
|
||||
<h2>Freetext Import Results</h2>
|
||||
<p>Below you can see the attributes that are to be created based on the results of the free-text import. Make sure that the categories and the types are correct, often several options will be offered based on an inconclusive automatic resolution. </p>
|
||||
<?php
|
||||
echo $this->Form->create('Attribute', array('url' => '/events/saveFreeText/' . $event_id));
|
||||
echo $this->Form->input('JsonObject', array(
|
||||
'label' => false,
|
||||
'type' => 'text',
|
||||
'style' => 'display:none;',
|
||||
'value' => '',
|
||||
));
|
||||
echo $this->Form->end();
|
||||
?>
|
||||
<table class="table table-striped table-hover table-condensed">
|
||||
<tr>
|
||||
<th>Value</th>
|
||||
|
@ -12,23 +22,25 @@
|
|||
</tr>
|
||||
<?php
|
||||
$options = array();
|
||||
echo $this->Form->create('Attribute', array('url' => '/events/saveFreeText/' . $event_id));
|
||||
foreach ($resultArray as $k => $item):
|
||||
?>
|
||||
<tr id="row_<?php echo $k; ?>" class="freetext_row">
|
||||
<?php
|
||||
echo $this->Form->input('Attribute.' . $k . '.save', array(
|
||||
echo $this->Form->input('Attribute' . $k . 'Save', array(
|
||||
'label' => false,
|
||||
'style' => 'display:none;',
|
||||
'value' => 1,
|
||||
));
|
||||
echo $this->Form->input('Attribute.' . $k . '.value', array(
|
||||
echo $this->Form->input('Attribute' . $k . 'Value', array(
|
||||
'label' => false,
|
||||
'type' => 'hidden',
|
||||
'value' => h($item['value']),
|
||||
));
|
||||
?>
|
||||
<td><?php echo h($item['value']); ?></td>
|
||||
<td>
|
||||
<input type="hidden" id="<?php echo 'Attribute' . $k . 'Save'; ?>" value=1 >
|
||||
<div id="<?php echo 'Attribute' . $k . 'Value'; ?>"><?php echo h($item['value']); ?></div>
|
||||
</td>
|
||||
<td class="short">
|
||||
<?php
|
||||
if (!isset($item['category'])) {
|
||||
|
@ -36,53 +48,43 @@
|
|||
} else {
|
||||
$default = array_search($item['category'], $typeCategoryMapping[$item['default_type']]);
|
||||
}
|
||||
echo $this->Form->input('Attribute.' . $k . '.category', array(
|
||||
'label' => false,
|
||||
'style' => 'padding:0px;height:20px;margin-bottom:0px;',
|
||||
'options' => $typeCategoryMapping[$item['default_type']],
|
||||
'value' => $default,
|
||||
));
|
||||
?>
|
||||
<select id="<?php echo 'Attribute' . $k . 'Category'; ?>" style='padding:0px;height:20px;margin-bottom:0px;'>
|
||||
<?php
|
||||
foreach ($typeCategoryMapping[$item['default_type']] as $type) {
|
||||
echo '<option value="' . $type . '" ';
|
||||
if ($type == $default) echo 'selected="selected"';
|
||||
echo '>' . $type . '</option>';
|
||||
}
|
||||
?>
|
||||
</select>
|
||||
</td>
|
||||
<td class="short">
|
||||
<?php
|
||||
$divVisibility = '';
|
||||
$selectVisibility = '';
|
||||
if (count($item['types']) == 1) {
|
||||
echo h($item['default_type']);
|
||||
echo $this->Form->input('Attribute.' . $k . '.type', array(
|
||||
'label' => false,
|
||||
'type' => 'hidden',
|
||||
'value' => $item['default_type'],
|
||||
));
|
||||
$selectVisibility = 'display:none;';
|
||||
} else {
|
||||
echo $this->Form->input('Attribute.' . $k . '.type', array(
|
||||
'label' => false,
|
||||
'style' => 'padding:0px;height:20px;margin-bottom:0px;',
|
||||
'options' => $item['types'],
|
||||
'value' => $item['default_type'],
|
||||
'class' => 'typeToggle',
|
||||
));
|
||||
if (!in_array(array_keys($item['types']), $options)) $options[] = array_keys($item['types']);
|
||||
$divVisibility = 'style="display:none;"';
|
||||
if (!in_array(array_keys($item['types']), $options)) $options[] = array_keys($item['types']);
|
||||
}
|
||||
?>
|
||||
<div id = "<?php echo 'Attribute' . $k . 'TypeStatic'; ?>" <?php echo $divVisibility; ?> ><?php echo h($item['default_type']); ?></div>
|
||||
<select id = "<?php echo 'Attribute' . $k . 'Type'; ?>" class='typeToggle' style='padding:0px;height:20px;margin-bottom:0px;<?php echo $selectVisibility; ?>'>
|
||||
<?php
|
||||
foreach ($item['types'] as $type) {
|
||||
echo '<option value="' . $type . '" ';
|
||||
echo ($type == $item['default_type'] ? 'selected="selected"' : '') . '>' . $type . '</option>';
|
||||
}
|
||||
?>
|
||||
</select>
|
||||
</td>
|
||||
<td class="short" style="width:30px;">
|
||||
<?php
|
||||
echo $this->Form->input('Attribute.' . $k . '.to_ids', array(
|
||||
'label' => false,
|
||||
'type' => 'checkbox',
|
||||
'checked' => $item['to_ids'],
|
||||
));
|
||||
?>
|
||||
<input type="checkbox" id="<?php echo 'Attribute' . $k . 'To_ids'; ?>" <?php if ($item['to_ids']) echo 'checked'; ?>/>
|
||||
</td>
|
||||
<td class="short">
|
||||
<?php
|
||||
echo $this->Form->input('Attribute.' . $k . '.comment', array(
|
||||
'label' => false,
|
||||
'style' => 'padding:0px;height:20px;margin-bottom:0px;',
|
||||
'type' => 'text',
|
||||
'placeholder' => 'Imported via the freetext import.',
|
||||
));
|
||||
?>
|
||||
<input type="text" id="<?php echo 'Attribute' . $k . 'Comment'; ?>" style="padding:0px;height:20px;margin-bottom:0px;" placeholder="Imported via the freetext import." />
|
||||
</td>
|
||||
<td class="action short">
|
||||
<span class="icon-remove pointer" onClick="freetextRemoveRow('<?php echo $k; ?>', '<?php echo $event_id; ?>');"></span>
|
||||
|
@ -101,9 +103,8 @@
|
|||
}
|
||||
?>
|
||||
</table>
|
||||
<button class="btn btn-primary" onClick="freetextImportResultsSubmit('<?php echo h($event_id); ?>', '<?php echo count($resultArray); ?>');">Submit</button>
|
||||
<?php
|
||||
echo $this->Form->button('Submit', array('class' => 'btn btn-primary'));
|
||||
echo $this->Form->end();
|
||||
if (!empty($optionsRearranged)):
|
||||
?>
|
||||
<span style="float:right">
|
||||
|
|
|
@ -1292,13 +1292,22 @@ function changeFreetextImportExecute() {
|
|||
var to = $('#changeTo').val();
|
||||
$('.typeToggle').each(function() {
|
||||
if ($( this ).val() == from) {
|
||||
if ($('#' + $(this).attr('id') + " option[value='" + from + "']").length > 0) {
|
||||
$( this ).val(to);
|
||||
}
|
||||
if (selectContainsOption("#" + $(this).attr('id'), to)) $( this ).val(to);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
function selectContainsOption(selectid, value) {
|
||||
var exists = false;
|
||||
$(selectid + ' option').each(function(){
|
||||
if (this.value == value) {
|
||||
exists = true;
|
||||
return false;
|
||||
}
|
||||
});
|
||||
return exists;
|
||||
}
|
||||
|
||||
function exportChoiceSelect(url, elementId, checkbox) {
|
||||
if (checkbox == 1) {
|
||||
if ($('#' + elementId + '_toggle').prop('checked')) {
|
||||
|
@ -1306,4 +1315,38 @@ function exportChoiceSelect(url, elementId, checkbox) {
|
|||
}
|
||||
}
|
||||
document.location.href = url;
|
||||
}
|
||||
}
|
||||
|
||||
function freetextImportResultsSubmit(id, count) {
|
||||
var attributeArray = [];
|
||||
var temp;
|
||||
for (i = 0; i < count; i++) {
|
||||
if ($('#Attribute' + i + 'Save').val() == 1) {
|
||||
temp = {
|
||||
value:$('#Attribute' + i + 'Value').val(),
|
||||
category:$('#Attribute' + i + 'Category').val(),
|
||||
type:$('#Attribute' + i + 'Type').val(),
|
||||
to_ids:$('#Attribute' + i + 'To_ids')[0].checked,
|
||||
comment:$('#Attribute' + i + 'Comment').val(),
|
||||
}
|
||||
attributeArray[attributeArray.length] = temp;
|
||||
}
|
||||
}
|
||||
$("#AttributeJsonObject").val(JSON.stringify(attributeArray));
|
||||
var formData = $("#AttributeFreeTextImportForm").serialize();
|
||||
$.ajax({
|
||||
type: "post",
|
||||
cache: false,
|
||||
url: "/events/saveFreeText/" + id,
|
||||
data: formData,
|
||||
beforeSend: function (XMLHttpRequest) {
|
||||
$(".loading").show();
|
||||
},
|
||||
success:function (data, textStatus) {
|
||||
window.location = '/events/view/' + id;
|
||||
},
|
||||
complete:function() {
|
||||
$(".loading").hide();
|
||||
},
|
||||
});
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue