chg: [clusterRelations] Moved relation_tree into its own `tool` and

added modal support for galaxyQuickView
pull/6120/head
mokaddem 2020-05-13 11:01:16 +02:00
parent 52a89a2507
commit 4c0e4984e1
No known key found for this signature in database
GPG Key ID: 164C473F627A06FA
9 changed files with 169 additions and 55 deletions

View File

@ -517,7 +517,7 @@ class GalaxiesController extends AppController
'recursive' => -1,
'conditions' => array('Galaxy.id' => $galaxyId)
));
$tree = $this->Galaxy->generateForkTree($clusters, $galaxy, $pruneRootLeaves=true); // moved this to Lib/Tool
$tree = $this->Galaxy->generateForkTree($clusters, $galaxy, $pruneRootLeaves=true);
if ($this->_isRest()) {
return $this->RestResponse->viewData($tree, $this->response->type());
}

View File

@ -834,41 +834,11 @@ class GalaxyClustersController extends AppController
$cluster = $this->GalaxyCluster->attachReferencingRelations($this->Auth->user(), $cluster);
$cluster = $this->GalaxyCluster->attachClusterToRelations($this->Auth->user(), $cluster);
$treeRight = array(array(
'GalaxyCluster' => $cluster['GalaxyCluster'],
'children' => array()
));
// add relation info between the two clusters
foreach($cluster['GalaxyClusterRelation'] as $relation) {
$tmp = array(
'Relation' => array_diff_key($relation, array_flip(array('GalaxyCluster'))),
'children' => array(
array('GalaxyCluster' => $relation['GalaxyCluster']),
)
);
$treeRight[0]['children'][] = $tmp;
}
App::uses('ClusterRelationsTreeTool', 'Tools');
$grapher = new ClusterRelationsTreeTool();
$grapher->construct($this->Auth->user(), $this->GalaxyCluster);
$tree = $grapher->getTree($cluster);
$treeLeft = array(array(
'GalaxyCluster' => $cluster['GalaxyCluster'],
'children' => array()
));
if (!empty($cluster['ReferencingGalaxyClusterRelation'])) {
foreach($cluster['ReferencingGalaxyClusterRelation'] as $relation) {
$tmp = array(
'Relation' => array_diff_key($relation, array_flip(array('GalaxyCluster'))),
'children' => array(
array('GalaxyCluster' => $relation['GalaxyCluster']),
)
);
$treeLeft[0]['children'][] = $tmp;
}
}
$tree = array(
'right' => $treeRight,
'left' => $treeLeft,
);
$this->set('existingRelations', $existingRelations);
$this->set('cluster', $cluster);
$relations = $this->GalaxyCluster->GalaxyClusterRelation->fetchRelations($this->Auth->user(), array(
@ -885,4 +855,22 @@ class GalaxyClustersController extends AppController
unset($distributionLevels[5]);
$this->set('distributionLevels', $distributionLevels);
}
public function viewRelationTree($clusterId)
{
$options = array('conditions' => array('GalaxyCluster.id' => $clusterId));
$cluster = $this->GalaxyCluster->fetchGalaxyClusters($this->Auth->user(), $options, true);
if (empty($cluster)) {
throw new NotFoundException('Invalid galaxy cluster');
}
$cluster = $cluster[0];
$cluster = $this->GalaxyCluster->attachReferencingRelations($this->Auth->user(), $cluster);
$cluster = $this->GalaxyCluster->attachClusterToRelations($this->Auth->user(), $cluster);
App::uses('ClusterRelationsTreeTool', 'Tools');
$grapher = new ClusterRelationsTreeTool();
$grapher->construct($this->Auth->user(), $this->GalaxyCluster);
$tree = $grapher->getTree($cluster);
$this->set('tree', $tree);
$this->render('/Elements/GalaxyClusters/view_relation_tree');
}
}

View File

@ -0,0 +1,78 @@
<?php
class ClusterRelationsTreeTool
{
private $GalaxyCluster = false;
private $user = false;
private $lookup = array();
public function construct($user, $GalaxyCluster)
{
$this->GalaxyCluster = $GalaxyCluster;
$this->user = $user;
return true;
}
public function getTree($cluster)
{
$treeRight = array(array(
'GalaxyCluster' => $cluster['GalaxyCluster'],
'children' => array()
));
// add relation info between the two clusters
foreach($cluster['GalaxyClusterRelation'] as $relation) {
$tmp = array(
'Relation' => array_diff_key($relation, array_flip(array('GalaxyCluster'))),
'children' => array(
array('GalaxyCluster' => $relation['GalaxyCluster']),
)
);
$treeRight[0]['children'][] = $tmp;
}
$treeLeft = array(array(
'GalaxyCluster' => $cluster['GalaxyCluster'],
'children' => array()
));
if (!empty($cluster['ReferencingGalaxyClusterRelation'])) {
foreach($cluster['ReferencingGalaxyClusterRelation'] as $relation) {
$tmp = array(
'Relation' => array_diff_key($relation, array_flip(array('GalaxyCluster'))),
'children' => array(
array('GalaxyCluster' => $relation['GalaxyCluster']),
)
);
$treeLeft[0]['children'][] = $tmp;
}
}
$tree = array(
'right' => $treeRight,
'left' => $treeLeft,
);
return $tree;
}
private function attachOwnerInsideCluster($cluster)
{
if (!empty($cluster['Org']) && !isset($cluster['GalaxyCluster']['Org'])) {
$cluster['GalaxyCluster']['Org'] = array(
'id' => $cluster['Org']['id'],
'name' => $cluster['Org']['name'],
);
}
if (!empty($cluster['Orgc']) && !isset($cluster['GalaxyCluster']['Orgc'])) {
$cluster['GalaxyCluster']['Orgc'] = array(
'id' => $cluster['Orgc']['id'],
'name' => $cluster['Orgc']['name'],
);
}
if (!empty($cluster['SharingGroup']) && !isset($cluster['GalaxyCluster']['SharingGroup'])) {
$cluster['GalaxyCluster']['SharingGroup'] = array(
'id' => $cluster['SharingGroup']['id'],
'name' => $cluster['SharingGroup']['name'],
'description' => $cluster['SharingGroup']['description'],
);
}
return $cluster;
}
}

View File

@ -4,8 +4,8 @@ echo $this->element('genericElements/assetLoader', array(
));
?>
<div style="padding: 5px; min-height: 600px;">
<svg id="treeSVG" style="width: 100%; height: 100%; min-height: 500px;"></svg>
<div style="padding: 5px; display: flex; position: absolute; top: 0; left: 0; right: 0; bottom: 0;">
<svg id="treeSVG" style="width: 100%; height: 100%;"></svg>
</div>
<script>

View File

@ -64,8 +64,9 @@
echo sprintf(
'<div class="large-left-margin">%s %s %s %s</div>',
sprintf(
'<span class="bold blue expandable useCursorPointer" data-toggle="popover" data-content="%s">%s</span>',
'<span class="bold blue expandable useCursorPointer" data-content="%s" data-clusterid="%s">%s</span>',
h($popover_data),
h($cluster['id']),
sprintf(
'<span><i class="fas fa-%s"></i> %s</span>',
$cluster['local'] ? 'user' : 'globe-americas',
@ -138,9 +139,31 @@
<script type="text/javascript">
$(document).ready(function () {
$('<?= isset($rowId) ? '#'.$rowId : '' ?> .expandable').popover({
$('<?= isset($rowId) ? '#'.$rowId : '' ?> .expandable')
.on('click', function() {
loadClusterRelations($(this).data('clusterid'));
})
.popover({
html: true,
trigger: 'hover'
});
});
function loadClusterRelations(clusterId) {
if (clusterId !== undefined) {
openGenericModal(
'<?= $baseurl ?>/GalaxyClusters/viewRelationTree/' + clusterId,
{
header: "<?= __('Cluster relation tree') ?>",
classes: "modal-xl",
bodyStyle: {"min-height": "500px"}
},
function() {
if (window.buildTree !== undefined) {
buildTree();
}
}
);
}
}
</script>

View File

@ -517,9 +517,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="clusterrelation_toggle" data-toggle-type="clusterrelation" onclick="enable_galaxy_relations();">
<span class="icon-plus icon-white" title="<?php echo __('Toggle Cluster relationships');?>" role="button" tabindex="0" aria-label="<?php echo __('Toggle Cluster relationships');?>" style="vertical-align:top;"></span><?php echo __('Cluster relations');?>
</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>
@ -585,13 +582,5 @@ function enable_attack_matrix() {
$("#attackmatrix_div").html(data);
});
}
function enable_galaxy_relations() {
if ($("#clusterrelation_div").find('svg').length == 0) {
$.get("<?= $baseurl ?>/events/viewClusterRelations/<?php echo h($event['Event']['id']); ?>", function(data) {
$("#clusterrelation_div").html(data);
});
}
}
</script>
<input type="hidden" value="/shortcuts/event_view.json" class="keyboardShortcutsConfig" />

View File

@ -151,7 +151,9 @@
</form>
</div>
</div>
<?php echo $this->element('GalaxyClusters/view_relation_tree'); ?>
<div style="min-height: 600px; position: relative;">
<?php echo $this->element('GalaxyClusters/view_relation_tree'); ?>
</div>
</div>
<div id="referencesTable_div" style="position: relative;" class="statistics_attack_matrix hidden">
<?= $relationTable ?>
@ -163,7 +165,7 @@ function toggleClusterRelations() {
duration: 300,
complete: function() {
if (window.buildTree !== undefined) {
buildTree();
();
}
}
});

View File

@ -941,6 +941,10 @@ a.proposal_link_red:hover {
.modal-body-long {
max-height: 600px;
}
.modal-xl {
width: 1000px;
margin-left: -500px;
}
.ajax_popover_form {
display:none;

View File

@ -1170,14 +1170,44 @@ function clickCreateButton(event, type) {
simplePopup("/" + destination + "/add/" + event);
}
function openGenericModal(url) {
function openGenericModal(url, modalData, callback) {
$.ajax({
type: "get",
url: url,
success: function (data) {
$('#genericModal').remove();
$('body').append(data);
$('#genericModal').modal();
if (modalData !== undefined) {
$modal = $('<div id="genericModal" class="modal hide fade" tabindex="-1" role="dialog" aria-labelledby="genericModalLabel" aria-hidden="true"></div>');
if (modalData.classes !== undefined) {
$modal.addClass(modalData.classes);
}
$modalHeaderText = $('<h3 id="genericModalLabel"></h3>');
if (modalData.header !== undefined) {
$modalHeaderText.text(modalData.header)
}
$modalHeader = $('<div class="modal-header"></div>').append(
$('<button type="button" class="close" data-dismiss="modal" aria-hidden="true">×</button>'),
$modalHeaderText
);
$modalBody = $('<div class="modal-body"></div>').html(data);
if (modalData.bodyStyle !== undefined) {
$modalBody.css(modalData.bodyStyle);
}
$modal.append(
$modalHeader,
$modalBody
);
htmlData = $modal[0].outerHTML;
} else {
htmlData = data;
}
$('body').append(htmlData);
$('#genericModal').modal().on('shown', function() {
if (callback !== undefined) {
callback();
}
});
},
error: function (data, textStatus, errorThrown) {
showMessage('fail', textStatus + ": " + errorThrown);