new: Several new features

- added multiple flag among other things
pull/2489/head
iglocska 2017-08-29 18:28:18 +02:00
parent c8b0be9431
commit 5552d7c030
15 changed files with 494 additions and 205 deletions

View File

@ -508,6 +508,7 @@ CREATE TABLE IF NOT EXISTS object_templates (
`description` text COLLATE utf8_bin,
`version` int(11) NOT NULL,
`requirements` text COLLATE utf8_bin,
`fixed` tinyint(1) NOT NULL DEFAULT 0,
PRIMARY KEY (id),
INDEX `user_id` (`user_id`),
INDEX `org_id` (`org_id`),
@ -525,8 +526,8 @@ CREATE TABLE IF NOT EXISTS object_templates (
CREATE TABLE IF NOT EXISTS object_template_elements (
`id` int(11) NOT NULL AUTO_INCREMENT,
`object_template_id` int(11) NOT NULL,
`in-object-name` varchar(255) CHARACTER SET utf8 COLLATE utf8_unicode_ci,
`type` varchar(255) CHARACTER SET utf8 COLLATE utf8_unicode_ci,
`object_relation` varchar(255) CHARACTER SET utf8 COLLATE utf8_bin,
`type` varchar(255) CHARACTER SET utf8 COLLATE utf8_bin,
`ui-priority` int(11) NOT NULL,
`categories` text COLLATE utf8_bin,
`sane_default` text COLLATE utf8_bin,
@ -535,7 +536,7 @@ CREATE TABLE IF NOT EXISTS object_template_elements (
`disable_correlations` tinyint(1) NOT NULL DEFAULT 0,
`multiple` tinyint(1) NOT NULL DEFAULT 0,
PRIMARY KEY (id),
INDEX `in-object-name` (`in-object-name`),
INDEX `object_relation` (`object_relation`),
INDEX `type` (`type`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

View File

@ -14,6 +14,51 @@ class ObjectsController extends AppController {
),
);
public function beforeFilter() {
parent::beforeFilter();
$this->Security->unlockedActions = array('revise_object', 'get_row');
}
public function revise_object($action, $event_id, $template_id, $object_id = false) {
if (!$this->request->is('post') && !$this->request->is('put')) {
throw new MethodNotAllowedException('This action can only be reached via POST requests');
}
$this->request->data = $this->MispObject->attributeCleanup($this->request->data);
$eventFindParams = array(
'recursive' => -1,
'fields' => array('Event.id', 'Event.uuid', 'Event.orgc_id'),
'conditions' => array('Event.id' => $event_id)
);
$template = $this->MispObject->ObjectTemplate->find('first', array(
'conditions' => array('ObjectTemplate.id' => $template_id),
'recursive' => -1,
'contain' => array(
'ObjectTemplateElement'
)
));
$event = $this->MispObject->Event->find('first', $eventFindParams);
if (empty($event) || (!$this->_isSiteAdmin() && $event['Event']['orgc_id'] != $this->Auth->user('org_id'))) {
throw new NotFoundException('Invalid event.');
}
if ($this->request->data['Object']['distribution'] == 4) {
$sg = $this->MispObject->SharingGroup->find('first', array(
'conditions' => array('SharingGroup.id' => $this->request->data['Object']['sharing_group_id']),
'recursive' => -1,
'fields' => array('SharingGroup.id', 'SharingGroup.name'),
'order' => false
));
if (empty($sg)) throw new NotFoundException('Invalid sharing group.');
$this->set('sg', $sg);
}
$this->set('distributionLevels', $this->MispObject->Attribute->distributionLevels);
$this->set('action', $action);
$this->set('template', $template);
$this->set('object_id', $object_id);
$this->set('event', $event);
$this->set('data', $this->request->data);
}
/**
* Create an object using a template
* POSTing will take the input and validate it against the template
@ -55,6 +100,9 @@ class ObjectsController extends AppController {
if (isset($this->request->data['request'])) {
$this->request->data = $this->request->data['request'];
}
if (isset($this->request->data['Object']['data'])) {
$this->request->data = json_decode($this->request->data['Object']['data'], true);
}
if (!isset($this->request->data['Attribute'])) {
$this->request->data = array('Attribute' => $this->request->data);
}
@ -64,7 +112,7 @@ class ObjectsController extends AppController {
$this->request->data = array('Object' => $this->request->data);
$this->request->data['Attribute'] = $attributeTemp;
unset($attributeTemp);
}
}
$object = $this->MispObject->attributeCleanup($this->request->data);
// we pre-validate the attributes before we create an object at this point
// This allows us to stop the process and return an error (API) or return
@ -114,7 +162,7 @@ class ObjectsController extends AppController {
if (!empty($error)) {
$this->Session->setFlash($error);
}
$template = $this->MispObject->prepareTemplate($template);
$template = $this->MispObject->prepareTemplate($template, $this->request->data);
$enabledRows = array_keys($template['ObjectTemplateElement']);
$this->set('enabledRows', $enabledRows);
$distributionData = $this->MispObject->Event->Attribute->fetchDistributionData($this->Auth->user());
@ -126,6 +174,28 @@ class ObjectsController extends AppController {
}
}
public function get_row($template_id, $object_relation, $k) {
$template = $this->MispObject->ObjectTemplate->find('first', array(
'conditions' => array('ObjectTemplate.id' => $template_id),
'recursive' => -1,
'contain' => array(
'ObjectTemplateElement'
)
));
$template = $this->MispObject->prepareTemplate($template);
$element = array();
foreach ($template['ObjectTemplateElement'] as $templateElement) {
if ($templateElement['object_relation'] == $object_relation) {
$element = $templateElement;
}
}
$distributionData = $this->MispObject->Event->Attribute->fetchDistributionData($this->Auth->user());
$this->layout = false;
$this->set('distributionData', $distributionData);
$this->set('k', $k);
$this->set('element', $element);
}
public function edit($id) {
if (!$this->userRole['perm_modify']) {
throw new MethodNotAllowedException('You don\'t have permissions to edit objects.');
@ -164,19 +234,22 @@ class ObjectsController extends AppController {
'ObjectTemplateElement'
)
));
$template = $this->MispObject->prepareTemplate($template);
$template = $this->MispObject->prepareTemplate($template, $object);
$enabledRows = false;
if ($this->request->is('post') || $this->request->is('put')) {
if (isset($this->request->data['request'])) {
$this->request->data = $this->request->data['request'];
}
if (isset($this->request->data['Object']['data'])) {
$this->request->data = json_decode($this->request->data['Object']['data'], true);
}
if (!isset($this->request->data['Attribute'])) {
$this->request->data = array('Attribute' => $this->request->data);
}
$objectToSave = $this->MispObject->attributeCleanup($this->request->data);
$objectToSave = $this->MispObject->deltaMerge($object, $objectToSave);
// we pre-validate the attributes before we create an object at this point
// This allows us to stop the process and return an error (API) or return
// to the add form
@ -202,7 +275,7 @@ class ObjectsController extends AppController {
$this->request->data['Object'] = $object['Object'];
foreach ($template['ObjectTemplateElement'] as $k => $element) {
foreach ($object['Attribute'] as $k2 => $attribute) {
if ($attribute['object_relation'] == $element['in-object-name']) {
if ($attribute['object_relation'] == $element['object_relation']) {
$enabledRows[] = $k;
$this->request->data['Attribute'][$k] = $attribute;
if (!empty($element['values_list'])) {
@ -232,6 +305,10 @@ class ObjectsController extends AppController {
$this->render('add');
}
public function addValueField() {
}
public function delete($id, $hard = false) {
if (!$this->userRole['perm_modify']) {
throw new MethodNotAllowedException('You don\'t have permissions to delete objects.');

View File

@ -786,7 +786,7 @@ class AppModel extends Model {
$sqlArray[] = "CREATE TABLE IF NOT EXISTS object_template_elements (
`id` int(11) NOT NULL AUTO_INCREMENT,
`object_template_id` int(11) NOT NULL,
`in-object-name` varchar(255) CHARACTER SET utf8 COLLATE utf8_unicode_ci,
`object_relation` varchar(255) CHARACTER SET utf8 COLLATE utf8_unicode_ci,
`type` varchar(255) CHARACTER SET utf8 COLLATE utf8_unicode_ci,
`ui-priority` int(11) NOT NULL,
`categories` text COLLATE utf8_bin,
@ -796,7 +796,7 @@ class AppModel extends Model {
`disable_correlations` tinyint(1) NOT NULL DEFAULT 0,
`multiple` tinyint(1) NOT NULL DEFAULT 0,
PRIMARY KEY (id),
INDEX `in-object-name` (`in-object-name`),
INDEX `object_relation` (`object_relation`),
INDEX `type` (`type`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;";

View File

@ -638,7 +638,7 @@ class Attribute extends AppModel {
// Set defaults for when some of the mandatory fields don't have defaults
// These fields all have sane defaults either based on another field, or due to server settings
if (empty($this->data['Attribute']['distribution'])) {
if (!isset($this->data['Attribute']['distribution'])) {
$this->data['Attribute']['distribution'] = Configure::read('MISP.default_attribute_distribution');
if ($this->data['Attribute']['distribution'] == 'event') {
$this->data['Attribute']['distribution'] = 5;

View File

@ -263,26 +263,58 @@ class MispObject extends AppModel {
/*
* Prepare the template form view's data, setting defaults, sorting elements
*/
public function prepareTemplate($template) {
public function prepareTemplate($template, $request = array()) {
$temp = array();
usort($template['ObjectTemplateElement'], function($a, $b) {
return $a['ui-priority'] < $b['ui-priority'];
});
foreach ($template['ObjectTemplateElement'] as $k => $v) {
if (isset($this->Event->Attribute->typeDefinitions[$template['ObjectTemplateElement'][$k]['type']])) {
$template['ObjectTemplateElement'][$k]['default_category'] = $this->Event->Attribute->typeDefinitions[$template['ObjectTemplateElement'][$k]['type']]['default_category'];
$template['ObjectTemplateElement'][$k]['to_ids'] = $this->Event->Attribute->typeDefinitions[$template['ObjectTemplateElement'][$k]['type']]['to_ids'];
if (empty($template['ObjectTemplateElement'][$k]['categories'])) {
$template['ObjectTemplateElement'][$k]['categories'] = array();
foreach ($this->Event->Attribute->categoryDefinitions as $catk => $catv) {
if (in_array($template['ObjectTemplateElement'][$k]['type'], $catv['types'])) {
$template['ObjectTemplateElement'][$k]['categories'][] = $catk;
$request_rearranged = array();
$template_object_elements = $template['ObjectTemplateElement'];
unset($template['ObjectTemplateElement']);
if (!empty($request['Attribute'])) {
foreach ($request['Attribute'] as $attribute) {
$request_rearranged[$attribute['object_relation']][] = $attribute;
}
}
foreach ($template_object_elements as $k => $v) {
if (empty($request_rearranged[$v['object_relation']])) {
if (isset($this->Event->Attribute->typeDefinitions[$v['type']])) {
$v['default_category'] = $this->Event->Attribute->typeDefinitions[$v['type']]['default_category'];
$v['to_ids'] = $this->Event->Attribute->typeDefinitions[$v['type']]['to_ids'];
if (empty($v['categories'])) {
$v['categories'] = array();
foreach ($this->Event->Attribute->categoryDefinitions as $catk => $catv) {
if (in_array($v['type'], $catv['types'])) {
$v['categories'][] = $catk;
}
}
}
$template['ObjectTemplateElement'][] = $v;
} else {
$template['warnings'][] = 'Missing attribute type "' . $v['type'] . '" found. Omitted template element ("' . $template['ObjectTemplateElement'][$k]['object_relation'] . '") that would not pass validation due to this.';
}
} else {
$template['warnings'][] = 'Missing attribute type "' . $template['ObjectTemplateElement'][$k]['type'] . '" found. Omitted template element ("' . $template['ObjectTemplateElement'][$k]['in-object-name'] . '") that would not pass validation due to this.';
unset($template['ObjectTemplateElement'][$k]);
foreach($request_rearranged[$v['object_relation']] as $request_item) {
if (isset($this->Event->Attribute->typeDefinitions[$v['type']])) {
$v['default_category'] = $request_item['category'];
$v['value'] = $request_item['value'];
$v['to_ids'] = $request_item['to_ids'];
$v['comment'] = $request_item['comment'];
$v['uuid'] = $request_item['uuid'];
if (isset($request_item['data'])) $v['data'] = $request_item['data'];
if (empty($v['categories'])) {
$v['categories'] = array();
foreach ($this->Event->Attribute->categoryDefinitions as $catk => $catv) {
if (in_array($v['type'], $catv['types'])) {
$v['categories'][] = $catk;
}
}
}
$template['ObjectTemplateElement'][] = $v;
} else {
$template['warnings'][] = 'Missing attribute type "' . $v['type'] . '" found. Omitted template element ("' . $template['ObjectTemplateElement'][$k]['object_relation'] . '") that would not pass validation due to this.';
}
}
}
}
return $template;
@ -332,29 +364,41 @@ class MispObject extends AppModel {
public function deltaMerge($object, $objectToSave) {
$object['Object']['comment'] = $objectToSave['Object']['comment'];
$object['Object']['distribution'] = $objectToSave['Object']['distribution'];
$object['Object']['sharing_group_id'] = $objectToSave['Object']['sharing_group_id'];
if ($object['Object']['distribution'] == 4) {
$object['Object']['sharing_group_id'] = $objectToSave['Object']['sharing_group_id'];
}
$date = new DateTime();
$object['Object']['timestamp'] = $date->getTimestamp();
$this->save($object);
$checkFields = array('category', 'value', 'to_ids', 'distribution', 'sharing_group_id', 'comment');
foreach ($objectToSave['Attribute'] as $newKey => $newAttribute) {
foreach ($object['Attribute'] as $origKey => $originalAttribute) {
if (!empty($newAttribute['uuid'])) {
if ($newAttribute['uuid'] == $originalAttribute['uuid']) {
$newAttribute['id'] = $originalAttribute['id'];
$newAttribute['event_id'] = $object['Object']['event_id'];
$newAttribute['object_id'] = $object['Object']['id'];
$newAttribute['timestamp'] = $date->getTimestamp();
$this->Event->Attribute->save($newAttribute, array(
'category',
'value',
'to_ids',
'distribution',
'sharing_group_id',
'comment',
'timestamp',
'object_id',
'event_id'
));
$different = false;
foreach ($checkFields as $f) {
if ($f == 'sharing_group_id' && empty($newAttribute[$f])) {
$newAttribute[$f] = 0;
}
if ($newAttribute[$f] != $originalAttribute[$f]) $different = true;
}
if ($different) {
$newAttribute['id'] = $originalAttribute['id'];
$newAttribute['event_id'] = $object['Object']['event_id'];
$newAttribute['object_id'] = $object['Object']['id'];
$newAttribute['timestamp'] = $date->getTimestamp();
$result = $this->Event->Attribute->save(array('Attribute' => $newAttribute), array(
'category',
'value',
'to_ids',
'distribution',
'sharing_group_id',
'comment',
'timestamp',
'object_id',
'event_id'
));
}
unset($object['Attribute'][$origKey]);
continue 2;
}

View File

@ -116,13 +116,13 @@ class ObjectTemplate extends AppModel {
$existingTemplateElements = array();
if (!empty($existingTemplateElementsTemp)) {
foreach ($existingTemplateElementsTemp as $k => $v) {
$existingTemplateElements[$v['ObjectTemplateElement']['in-object-name']] = $v['ObjectTemplateElement'];
$existingTemplateElements[$v['ObjectTemplateElement']['object_relation']] = $v['ObjectTemplateElement'];
}
}
unset($existingTemplateElementsTemp);
$fieldsToCompare = array('in-object-name', 'type', 'ui-priority', 'categories', 'sane_default', 'values_list');
$fieldsToCompare = array('object_relation', 'type', 'ui-priority', 'categories', 'sane_default', 'values_list', 'multiple');
foreach ($template['attributes'] as $k => $attribute) {
$attribute['in-object-name'] = $k;
$attribute['object_relation'] = $k;
$attribute = $this->__convertJSONToElement($attribute);
if (isset($existingTemplateElements[$k])) {
$update_required = false;
@ -134,15 +134,15 @@ class ObjectTemplate extends AppModel {
}
}
if ($update_required) {
$attribute = $existingTemplateElements[$k];
$attribute['id'] = $existingTemplateElements[$k]['id'];
$attribute['object_template_id'] = $id;
$this->ObjectTemplateElement->save(array('ObjectTemplateElement' => $attribute));
$result = $this->ObjectTemplateElement->save(array('ObjectTemplateElement' => $attribute));
}
if (isset($existingTemplateElements[$k])) unset($existingTemplateElements[$k]);
} else {
$this->ObjectTemplateElement->create();
$attribute['object_template_id'] = $id;
$this->ObjectTemplateElement->save(array('ObjectTemplateElement' => $attribute));
$result = $this->ObjectTemplateElement->save(array('ObjectTemplateElement' => $attribute));
}
}
if (!empty($existingTemplateElements)) {
@ -162,10 +162,11 @@ class ObjectTemplate extends AppModel {
'ui-priority' => 'ui-priority',
'type' => 'type',
'disable_correlation' => 'disable_correlation',
'in-object-name' => 'in-object-name',
'object_relation' => 'object_relation',
'categories' => 'categories',
'sane_default' => 'sane_default',
'values_list' => 'values_list'
'values_list' => 'values_list',
'multiple' => 'multiple'
);
foreach ($translation_table as $from => $to) {
if (isset($attribute[$from])) {
@ -177,6 +178,7 @@ class ObjectTemplate extends AppModel {
public function checkTemplateConformity($template, $attributes) {
if (!empty($template['ObjectTemplate']['requirements'])) {
// check for all required attributes
if (!empty($template['ObjectTemplate']['requirements']['required'])) {
foreach ($template['ObjectTemplate']['requirements']['required'] as $requiredField) {
$found = false;
@ -188,6 +190,7 @@ class ObjectTemplate extends AppModel {
if (!$found) return 'Could not save the object as a required attribute is not set (' . $requiredField . ')';
}
}
// check for all required one of attributes
if (!empty($template['ObjectTemplate']['requirements']['requiredOneOf'])) {
$found = false;
foreach ($template['ObjectTemplate']['requirements']['requiredOneOf'] as $requiredField) {
@ -200,6 +203,21 @@ class ObjectTemplate extends AppModel {
if (!$found) return 'Could not save the object as it requires at least one of the following attributes to be set: ' . implode(', ', $template['ObjectTemplate']['requirements']['requiredOneOf']);
}
}
// check the multiple flag is adhered to
foreach ($template['ObjectTemplateElement'] as $template_attribute) {
if ($template_attribute['multiple'] !== true) {
$found_relations = array();
foreach ($attributes['Attribute'] as $attribute) {
if ($attribute['object_relation'] == $template_attribute['object_relation']) {
if (!isset($found_relations[$attribute['object_relation']])) {
$found_relations[$attribute['object_relation']] = true;
} else {
return 'Could not save the object as a unique relationship within the object was assigned to more than one attribute. This is only allowed if the multiple flag is set in the object template.';
}
}
}
}
}
return true;
}
}

View File

@ -0,0 +1,114 @@
<tr id="row_<?php echo h($k); ?>" class="attribute_row">
<td>
<?php
if (empty($enabledRows)) $enabledRows = array();
if (empty($action)) $action = 'add';
echo $this->Form->input('Attribute.' . $k . '.save', array(
'type' => 'checkbox',
'checked' => in_array($k, $enabledRows),
'label' => false,
'div' => false
));
?>
</td>
<td class="shortish" title="<?php echo h($element['description']); ?>">
<?php
$formSettings = array(
'type' => 'hidden',
'value' => $element['object_relation'],
'label' => false,
'div' => false
);
echo $this->Form->input('Attribute.' . $k . '.object_relation', $formSettings);
if ($action == 'edit') {
echo $this->Form->input('Attribute.' . $k . '.uuid', array(
'type' => 'hidden',
'label' => false,
'div' => false,
'value' => !empty($element['uuid']) ? $element['uuid'] : ''
));
}
$formSettings = array(
'type' => 'hidden',
'value' => $element['type'],
'label' => false,
'div' => false
);
echo $this->Form->input('Attribute.' . $k . '.type', $formSettings);
echo '<span class="bold">' . Inflector::humanize(h($element['object_relation'])) . '</span>';
if (!empty($template['ObjectTemplate']['requirements']['required']) && in_array($element['object_relation'], $template['ObjectTemplate']['requirements']['required'])) {
echo '<span class="bold red">' . '(*)' . '</span>';
}
echo ' :: ' . h($element['type']) . '';
?>
</td>
<td class="short">
<?php
$formSettings = array(
'options' => array_combine($element['categories'], $element['categories']),
'default' => $element['default_category'],
'style' => 'margin-bottom:0px;',
'label' => false,
'div' => false
);
echo $this->Form->input('Attribute.' . $k . '.category', $formSettings);
?>
</td>
<td>
<?php
echo $this->element(
'Objects/object_value_field',
array(
'element' => $element,
'k' => $k
)
);
?>
</td>
<td>
<?php
echo $this->Form->input('Attribute.' . $k . '.to_ids', array(
'type' => 'checkbox',
'checked' => $element['to_ids'],
'label' => false,
'div' => false
));
?>
</td>
<td class="short">
<?php
echo $this->Form->input('Attribute.' . $k . '.distribution', array(
'class' => 'Attribute_distribution_select',
'options' => $distributionData['levels'],
'default' => !empty($element['distribution']) ? $element['distribution'] : $distributionData['initial'],
'style' => 'margin-bottom:0px;',
'label' => false,
'div' => false
));
?>
<br />
<?php
echo $this->Form->input('Attribute.' . $k . '.sharing_group_id', array(
'class' => 'Attribute_sharing_group_id_select',
'options' => $distributionData['sgs'],
'default' => !empty($element['sharing_group_id']) ? $element['sharing_group_id'] : false,
'label' => false,
'div' => false,
'style' => 'display:none;margin-bottom:0px;',
));
?>
</td>
<td>
<?php
echo $this->Form->input('Attribute.' . $k . '.comment', array(
'type' => 'textarea',
'style' => 'height:20px;width:400px;',
'required' => false,
'allowEmpty' => true,
'label' => false,
'div' => false,
'value' => empty($element['comment']) ? '' : $element['comment']
));
?>
</td>
</tr>

View File

@ -0,0 +1,56 @@
<div class="object_value_field">
<?php
if ($element['type'] == 'malware-sample' || $element['type'] == 'attachment'):
echo $this->Form->file('Attribute.' . $k . '.Attachment', array(
'class' => 'Attribute_attachment'
));
else:
if (empty($element['values_list']) && empty($element['sane_default'])):
echo $this->Form->input('Attribute.' . $k . '.value', array(
'type' => 'textarea',
'required' => false,
'allowEmpty' => true,
'style' => 'height:20px;width:400px;',
'label' => false,
'div' => false,
'value' => empty($element['value']) ? '' : $element['value']
));
else:
if (empty($element['values_list'])) {
$list = $element['sane_default'];
$list[] = 'Enter value manually';
} else {
$list = $element['values_list'];
}
$list = array_combine($list, $list);
?>
<div class="value_select_with_manual_entry">
<?php
echo $this->Form->input('Attribute.' . $k . '.value_select', array(
'class' => 'Attribute_value_select',
'style' => 'width:414px;margin-bottom:0px;',
'options' => array_combine($list, $list),
'label' => false,
'div' => false,
'value' => empty($element['value']) ? '' : $element['value']
));
?>
<br />
<?php
echo $this->Form->input('Attribute.' . $k . '.value', array(
'class' => 'Attribute_value',
'type' => 'textarea',
'required' => false,
'allowEmpty' => true,
'style' => 'height:20px;width:400px;display:none;',
'label' => false,
'div' => false,
'value' => empty($element['value']) ? '' : $element['value']
));
?>
</div>
<?php
endif;
endif;
?>
</div>

View File

@ -16,9 +16,10 @@
</div>
<table class="table table-striped table-hover table-condensed">
<tr>
<th><?php echo $this->Paginator->sort('in_object_name');?></th>
<th><?php echo $this->Paginator->sort('object_relation');?></th>
<th><?php echo $this->Paginator->sort('type');?></th>
<th><?php echo $this->Paginator->sort('ui-priority');?></th>
<th><?php echo $this->Paginator->sort('multiple');?></th>
<th><?php echo $this->Paginator->sort('ui-priority', 'UI-priority');?></th>
<th><?php echo $this->Paginator->sort('description');?></th>
<th>Categories</th>
<th>Sane defaults</th>
@ -30,10 +31,11 @@
foreach ($list as $k => $item):
?>
<tr>
<td class="short bold"><?php echo h($item['ObjectTemplateElement']['in-object-name']); ?>&nbsp;</td>
<td class="short bold"><?php echo h($item['ObjectTemplateElement']['object_relation']); ?>&nbsp;</td>
<td class="short"><?php echo h($item['ObjectTemplateElement']['type']); ?>&nbsp;</td>
<td class="short"><span class="icon-<?php echo $item['ObjectTemplateElement']['multiple'] ? 'ok' : 'remove'; ?>"></span></td>
<td class="short"><?php echo h($item['ObjectTemplateElement']['ui-priority']); ?>&nbsp;</td>
<td class="short"><?php echo h($item['ObjectTemplateElement']['description']); ?>&nbsp;</td>
<td><?php echo h($item['ObjectTemplateElement']['description']); ?>&nbsp;</td>
<?php
foreach ($listItems as $listItem):
?>

View File

@ -1,6 +1,6 @@
<div class="<?php if (!isset($ajax) || !$ajax) echo 'form';?>">
<?php
$url = ($action == 'add') ? '/objects/add/' . $event['Event']['id'] . '/' . $template['ObjectTemplate']['id'] : '/objects/edit/' . $object['Object']['id'];
$url = ($action == 'add') ? '/objects/revise_object/add/' . $event['Event']['id'] . '/' . $template['ObjectTemplate']['id'] : '/objects/revise_object/edit/' . $event['Event']['id'] . '/' . $template['ObjectTemplate']['id'] . '/' . $object['Object']['id'];
echo $this->Form->create('Object', array('id', 'url' => $url, 'enctype' => 'multipart/form-data'));
?>
<h3><?php echo ucfirst($action) . ' ' . Inflector::humanize(h($template['ObjectTemplate']['name'])) . ' Object'; ?></h3>
@ -67,7 +67,8 @@
'required' => false,
'allowEmpty' => true,
'label' => false,
'div' => false
'div' => false,
'value' => empty($template['Object']['comment']) ? '' : $template['Object']['comment']
));
?>
</dd>
@ -101,162 +102,42 @@
$row_list = array();
foreach ($template['ObjectTemplateElement'] as $k => $element):
$row_list[] = $k;
?>
<tr>
<td>
<?php
echo $this->Form->input('Attribute.' . $k . '.save', array(
'type' => 'checkbox',
'checked' => in_array($k, $enabledRows),
'label' => false,
'div' => false
));
?>
</td>
<td class="shortish" title="<?php echo h($element['description']); ?>">
<?php
$formSettings = array(
'type' => 'hidden',
'value' => $element['in-object-name'],
'label' => false,
'div' => false
);
echo $this->Form->input('Attribute.' . $k . '.object_relation', $formSettings);
if ($action == 'edit') {
echo $this->Form->input('Attribute.' . $k . '.uuid', array(
'type' => 'hidden',
'label' => false,
'div' => false
));
echo $this->element(
'Objects/object_add_attributes',
array(
'element' => $element,
'k' => $k,
'action' => $action,
'enabledRows' => $enabledRows
)
);
if ($element['multiple']):
$lastOfType = true;
$lookAheadArray = array_slice($template['ObjectTemplateElement'], $k, count($template['ObjectTemplateElement']), true);
if (count($lookAheadArray) > 1) {
foreach ($lookAheadArray as $k2 => $temp) {
if ($k2 == $k) continue;
if ($temp['object_relation'] == $element['object_relation']) {
$lastOfType = false;
}
}
$formSettings = array(
'type' => 'hidden',
'value' => $element['type'],
'label' => false,
'div' => false
);
echo $this->Form->input('Attribute.' . $k . '.type', $formSettings);
echo '<span class="bold">' . Inflector::humanize(h($element['in-object-name'])) . '</span>';
if (!empty($template['ObjectTemplate']['requirements']['required']) && in_array($element['in-object-name'], $template['ObjectTemplate']['requirements']['required'])) {
echo '<span class="bold red">' . '(*)' . '</span>';
}
echo ' :: ' . h($element['type']) . '';
?>
</td>
<td class="short">
<?php
$formSettings = array(
'options' => array_combine($element['categories'], $element['categories']),
'default' => $element['default_category'],
'style' => 'margin-bottom:0px;',
'label' => false,
'div' => false
);
echo $this->Form->input('Attribute.' . $k . '.category', $formSettings);
?>
</td>
<td>
<?php
if ($element['type'] == 'malware-sample' || $element['type'] == 'attachment'):
echo $this->Form->file('Attribute.' . $k . '.Attachment', array(
'class' => 'Attribute_attachment'
));
else:
if (empty($element['values_list']) && empty($element['sane_default'])):
echo $this->Form->input('Attribute.' . $k . '.value', array(
'type' => 'textarea',
'required' => false,
'allowEmpty' => true,
'style' => 'height:20px;width:400px;',
'label' => false,
'div' => false
));
else:
if (empty($element['values_list'])) {
$list = $element['sane_default'];
$list[] = 'Enter value manually';
} else {
$list = $element['values_list'];
}
$list = array_combine($list, $list);
?>
<div class="value_select_with_manual_entry">
<?php
echo $this->Form->input('Attribute.' . $k . '.value_select', array(
'class' => 'Attribute_value_select',
'style' => 'width:414px;margin-bottom:0px;',
'options' => array_combine($list, $list),
'label' => false,
'div' => false
));
?>
<br />
<?php
echo $this->Form->input('Attribute.' . $k . '.value', array(
'class' => 'Attribute_value',
'type' => 'textarea',
'required' => false,
'allowEmpty' => true,
'style' => 'height:20px;width:400px;display:none;',
'label' => false,
'div' => false
));
?>
</div>
<?php
endif;
endif;
?>
</td>
<td>
<?php
echo $this->Form->input('Attribute.' . $k . '.to_ids', array(
'type' => 'checkbox',
'checked' => $element['to_ids'],
'label' => false,
'div' => false
));
?>
</td>
<td class="short">
<?php
echo $this->Form->input('Attribute.' . $k . '.distribution', array(
'class' => 'Attribute_distribution_select',
'options' => $distributionData['levels'],
'default' => $distributionData['initial'],
'style' => 'margin-bottom:0px;',
'label' => false,
'div' => false
));
?>
<br />
<?php
echo $this->Form->input('Attribute.' . $k . '.sharing_group_id', array(
'class' => 'Attribute_sharing_group_id_select',
'options' => $distributionData['sgs'],
'label' => false,
'div' => false,
'style' => 'display:none;margin-bottom:0px;',
));
?>
</td>
<td>
<?php
echo $this->Form->input('Attribute.' . $k . '.comment', array(
'type' => 'textarea',
'style' => 'height:20px;width:400px;',
'required' => false,
'allowEmpty' => true,
'label' => false,
'div' => false
));
?>
</td>
</tr>
}
if ($lastOfType):
?>
<tr id="row_<?php echo h($element['object_relation']); ?>_expand">
<td class="down-expand-button add_object_attribute_row" colspan="7" data-template-id="<?php echo h($template['ObjectTemplate']['id']);?>" data-target-row="<?php echo h($k); ?>" data-object-relation="<?php echo h($element['object_relation']); ?>">
<span class="fa fa-angle-double-down" ></span>
</td>
</tr>
<?php
endif;
endif;
?>
<?php
endforeach;
?>
</table>
<div id="last-row" class="hidden" data-last-row="<?php echo h($k); ?>"></div>
<?php if ($ajax): ?>
<div class="overlay_spacing">
<table>
@ -305,5 +186,10 @@
$(".Attribute_value_select").change(function() {
checkAndEnable($(this).parent().find('.Attribute_value'), $(this).val() == 'Enter value manually');
});
$('.add_attribute_row').click(function() {
var selector = $(this).data('target');
var count = $(this).parent().children(selector).length;
$(this).parent().children(selector).first().clone().appendTo($(this).parent()).insertBefore($('.add_unlocked_field'));
});
});
</script>

View File

@ -0,0 +1,10 @@
<?php
echo $this->element(
'Objects/object_add_attributes',
array(
'element' => $element,
'k' => $k,
'appendValue' => '0'
)
);
?>

View File

@ -0,0 +1,56 @@
<div class="form">
<h3>Object pre-save review</h3>
<p>Make sure that the below Object reflects your expectation before submiting it.</p>
<?php
$url = ($action == 'add') ? '/objects/add/' . $event['Event']['id'] . '/' . $template['ObjectTemplate']['id'] : '/objects/edit/' . $object_id;
echo $this->Form->create('Object', array('id', 'url' => $url));
$formSettings = array(
'type' => 'hidden',
'value' => json_encode($data, true),
'label' => false,
'div' => false
);
echo $this->Form->input('data', $formSettings);
?>
<div style="margin-bottom:20px;">
<span class="bold">Name</span>: <?php echo h($template['ObjectTemplate']['name']); ?><br />
<span class="bold">Meta-category</span>: <?php echo h($template['ObjectTemplate']['meta-category']); ?><br />
<span class="bold">Distribution</span>:
<?php
if ($data['Object']['distribution'] != 4) {
echo $distributionLevels[$data['Object']['distribution']];
} else {
echo h($sg['SharingGroup']['name']);
}
?><br />
<span class="bold">Comment</span>: <?php echo h($data['Object']['comment']); ?><br />
<span class="bold">Attributes</span>:<br />
<?php
$attributeFields = array('category', 'type', 'value', 'to_ids' , 'comment', 'uuid', 'distribution', 'sharing_group_id');
if (!empty($data['Attribute'])):
foreach ($data['Attribute'] as $attribute):
echo '<span class="bold" style="margin-left:2em;">' . h($attribute['object_relation']) . ':</span><br />';
foreach ($attributeFields as $field):
if ($field == 'to_ids') $attribute[$field] = $attribute[$field] ? 'Yes' : 'No';
if (isset($attribute[$field])):
?>
<span class="bold" style="margin-left:4em;"><?php echo Inflector::humanize($field);?></span>: <?php echo h($attribute[$field]); ?><br />
<?php
endif;
endforeach;
endforeach;
endif;
?>
</div>
<?php
echo $this->Form->button('Submit', array('class' => 'btn btn-primary'));
?>
<a href="<?php echo $baseurl . '/events/view/' . h($event['Event']['id']); ?>" style="margin-left:10px;" class="btn btn-inverse">Cancel</a>
<?php
echo $this->Form->end();
?>
</div>
<?php
echo $this->element('side_menu', array('menuList' => 'event', 'menuItem' => 'addObject', 'event' => $event));
?>

@ -1 +1 @@
Subproject commit 01a23c205cf2a27a2351ae3fcc0f3735a8b436b1
Subproject commit d34dd5fb606f1c4d882733d16c16103fe429991c

View File

@ -1882,6 +1882,19 @@ tr.blank_table_row td {
background-color: #ffffff !important;
}
.down-expand-button {
text-align:center !important;
border:0px;
padding:0px !important;
width:100%;
cursor: pointer;
cursor: hand;
}
table tr:hover .down-expand-button {
background: rgb(221, 221, 221) !important;
}
.strikethrough {
text-decoration: line-through;
}

View File

@ -3198,6 +3198,18 @@ function changeObjectReferenceSelectOption() {
}
}
$('.add_object_attribute_row').click(function() {
var template_id = $(this).data('template-id');
var object_relation = $(this).data('object-relation');
var k = $('#last-row').data('last-row');
var k = k+1;
$('#last-row').data('last-row', k);
url = "/objects/get_row/" + template_id + "/" + object_relation + "/" + k;
$.get(url, function(data) {
$('#row_' + object_relation + '_expand').before($(data).fadeIn()).html();
});
});
(function(){
"use strict";
$(".datepicker").datepicker({