chg: [eventReport] Added markdown-it dependency and started integration

- WiP
pull/6412/head
mokaddem 2020-08-04 10:08:18 +02:00
parent 65ffe0f4fa
commit 8d6f2eab03
No known key found for this signature in database
GPG Key ID: 164C473F627A06FA
15 changed files with 8412 additions and 12 deletions

View File

@ -62,11 +62,35 @@ class EventReportsController extends AppController
$this->set('initialDistribution', $initialDistribution);
$sgs = $this->EventReport->Event->SharingGroup->fetchAllAuthorised($this->Auth->user(), 'name', 1);
$this->set('sharingGroups', $sgs);
$this->set('action', 'add');
}
public function view($report_id)
public function view($report_id, $ajax=false)
{
$report = $this->EventReport->fetchReports($this->Auth->user(), array('conditions' => array('id' => $report_id)));
if (empty($report)) {
throw new NotFoundException(__('Invalid Event Report'));
}
$report = $report[0];
$this->set('id', $report_id);
$this->set('report', $report);
$this->set('ajax', $ajax);
$distributionLevels = $this->EventReport->Event->Attribute->distributionLevels;
$this->set('distributionLevels', $distributionLevels);
}
public function viewSummary($report_id)
{
$report = $this->EventReport->fetchReports($this->Auth->user(), array('conditions' => array('id' => $report_id)));
if (empty($report)) {
throw new NotFoundException(__('Invalid Event Report'));
}
$report = $report[0];
$this->set('id', $report_id);
$this->set('report', $report);
$distributionLevels = $this->EventReport->Event->Attribute->distributionLevels;
$this->set('distributionLevels', $distributionLevels);
}
public function edit($id)
@ -118,6 +142,7 @@ class EventReportsController extends AppController
public function delete($id)
{
$this->delete($id);
}

View File

@ -1406,7 +1406,7 @@ class AppModel extends Model
case 56:
$sqlArray[] = "CREATE TABLE IF NOT EXISTS event_reports (
`id` int(11) NOT NULL AUTO_INCREMENT,
`uuid` varchar(40) COLLATE utf8_bin DEFAULT NULL,
`uuid` varchar(40) COLLATE utf8_bin NOT NULL ,
`event_id` int(11) NOT NULL,
`name` varchar(255) NOT NULL,
`content` text,
@ -1415,6 +1415,7 @@ class AppModel extends Model
`timestamp` int(11) NOT NULL,
`deleted` tinyint(1) NOT NULL DEFAULT 0,
PRIMARY KEY (id),
CONSTRAINT u_uuid UNIQUE (uuid),
INDEX `name` (`name`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;";
break;

View File

@ -2145,7 +2145,8 @@ class Event extends AppModel
'EventTag' => array(
'Tag' => array('conditions' => $tagConditions, 'order' => false),
'order' => false
)
),
'EventReport' => array()
)
);
if (!empty($options['excludeLocalTags'])) {

View File

@ -139,7 +139,7 @@ class EventReport extends AppModel
}
}
$fieldList = array('name', 'content', 'timestamp', 'distribution', 'sharing_group_id', 'deleted');
$saveSuccess = $this->edit($report, array('fieldList' => $fieldList));
// $saveSuccess = $this->save($report, array('fieldList' => $fieldList));
return $errors;
}

View File

@ -0,0 +1,128 @@
<div style="margin-bottom: 10px;">
<!-- <button type="button" class="btn btn-primary" onclick="renderMarkdown()">
<i class="<?= $this->FontAwesome->getClass('markdown') ?> fa-markdown"></i>
<?= __('Render Markdown') ?>
</button> -->
<button type="button" class="btn btn-inverse" onclick="toggleEditor()">
<i class="<?= $this->FontAwesome->getClass('edit') ?> fa-edit"></i>
<?= __('Edit') ?>
</button>
<button id="saveMarkdownButton" type="button" class="btn btn-primary" onclick="saveMarkdown()" disabled>
<i class="<?= $this->FontAwesome->getClass('edit') ?> fa-edit"></i>
<?= __('Save') ?>
</button>
<!-- <button type="button" class="btn btn-primary">
<i class="<?= $this->FontAwesome->getClass('columns') ?> fa-columns"></i>
<?= __('Split Edit') ?>
</button> -->
</div>
<!-- <div id="raw">
<pre><?php echo h($markdown) ?></pre>
</div> -->
<div class="viewer-container">
<div id="editor-container" style="display: flex;">
<textarea id="editor"></textarea>
</div>
<div id="viewer">
</div>
</div>
<?php
echo $this->element('genericElements/assetLoader', array(
'js' => array('markdown-it')
));
?>
<script>
var md;
var originalRaw = <?= json_encode(is_array($markdown) ? $markdown : array($markdown), JSON_HEX_TAG); ?>[0];
var modelName = '<?= h($modelName) ?>';
var mardownModelFieldName = '<?= h($mardownModelFieldName) ?>';
var renderTimer;
var renderDelay = 50;
var loadingSpanAnimation = '<span id="loadingSpan" class="fa fa-spin fa-spinner" style="margin-left: 5px;"></span>';
$(document).ready(function() {
$('#editor-container').hide();
md = window.markdownit();
setEditorData(originalRaw);
$('#editor').on('input', function() {
doRender();
})
renderMarkdown()
})
function toggleEditor() {
$('#editor-container').show();
}
function getEditorData() {
return $('#editor').val()
}
function setEditorData(data) {
$('#editor').val(data)
}
function saveMarkdown() {
var url = "<?= $baseurl ?>/eventReports/edit/<?= h($id) ?>"
fetchFormDataAjax(url, function(formHTML) {
$('body').append($('<div id="temp" style="display: none"/>').html(formHTML))
var $tmpForm = $('#temp form')
$tmpForm.find('[name="data[' + modelName + '][' + mardownModelFieldName + ']"]').val(getEditorData())
$.ajax({
data: $('#GalaxyAttachMultipleClustersForm').serialize(),
beforeSend: function() {
$('#saveMarkdownButton')
.prop('disabled', 'disabled')
.append(loadingSpanAnimation);
},
success:function(data, textStatus) {
showMessage('success', '<?= 'Markdown saved' ?>');
},
error: function(jqXHR, textStatus, errorThrown) {
showMessage('fail', '<?= 'Could not save markdown. Reason' ?>' + ": " + errorThrown);
},
complete:function() {
$('#temp').remove();
$('#saveMarkdownButton')
.prop('disabled', '')
.find('#loadingSpan').remove();
},
type:"post",
url: url
})
})
}
function renderMarkdown() {
var toRender = getEditorData();
var result = md.render(toRender);
$('#viewer').html(result);
}
function doRender() {
clearTimeout(renderTimer);
renderTimer = setTimeout(function() {
$('#saveMarkdownButton').prop('disabled', '');
renderMarkdown();
}, renderDelay);
}
</script>
<style>
.viewer-container {
display: flex;
}
.viewer-container > div {
flex-grow: 1;
margin-left: 10px;
}
#editor {
width: 100%;
border-radius: 0;
}
</style>

View File

@ -0,0 +1,5 @@
<ul>
<?php foreach($reports as $report): ?>
<li><a class="useCursorPointer" onclick="openGenericModal('<?= sprintf('/eventReports/viewSummary/%s', h($report['id'])) ?>')"><?= h($report['name']) ?></a></li>
<?php endforeach; ?>
</ul>

View File

@ -385,7 +385,7 @@ $divider = $this->element('/genericElements/SideMenu/side_menu_divider');
}
break;
case 'event-report':
case 'eventReports':
echo $this->element('/genericElements/SideMenu/side_menu_link', array(
'element_id' => 'index',
'url' => '/eventReports/index',

View File

@ -23,7 +23,8 @@
$action = $this->request->params['action'];
$controller = $this->request->params['controller'];
echo sprintf(
'<div id="genericModal" class="modal hide fade" tabindex="-1" role="dialog" aria-labelledby="genericModalLabel" aria-hidden="true">%s%s%s</div>',
'<div id="genericModal" class="modal %s hide fade" tabindex="-1" role="dialog" aria-labelledby="genericModalLabel" aria-hidden="true">%s%s%s</div>',
isset($type) ? sprintf('modal-%s', $type) : '',
sprintf(
'<div class="modal-header"><button type="button" class="close" data-dismiss="modal" aria-hidden="true">×</button><h3 id="genericModalLabel">%s</h3></div>',
empty($data['title']) ?

View File

@ -3,7 +3,7 @@
echo $this->element('genericElements/Form/genericForm', array(
'form' => $this->Form,
'data' => array(
'title' => $action == 'add' ? __('Add Event Report') : __('Edit Event Report'),
'title' => $action == 'add' ? __('Add Event Report (event %s)', h($event_id)) : __('Edit Event Report (event %s)', h($event_id)),
'model' => 'EventReport',
'fields' => array(
array(
@ -26,7 +26,7 @@
),
array(
'field' => 'content',
'class' => 'textarea'
'class' => 'textarea input span6'
),
array(
'field' => 'event_id',

View File

@ -68,6 +68,6 @@
));
if(!$embedded_view) {
echo '</div>';
echo $this->element('/genericElements/SideMenu/side_menu', array('menuList' => 'event-report', 'menuItem' => 'index'));
echo $this->element('/genericElements/SideMenu/side_menu', array('menuList' => 'eventReports', 'menuItem' => 'index'));
}
?>

View File

@ -0,0 +1,49 @@
<?php
$table_data = array();
$table_data[] = array('key' => __('ID'), 'value' => $report['EventReport']['id']);
$table_data[] = array('key' => __('UUID'), 'value' => $report['EventReport']['uuid']);
$table_data[] = array('key' => __('Name'), 'value' => $report['EventReport']['name']);
$table_data[] = array(
'key' => __('Distribution'),
'value_class' => ($report['EventReport']['distribution'] == 0) ? 'privateRedText' : '',
'html' => sprintf('%s',
($report['EventReport']['distribution'] == 4) ?
sprintf('<a href="%s%s">%s</a>', $baseurl . '/sharing_groups/view/', h($report['SharingGroup']['id']), h($report['SharingGroup']['name'])) :
h($distributionLevels[$report['EventReport']['distribution']])
)
);
$table_data[] = array('key' => __('Timestamp'), 'value' => $report['EventReport']['timestamp']);
$table_data[] = array('key' => __('Deleted'), 'value' => $report['EventReport']['deleted'] ? __('Yes') : __('No'));
?>
<div class='<?= !isset($ajax) || !$ajax ? 'view' : '' ?>'>
<div class="row-fluid">
<h2><?= h($report['EventReport']['name']) ?></h2>
<div class="span8" style="margin-bottom: 10px;">
<?php echo $this->element('genericElements/viewMetaTable', array('table_data' => $table_data)); ?>
</div>
<div class="clear">
<h4>
<?= __('Event Report content') ?>
</h4>
<?= $this->element('EventReports/markdownViewer', array(
'markdown' => $report['EventReport']['content'],
'modelName' => 'EventReport',
'mardownModelFieldName' => 'content',
)) ?>
</div>
</div>
</div>
<script type="text/javascript">
$(document).ready(function () {
});
</script>
<?php
if (!isset($ajax) || !$ajax) {
echo $this->element('/genericElements/SideMenu/side_menu', array('menuList' => 'eventReports', 'menuItem' => 'view'));
}
?>

View File

@ -0,0 +1,15 @@
<?php
$data = array(
'title' => __('Event report: %s', h($report['EventReport']['name'])),
'content' => array(
array(
'html' => $this->element('EventReports/markdownViewer', array(
'markdown' => $report['EventReport']['content'],
'modelName' => 'EventReport',
'mardownModelFieldName' => 'content',
))
),
)
);
echo $this->element('genericElements/infoModal', array('data' => $data, 'type' => 'xl'));
?>

View File

@ -366,6 +366,17 @@
</div>
<?php endif; ?>
<?php if (!empty($event['EventReport'])): ?>
<h3><?php echo __('Event Reports');?></h3>
<div class="inline correlation-container">
<?=
$this->element('/EventReports/quickIndex', array(
'reports' => $event['EventReport']
))
?>
</div>
<?php endif; ?>
<?php
if (!empty($event['RelatedEvent'])):
?>
@ -517,9 +528,6 @@
<button class="btn btn-inverse toggle qet galaxy-toggle-button" id="attackmatrix_toggle" data-toggle-type="attackmatrix" onclick="enable_attack_matrix();">
<span class="icon-plus icon-white" title="<?php echo __('Toggle ATT&CK matrix');?>" role="button" tabindex="0" aria-label="<?php echo __('Toggle ATT&CK matrix');?>" style="vertical-align:top;"></span><?php echo __('ATT&CK matrix');?>
</button>
<button class="btn btn-inverse toggle qet galaxy-toggle-button" id="report_toggle" data-toggle-type="eventreport" onclick="enable_event_report();">
<span class="icon-plus icon-white" title="<?php echo __('Toggle Event report');?>" role="button" tabindex="0" aria-label="<?php echo __('Toggle Event report');?>" style="vertical-align:top;"></span><?php echo __('Event report');?>
</button>
<button class="btn btn-inverse toggle qet galaxy-toggle-button" id="attributes_toggle" data-toggle-type="attributes">
<span class="icon-minus icon-white" title="<?php echo __('Toggle attributes');?>" role="button" tabindex="0" aria-label="<?php echo __('Toggle attributes');?>" style="vertical-align:top;"></span><?php echo __('Attributes');?>
</button>

View File

@ -954,6 +954,12 @@ a.proposal_link_red:hover {
z-index:5;
}
.modal.modal-xl {
width: 90%;
left: 5%;
margin-left: 0px;
}
.ajax_popover_form_large {
width: 1400px;
left: calc(50% - 700px);

File diff suppressed because one or more lines are too long