mirror of https://github.com/MISP/MISP
chg: [clusterRelations] Moved relation_tree into its own `tool` and
added modal support for galaxyQuickViewpull/6120/head
parent
52a89a2507
commit
4c0e4984e1
|
@ -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());
|
||||
}
|
||||
|
|
|
@ -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');
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
}
|
|
@ -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>
|
||||
|
|
|
@ -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>
|
||||
|
|
|
@ -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" />
|
||||
|
|
|
@ -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();
|
||||
();
|
||||
}
|
||||
}
|
||||
});
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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);
|
||||
|
|
Loading…
Reference in New Issue