Further work on the templates

pull/274/head^2
iglocska 2014-06-25 09:56:33 +02:00
parent a4a987e027
commit 9bede8e1b4
10 changed files with 342 additions and 151 deletions

View File

@ -1,7 +1,6 @@
<?php
App::uses('AppController', 'Controller');
App::uses('ComplexTypeTool', 'Tools');
/**
* Templates Controller
@ -21,7 +20,7 @@ class TemplatesController extends AppController {
public function beforeFilter() { // TODO REMOVE
parent::beforeFilter();
$this->Security->unlockedActions = array('saveElementSorting');
$this->Security->unlockedActions = array('saveElementSorting', 'populateEventFromTemplate');
}
public function fetchFormFromTemplate($id) {
@ -209,7 +208,16 @@ class TemplatesController extends AppController {
}
public function delete($id) {
$template = $this->Template->checkAuthorisation($id, $this->Auth->user(), true);
if (!$this->request->is('post')) throw new MethodNotAllowedException('This action can only be invoked via a post request.');
if (!$this->_isSiteAdmin() && !$template) throw new MethodNotAllowedException('No template with the provided ID exists, or you are not authorised to edit it.');
if ($this->Template->delete($id, true)) {
$this->Session->setFlash('Template deleted.');
$this->redirect(array('action' => 'index'));
} else {
$this->Session->setFlash('The template could not be deleted.');
$this->redirect(array('action' => 'index'));
}
}
@ -255,47 +263,53 @@ class TemplatesController extends AppController {
'recursive' => -1,
'fields' => array('id', 'orgc', 'distribution'),
));
if (empty($event)) throw new MethodNotAllowedException('Event not found or you are not authorised to edit it.');
if (empty($template)) throw new MethodNotAllowedException('Template not found or you are not authorised to edit it.');
if (!$this->_isSiteAdmin()) {
if ($event['Event']['orgc'] != $this->Auth->user('org')) throw new MethodNotAllowedException('Event not found or you are not authorised to edit it.');
if ($template['Template']['org'] != $this->Auth->user('org')) throw new MethodNotAllowedException('Template not found or you are not authorised to use it.');
}
$this->set('template_id', $template_id);
$this->set('event_id', $event_id);
if ($this->request->is('post')) {
if (!isset($this->request->data['Template']['attributes'])) {
$result = array();
$errors = array();
$attributes = array();
foreach ($template['TemplateElement'] as $element) {
if ($element['element_definition'] == 'attribute') {
$result = $this->_resolveElementAttribute($element['TemplateElementAttribute'][0], $this->request->data['Template']['value_' . $element['id']]);
if ($result['errors']) {
$errors[$element['id']] = $result['errors'];
} else {
foreach ($result['attributes'] as &$a) {
$a['event_id'] = $event_id;
$a['distribution'] = $event['Event']['distribution'];
$test = $this->Event->Attribute->checkForvalidationIssues(array('Attribute' => $a));
if ($test) {
foreach ($test['value'] as $e) {
$errors[$element['id']] = $e;
}
} else {
$attributes[] = $a;
}
}
}
} else if ($element['element_definition'] == 'file') {
//$result = $this->_resolveElementFile($element['TemplateElementFile'][0], $this->request->data['Template']['value_' . $element['id']]);
}
}
if (empty($errors)) {
$this->set('template', $this->request->data);
$this->set('attributes', $attributes);
$this->set('distributionLevels', $this->Event->distributionLevels);
$this->render('populate_event_from_template_attributes');
} else {
$this->set('template', $this->request->data);
$this->set('errors', $errors);
$this->set('templateData', $template);
$this->loadModel('Attribute');
$this->set('validTypeGroups', $this->Attribute->validTypeGroups);
}
$result = $this->Event->Attribute->checkTemplateAttributes($template, $this->request->data, $event_id, $event['Event']['distribution']);
$errors = $result['errors'];
$attributes = $result['attributes'];
if (empty($errors) && empty($this->request->data['Template']['modify'])) {
$this->set('template', $this->request->data);
$this->set('attributes', $attributes);
$this->set('distributionLevels', $this->Event->distributionLevels);
$this->render('populate_event_from_template_attributes');
} else {
$this->set('template', $this->request->data);
$this->set('errors', $errors);
$this->set('templateData', $template);
$this->set('validTypeGroups', $this->Event->Attribute->validTypeGroups);
}
} else {
$this->set('templateData', $template);
$this->set('validTypeGroups', $this->Event->Attribute->validTypeGroups);
}
}
public function submitEventPopulation($template_id, $event_id) {
if ($this->request->is('post')) {
$this->loadModel('Event');
$event = $this->Event->find('first', array(
'conditions' => array('id' => $event_id),
'recursive' => -1,
'fields' => array('id', 'orgc', 'distribution'),
));
if (empty($event)) throw new MethodNotAllowedException('Event not found or you are not authorised to edit it.');
if (!$this->_isSiteAdmin()) {
if ($event['Event']['orgc'] != $this->Auth->user('org')) throw new MethodNotAllowedException('Event not found or you are not authorised to edit it.');
}
if (isset($this->request->data['Template']['attributes'])) {
$attributes = unserialize($this->request->data['Template']['attributes']);
$this->loadModel('Attribute');
$fails = 0;
@ -303,77 +317,15 @@ class TemplatesController extends AppController {
$this->Attribute->create();
if (!$this->Attribute->save(array('Attribute' => $attribute))) $fails++;
}
if ($fails == 0) $this->Session->setFlash(__('Event populated, ' . $k . ' attributes successfully created.'));
$count = $k + 1;
if ($fails == 0) $this->Session->setFlash(__('Event populated, ' . $count . ' attributes successfully created.'));
else $this->Session->setFlash(__('Event populated, but ' . $fails . ' attributes could not be saved.'));
$this->redirect(array('controller' => 'events', 'action' => 'view', $event_id));
} else {
throw new MethodNotAllowedException('No attributes submitted for creation.');
}
} else {
$this->set('templateData', $template);
$this->loadModel('Attribute');
$this->set('validTypeGroups', $this->Attribute->validTypeGroups);
throw new MethodNotAllowedException();
}
}
private function _resolveElementAttribute($element, $value) {
$attributes = array();
$results = array();
$errors=null;
if (!empty($value)) {
if ($element['batch']) {
$values = explode("\n", $value);
foreach ($values as $v) {
$v = trim($v);
$attributes[] = $this->_createAttribute($element, $v);
}
} else {
$attributes[] = $this->_createAttribute($element, trim($value));
}
foreach ($attributes as $att) {
if (isset($att['multi'])) {
foreach ($att['multi'] as $a) {
$results[] = $a;
}
} else {
$results[] = $att;
}
}
} else {
if ($element['mandatory']) $errors = 'This field is mandatory.';
}
return array('attributes' => $results, 'errors' => $errors);
}
private function _createAttribute($element, $value) {
$attribute = array(
'comment' => $element['name'],
'to_ids' => $element['to_ids'],
'category' => $element['category'],
'value' => $value,
);
if ($element['complex']) {
$complexTypeTool = new ComplexTypeTool();
$result = $complexTypeTool->checkComplexRouter($value, ucfirst($element['type']));
if (isset($result['multi'])) {
$temp = $attribute;
$attribute = array();
foreach($result['multi'] as $k => $r) {
$attribute['multi'][] = $temp;
$attribute['multi'][$k]['type'] = $r['type'];
$attribute['multi'][$k]['value'] = $r['value'];
}
} else if ($result != false) {
$attribute['type'] = $result['type'];
$attribute['value'] = $result['value'];
} else {
return false;
}
} else {
$attribute['type'] = $element['type'];
}
return $attribute;
}
private function _resolveElementFile($element, $value) {
}
}

View File

@ -1351,7 +1351,7 @@ class Attribute extends AppModel {
return $result;
}
public function checkForvalidationIssues($attribute) {
public function checkForValidationIssues($attribute) {
$this->set($attribute);
if ($this->validates()) {
return false;
@ -1359,4 +1359,161 @@ class Attribute extends AppModel {
return $this->validationErrors;
}
}
public function checkTemplateAttributes($template, $data, $event_id, $distribution) {
$result = array();
$errors = array();
$attributes = array();
foreach ($template['TemplateElement'] as $element) {
if ($element['element_definition'] == 'attribute') {
$result = $this->__resolveElementAttribute($element['TemplateElementAttribute'][0], $data['Template']['value_' . $element['id']]);
} else if ($element['element_definition'] == 'file') {
$temp = array();
foreach ($data['Template']['file_' . $element['id']] as $fileArray) {
foreach ($fileArray as $k => $file) {
if (($file['name'] != '' && $file['size'] > 0) || ($k + 1 == count($fileArray))) {
$temp[] = $file;
}
}
}
$result = $this->__resolveElementFile($element['TemplateElementFile'][0], $temp);
}
if ($element['element_definition'] == 'file' || $element['element_definition'] == 'attribute') {
if ($result['errors']) {
$errors[$element['id']] = $result['errors'];
} else {
foreach ($result['attributes'] as &$a) {
$a['event_id'] = $event_id;
$a['distribution'] = $distribution;
$test = $this->checkForValidationIssues(array('Attribute' => $a));
if ($test) {
foreach ($test['value'] as $e) {
$errors[$element['id']] = $e;
}
} else {
$attributes[] = $a;
}
}
}
}
}
return array('attributes' => $attributes, 'errors' => $errors);
}
private function __resolveElementAttribute($element, $value) {
$attributes = array();
$results = array();
$errors=null;
if (!empty($value)) {
if ($element['batch']) {
$values = explode("\n", $value);
foreach ($values as $v) {
$v = trim($v);
$attributes[] = $this->__createAttribute($element, $v);
}
} else {
$attributes[] = $this->__createAttribute($element, trim($value));
}
foreach ($attributes as $att) {
if (isset($att['multi'])) {
foreach ($att['multi'] as $a) {
$results[] = $a;
}
} else {
$results[] = $att;
}
}
} else {
if ($element['mandatory']) $errors = 'This field is mandatory.';
}
return array('attributes' => $results, 'errors' => $errors);
}
private function __resolveElementFile($element, $value) {
$attributes = array();
$errors = null;
$results = array();
$count = count($value);
$element['complex'] = false;
if ($element['malware']) {
$element['type'] = 'malware-sample';
$element['to_ids'] = true;
} else {
$element['type'] = 'attachment';
$element['to_ids'] = false;
}
if ($count == 1 && $value[0]['size'] == 0) {
if ($element['mandatory']) $errors = 'This field is mandatory.';
} else {
if ($count > 1) unset($value[$count-1]);
foreach ($value as $v) {
if (!($v['size'] > 0 && $v['error'] == 0)) {
$errors = 'File upload failed or the file was empty.';
} else if (!preg_match('@^[\w\-. ]+$@', $v['name'])) {
$errors = 'Filename not allowed.';
} else {
if ($element['malware']) {
$malwareName = $v['name'] . '|' . hash_file('md5', $v['tmp_name']);
$attributes[] = $this->__createAttribute($element, $malwareName);
$file = new File($v['tmp_name']);
if (!$file->exists()) {
$errors = 'File cannot be read.';
} else {
$content = $file->read();
$attributes[count($attributes) - 1]['data'] = base64_encode($content);
$element['type'] = 'filename|sha256';
$sha256 = $v['name'] . '|' . (hash_file('sha256', $v['tmp_name']));
$attributes[] = $this->__createAttribute($element, $sha256);
$element['type'] = 'filename|sha1';
$sha1 = $v['name'] . '|' . (hash_file('sha1', $v['tmp_name']));
$attributes[] = $this->__createAttribute($element, $sha1);
}
} else {
$attributes[] = $this->__createAttribute($element, $v['name']);
$file = new File($v['tmp_name']);
if (!$file->exists()) {
$errors = 'File cannot be read.';
} else {
$content = $file->read();
$attributes[count($attributes) - 1]['data'] = base64_encode($content);
}
}
}
}
}
return array('attributes' => $attributes, 'errors' => $errors);
}
private function __createAttribute($element, $value) {
$attribute = array(
'comment' => $element['name'],
'to_ids' => $element['to_ids'],
'category' => $element['category'],
'value' => $value,
);
if ($element['complex']) {
App::uses('ComplexTypeTool', 'Tools');
$complexTypeTool = new ComplexTypeTool();
$result = $complexTypeTool->checkComplexRouter($value, ucfirst($element['type']));
if (isset($result['multi'])) {
$temp = $attribute;
$attribute = array();
foreach($result['multi'] as $k => $r) {
$attribute['multi'][] = $temp;
$attribute['multi'][$k]['type'] = $r['type'];
$attribute['multi'][$k]['value'] = $r['value'];
}
} else if ($result != false) {
$attribute['type'] = $result['type'];
$attribute['value'] = $result['value'];
} else {
return false;
}
} else {
$attribute['type'] = $element['type'];
}
return $attribute;
}
}

View File

@ -9,9 +9,12 @@ App::uses('AppModel', 'Model');
class Template extends AppModel {
public $actsAs = array('Containable');
public $hasMany = array(
'TemplateTag',
'TemplateTag' => array(
'dependent' => true,
),
'TemplateElement' => array(
'order' => 'TemplateElement.position'
'order' => 'TemplateElement.position',
'dependent' => true,
)
);

View File

@ -8,7 +8,17 @@ App::uses('AppModel', 'Model');
*/
class TemplateElement extends AppModel {
public $actsAs = array('Containable');
public $hasMany = array('TemplateElementAttribute', 'TemplateElementText', 'TemplateElementFile');
public $hasMany = array(
'TemplateElementAttribute' => array(
'dependent' => true
),
'TemplateElementText' => array(
'dependent' => true
),
'TemplateElementFile' => array(
'dependent' => true
)
);
public $belongsTo = array('Template');
public function lastPosition($template_id) {

View File

@ -2,7 +2,6 @@
echo $this->Html->script('ajaxification');
$mayModify = ($isSiteAdmin || ($isAclModify && $event['Event']['user_id'] == $me['id'] && $event['Event']['orgc'] == $me['org']) || ($isAclModifyOrg && $event['Event']['orgc'] == $me['org']));
$mayPublish = ($isAclPublish && $event['Event']['orgc'] == $me['org']);
if (!empty($eventArray)):
$pageCount = intval($objectCount / 50);
if ($objectCount%50 != 0) $pageCount++;
$possibleAction = 'Proposal';
@ -45,6 +44,18 @@
<?php
endif;
?>
<div id="edit_object_div">
<?php
echo $this->Form->create('Attribute', array('id' => 'delete_selected', 'action' => 'deleteSelected'));
echo $this->Form->input('ids', array(
'type' => 'text',
'value' => 'test',
'style' => 'display:none;',
'label' => false,
));
echo $this->Form->end();
?>
</div>
<div id="attributeList" class="attributeListContainer">
<div class="tabMenu tabMenuEditBlock noPrint">
<span id="create-button" title="Add attribute" class="icon-plus useCursorPointer" onClick="clickCreateButton(<?php echo $event['Event']['id']; ?>, '<?php echo $possibleAction; ?>');"></span>
@ -56,7 +67,7 @@
</div>
<table class="table table-striped table-condensed">
<tr>
<?php if ($mayModify): ?>
<?php if ($mayModify && !empty($eventArray)): ?>
<th><input class="select_all" type="checkbox" onClick="toggleAllAttributeCheckboxes();" /></th>
<?php endif;?>
<th>Date</th>
@ -111,22 +122,7 @@
<?php endif; ?>
</ul>
</div>
<?php
endif;
?>
<div id="edit_object_div">
<?php
echo $this->Form->create('Attribute', array('id' => 'delete_selected', 'action' => 'deleteSelected'));
echo $this->Form->input('ids', array(
'type' => 'text',
'value' => 'test',
'style' => 'display:none;',
'label' => false,
));
echo $this->Form->end();
?>
</div>
<?php
<?php
for ($j = 0; $j < 2; $j++) {
$side = 'a';
if ($j == 1) $side = 'b';
@ -182,16 +178,16 @@
);
}
endif;
?>
<script type="text/javascript">
$(document).ready(function(){
$('input:checkbox').removeAttr('checked');
$('.mass-select').hide();
$('input[type="checkbox"]').click(function(){
attributeListAnyCheckBoxesChecked();
});
});
</script>
<?php
?>
<script type="text/javascript">
$(document).ready(function(){
$('input:checkbox').removeAttr('checked');
$('.mass-select').hide();
$('input[type="checkbox"]').click(function(){
attributeListAnyCheckBoxesChecked();
});
});
</script>
<?php
echo $this->Js->writeBuffer();
?>

View File

@ -0,0 +1,25 @@
<?php //debug($element_id); ?>
<div id="populate_template_info" class="templateTableRow templateTableRow80">
<div class="templateElementHeader" style="width:100%; position:relative;">
<div class="templateGlass"></div>
<div class ="templateElementHeaderText"><?php echo h($element['name']); ?></div>
</div>
<div id="populate_template_info_body" class="populate_template_div_body">
<div class="left">Description:</div>
<div class="right"><?php echo h($element['description']); ?></div><br />
<div class="left">File<?php if ($element['batch']) echo 's'?>:</div>
<div class="right" id ="filenames_<?php echo $element_id; ?>">&nbsp;</div><br />
<div class="input file" id="file_container_<?php echo $element_id;?>">
</div>
</div>
</div>
<script type="text/javascript">
var i_<?php echo $element_id; ?> = 0;
var element_id_<?php echo $element_id; ?> = <?php echo $element_id; ?>;
var batch_<?php echo $element_id; ?> = "<?php echo ($element['batch'] ? 'yes' : 'no'); ?>";
$(document).ready(function() {
populateTemplateCreateFileUpload(element_id_<?php echo $element_id; ?>, i_<?php echo $element_id; ?>, batch_<?php echo $element_id; ?>);
});
</script>

View File

@ -1,3 +1,4 @@
<?php echo $this->Html->script('ajaxification'); ?>
<div class="populate_from_template form">
<?php echo $this->Form->create('', array('type' => 'file'));?>
<fieldset>

View File

@ -22,7 +22,7 @@ foreach ($attributes as $item):?>
endforeach;?>
</table>
<div style="float:left;">
<?php echo $this->Form->create('Template');?>
<?php echo $this->Form->create('Template', array('url' => '/templates/submitEventPopulation/' . $template_id . '/' . $event_id));?>
<fieldset>
<?php
echo $this->Form->input('attributes', array(
@ -44,12 +44,18 @@ endforeach;?>
<fieldset>
<?php
foreach ($template['Template'] as $k => $v) {
if (strpos($k, 'ile_')) $v = serialize($v);
echo $this->Form->input($k, array(
'label' => false,
'type' => 'hidden',
'value' => $v,
));
}
echo $this->Form->input('modify', array(
'label' => false,
'type' => 'hidden',
'value' => true,
));
?>
</fieldset>
<?php

View File

@ -1188,6 +1188,25 @@ a.proposal_link_red:hover {
font-weight:bold;
}
.template_file_box {
background-color:#0088cc;
color:white;
white-space:nowrap;
}
.template_file_box_container {
float:left;
padding:3px;
}
.drop {
min-height: 150px;
width: 250px;
border: 1px solid blue;
margin: 10px;
padding: 10px;
}
@-webkit-keyframes rotation {
from {-webkit-transform: rotate(0deg);}
to {-webkit-transform: rotate(359deg);}

View File

@ -6,12 +6,6 @@ function deleteObject(type, action, id, event) {
$("#confirmation_box").fadeIn();
$("#gray_out").fadeIn();
$("#confirmation_box").html(data);
$(window).bind('keypress', function(e) {
var code = e.keyCode || e.which;
if (code == 13) {
submitDeletion(event, action, type, id);
}
});
});
}
@ -297,12 +291,13 @@ function deleteSelectedAttributes(event) {
var selected = [];
$(".select_attribute").each(function() {
if ($(this).is(":checked")) {
var test = $(this).data("id");
selected.push(test);
var temp= $(this).data("id");
selected.push(temp);
}
});
$('#AttributeIds').attr('value', JSON.stringify(selected));
var formData = $('#delete_selected').serialize();
console.log(formData);
$.ajax({
data: formData,
cache: false,
@ -765,4 +760,31 @@ function resizePopoverBody() {
bodyheight = 3 * bodyheight / 4 - 150;
console.log(bodyheight);
$("#popover_choice_main").css({"max-height": bodyheight});
}
function populateTemplateBindChangeEvent(name, filenameContainer, e, i, batch) {
$(name).change(
function(){
if (batch == 'yes') {
var files = $(this)[0].files;
for (var i = 0; i < files.length; i++) {
$(filenameContainer).append('<div class ="template_file_box_container"><span class="tagFirstHalf template_file_box">' + files[i].name + '</span><span class="tagSecondHalf useCursorPointer">x</span></div>');
}
$(name).hide();
i++;
populateTemplateCreateFileUpload(e, i, batch);
} else {
$(filenameContainer).html('<span class="tagFirstHalf">' + $(this).val() + '<span class="icon-remove"></span></span>');
}
});
}
function populateTemplateCreateFileUpload(e, i, batch) {
if (batch == 'yes') {
$('#file_container_' + e).append('<input id="Template' + e + 'File' + i + '" type="file" name="data[Template][file_' + e + '][' + i + '][]" multiple="multiple">');
} else {
$('#file_container_' + e).append('<input id="Template' + e + 'File' + i + '" type="file" name="data[Template][file_' + e + '][' + i + '][]">');
}
populateTemplateBindChangeEvent('#Template' + e + 'File' + i, '#filenames_' + e, e, i, batch);
}