2016-12-05 00:47:34 +01:00
|
|
|
<?php
|
|
|
|
App::uses('AppController', 'Controller');
|
|
|
|
|
2018-07-19 11:48:22 +02:00
|
|
|
class GalaxyClustersController extends AppController
|
|
|
|
{
|
|
|
|
public $components = array('Session', 'RequestHandler');
|
2016-12-05 00:47:34 +01:00
|
|
|
|
2018-07-19 11:48:22 +02:00
|
|
|
public $paginate = array(
|
|
|
|
'limit' => 60,
|
2019-02-10 13:08:12 +01:00
|
|
|
'maxLimit' => 9999, // LATER we will bump here on a problem once we have more than 9999 events <- no we won't, this is the max a user van view/page.
|
2018-07-19 11:48:22 +02:00
|
|
|
'recursive' => -1,
|
|
|
|
'order' => array(
|
|
|
|
'GalaxyCluster.value' => 'ASC'
|
|
|
|
),
|
|
|
|
'contain' => array(
|
|
|
|
'Tag' => array(
|
|
|
|
'fields' => array('Tag.id'),
|
|
|
|
/*
|
|
|
|
'EventTag' => array(
|
|
|
|
'fields' => array('EventTag.event_id')
|
|
|
|
),
|
|
|
|
'AttributeTag' => array(
|
|
|
|
'fields' => array('AttributeTag.event_id', 'AttributeTag.attribute_id')
|
|
|
|
)
|
|
|
|
*/
|
|
|
|
),
|
|
|
|
'GalaxyElement' => array(
|
|
|
|
'conditions' => array('GalaxyElement.key' => 'synonyms'),
|
|
|
|
'fields' => array('value')
|
|
|
|
),
|
|
|
|
)
|
|
|
|
);
|
2016-12-05 00:47:34 +01:00
|
|
|
|
2018-07-19 11:48:22 +02:00
|
|
|
public function index($id)
|
|
|
|
{
|
2020-03-12 13:39:50 +01:00
|
|
|
$filters = $this->IndexFilter->harvestParameters(array('context', 'searchall'));
|
2020-04-15 08:46:21 +02:00
|
|
|
$aclConditions = $this->GalaxyCluster->buildConditions($this->Auth->user());
|
2020-03-12 13:39:50 +01:00
|
|
|
$contextConditions = array();
|
|
|
|
if (empty($filters['context'])) {
|
|
|
|
$filters['context'] = 'all';
|
2020-04-15 08:46:21 +02:00
|
|
|
} else {
|
|
|
|
$contextConditions = array();
|
|
|
|
if ($filters['context'] == 'default') {
|
|
|
|
$contextConditions = array(
|
2020-04-15 11:49:50 +02:00
|
|
|
'GalaxyCluster.default' => true
|
2020-04-15 08:46:21 +02:00
|
|
|
);
|
2020-04-15 11:49:50 +02:00
|
|
|
} elseif ($filters['context'] == 'custom') {
|
2020-04-15 08:46:21 +02:00
|
|
|
$contextConditions = array(
|
2020-04-15 11:49:50 +02:00
|
|
|
'GalaxyCluster.default' => false
|
2020-04-15 08:46:21 +02:00
|
|
|
);
|
2020-04-15 11:49:50 +02:00
|
|
|
} elseif ($filters['context'] == 'org') {
|
2020-04-15 08:46:21 +02:00
|
|
|
$contextConditions = array(
|
2020-04-15 11:49:50 +02:00
|
|
|
'GalaxyCluster.org_id' => $this->Auth->user('org_id')
|
2020-04-15 08:46:21 +02:00
|
|
|
);
|
|
|
|
}
|
2020-03-12 13:39:50 +01:00
|
|
|
}
|
2020-04-15 08:46:21 +02:00
|
|
|
$this->set('passedArgsArray', array('context' => $filters['context'], 'searchall' => isset($filters['searchall']) ? $filters['searchall'] : ''));
|
2020-03-12 13:39:50 +01:00
|
|
|
$this->set('context', $filters['context']);
|
2020-04-15 08:46:21 +02:00
|
|
|
$searchConditions = array();
|
|
|
|
if (empty($filters['searchall'])) {
|
|
|
|
$filters['searchall'] = '';
|
|
|
|
}
|
|
|
|
if (strlen($filters['searchall']) > 0) {
|
|
|
|
$searchall = '%' . strtolower($filters['searchall']) . '%';
|
2018-07-19 11:48:22 +02:00
|
|
|
$synonym_hits = $this->GalaxyCluster->GalaxyElement->find(
|
|
|
|
'list',
|
|
|
|
array(
|
|
|
|
'recursive' => -1,
|
|
|
|
'conditions' => array(
|
2020-04-15 08:46:21 +02:00
|
|
|
'LOWER(GalaxyElement.value) LIKE' => $searchall,
|
2018-07-19 11:48:22 +02:00
|
|
|
'GalaxyElement.key' => 'synonyms' ),
|
|
|
|
'fields' => array(
|
|
|
|
'GalaxyElement.galaxy_cluster_id')
|
|
|
|
)
|
|
|
|
);
|
2020-04-15 08:46:21 +02:00
|
|
|
$searchConditions = array(
|
|
|
|
'OR' => array(
|
|
|
|
'LOWER(GalaxyCluster.value) LIKE' => $searchall,
|
|
|
|
'LOWER(GalaxyCluster.description) LIKE' => $searchall,
|
|
|
|
'GalaxyCluster.uuid' => $filters['searchall'],
|
|
|
|
'GalaxyCluster.id' => array_values($synonym_hits),
|
|
|
|
),
|
|
|
|
);
|
2018-07-19 11:48:22 +02:00
|
|
|
}
|
2020-04-15 08:46:21 +02:00
|
|
|
$searchConditions['GalaxyCluster.galaxy_id'] = $id;
|
|
|
|
|
|
|
|
if ($this->_isRest()) {
|
|
|
|
$clusters = $this->Galaxy->find('all',
|
|
|
|
array(
|
|
|
|
// 'recursive' => -1,
|
|
|
|
'conditions' => array(
|
|
|
|
'AND' => array($contextConditions, $searchConditions, $aclConditions)
|
|
|
|
),
|
|
|
|
)
|
|
|
|
);
|
|
|
|
return $this->RestResponse->viewData($galaxies, $this->response->type());
|
|
|
|
} else {
|
|
|
|
$this->paginate['conditions']['AND'][] = $contextConditions;
|
|
|
|
$this->paginate['conditions']['AND'][] = $searchConditions;
|
|
|
|
$this->paginate['conditions']['AND'][] = $aclConditions;
|
2020-05-29 10:26:11 +02:00
|
|
|
$this->paginate['contain'] = array_merge($this->paginate['contain'], array('Org', 'Orgc', 'SharingGroup', 'GalaxyClusterRelation', 'TargettingClusterRelation'));
|
2020-04-15 08:46:21 +02:00
|
|
|
$clusters = $this->paginate();
|
|
|
|
foreach ($clusters as $k => $cluster) {
|
2020-04-15 15:35:52 +02:00
|
|
|
$clusters[$k] = $this->GalaxyCluster->attachExtendByInfo($this->Auth->user(), $clusters[$k]);
|
|
|
|
$clusters[$k] = $this->GalaxyCluster->attachExtendFromInfo($this->Auth->user(), $clusters[$k]);
|
2018-07-19 11:48:22 +02:00
|
|
|
}
|
2020-04-15 08:46:21 +02:00
|
|
|
$sgs = $this->GalaxyCluster->Tag->EventTag->Event->SharingGroup->fetchAllAuthorised($this->Auth->user());
|
|
|
|
foreach ($clusters as $k => $cluster) {
|
|
|
|
if (!empty($cluster['Tag']['id'])) {
|
|
|
|
$clusters[$k]['GalaxyCluster']['event_count'] = $this->GalaxyCluster->Tag->EventTag->countForTag($cluster['Tag']['id'], $this->Auth->user(), $sgs);
|
|
|
|
} else {
|
|
|
|
$clusters[$k]['GalaxyCluster']['event_count'] = 0;
|
2018-07-19 11:48:22 +02:00
|
|
|
}
|
2020-05-29 10:26:11 +02:00
|
|
|
$clusters[$k]['GalaxyCluster']['relation_counts'] = array(
|
|
|
|
'out' => count($clusters[$k]['GalaxyClusterRelation']),
|
|
|
|
'in' => count($clusters[$k]['TargettingClusterRelation']),
|
|
|
|
);
|
2018-07-19 11:48:22 +02:00
|
|
|
}
|
2020-04-15 08:46:21 +02:00
|
|
|
$tagIds = array();
|
|
|
|
$sightings = array();
|
|
|
|
if (!empty($clusters)) {
|
|
|
|
$galaxyType = $clusters[0]['GalaxyCluster']['type'];
|
|
|
|
foreach ($clusters as $k => $v) {
|
|
|
|
$clusters[$k]['event_ids'] = array();
|
|
|
|
if (!empty($v['Tag'])) {
|
|
|
|
$tagIds[] = $v['Tag']['id'];
|
|
|
|
$clusters[$k]['GalaxyCluster']['tag_id'] = $v['Tag']['id'];
|
|
|
|
}
|
|
|
|
$clusters[$k]['GalaxyCluster']['synonyms'] = array();
|
|
|
|
foreach ($v['GalaxyElement'] as $element) {
|
|
|
|
$clusters[$k]['GalaxyCluster']['synonyms'][] = $element['value'];
|
|
|
|
}
|
|
|
|
}
|
2018-07-19 11:48:22 +02:00
|
|
|
}
|
2020-04-15 08:46:21 +02:00
|
|
|
$this->loadModel('Sighting');
|
|
|
|
$sightings['tags'] = array();
|
|
|
|
foreach ($clusters as $k => $cluster) {
|
|
|
|
if (!empty($cluster['GalaxyCluster']['tag_id'])) {
|
|
|
|
$temp = $this->Sighting->getSightingsForTag($this->Auth->user(), $cluster['GalaxyCluster']['tag_id']);
|
|
|
|
$clusters[$k]['sightings'] = $temp;
|
2018-07-19 11:48:22 +02:00
|
|
|
}
|
2020-04-15 08:46:21 +02:00
|
|
|
}
|
|
|
|
$csv = array();
|
|
|
|
foreach ($clusters as $k => $cluster) {
|
|
|
|
$startDate = !empty($cluster['sightings']) ? min(array_keys($cluster['sightings'])) : date('Y-m-d');
|
|
|
|
$startDate = date('Y-m-d', strtotime("-3 days", strtotime($startDate)));
|
|
|
|
$to = date('Y-m-d', time());
|
|
|
|
for ($date = $startDate; strtotime($date) <= strtotime($to); $date = date('Y-m-d', strtotime("+1 day", strtotime($date)))) {
|
|
|
|
if (!isset($csv[$k])) {
|
|
|
|
$csv[$k] = 'Date,Close\n';
|
|
|
|
}
|
|
|
|
if (isset($cluster['sightings'][$date])) {
|
|
|
|
$csv[$k] .= $date . ',' . $cluster['sightings'][$date] . '\n';
|
|
|
|
} else {
|
|
|
|
$csv[$k] .= $date . ',0\n';
|
|
|
|
}
|
2018-07-19 11:48:22 +02:00
|
|
|
}
|
|
|
|
}
|
2020-04-15 08:46:21 +02:00
|
|
|
$this->loadModel('Attribute');
|
|
|
|
$distributionLevels = $this->Attribute->distributionLevels;
|
|
|
|
unset($distributionLevels[5]);
|
|
|
|
$this->set('distributionLevels', $distributionLevels);
|
|
|
|
$this->set('csv', $csv);
|
|
|
|
$this->set('list', $clusters);
|
|
|
|
$this->set('galaxy_id', $id);
|
2018-07-19 11:48:22 +02:00
|
|
|
}
|
|
|
|
if ($this->request->is('ajax')) {
|
|
|
|
$this->layout = 'ajax';
|
|
|
|
$this->render('ajax/index');
|
|
|
|
}
|
|
|
|
}
|
2016-12-22 17:30:27 +01:00
|
|
|
|
2018-07-19 11:48:22 +02:00
|
|
|
public function view($id)
|
|
|
|
{
|
2020-04-14 15:14:18 +02:00
|
|
|
$conditions = array();
|
2018-11-23 14:11:33 +01:00
|
|
|
if (Validation::uuid($id)) {
|
2020-04-14 15:14:18 +02:00
|
|
|
$conditions['GalaxyCluster.uuid'] = $id;
|
|
|
|
} else {
|
|
|
|
$conditions['GalaxyCluster.id'] = $id;
|
2018-11-23 14:11:33 +01:00
|
|
|
}
|
2020-04-21 11:51:14 +02:00
|
|
|
$contain = array('Galaxy', 'Orgc', 'Org');
|
2020-04-15 08:46:21 +02:00
|
|
|
if ($this->_isRest()) {
|
|
|
|
$contain[] = 'GalaxyElement';
|
|
|
|
}
|
2020-04-14 15:14:18 +02:00
|
|
|
$options = array(
|
2020-04-15 08:46:21 +02:00
|
|
|
'conditions' => $conditions,
|
2020-05-25 10:04:07 +02:00
|
|
|
// 'contain' => $contain
|
2020-04-14 15:14:18 +02:00
|
|
|
);
|
2020-04-15 08:46:21 +02:00
|
|
|
$cluster = $this->GalaxyCluster->fetchGalaxyClusters($this->Auth->user(), $options, $full=true);
|
2018-07-19 11:48:22 +02:00
|
|
|
if (!empty($cluster)) {
|
2020-04-14 15:14:18 +02:00
|
|
|
$cluster = $cluster[0];
|
2018-07-19 11:48:22 +02:00
|
|
|
$this->loadModel('Tag');
|
|
|
|
$tag = $this->Tag->find('first', array(
|
2020-06-01 17:45:53 +02:00
|
|
|
'conditions' => array(
|
|
|
|
'LOWER(name)' => strtolower($cluster['GalaxyCluster']['tag_name']),
|
|
|
|
),
|
|
|
|
'fields' => array('id'),
|
|
|
|
'recursive' => -1,
|
|
|
|
'contain' => array('EventTag.tag_id')
|
2018-07-19 11:48:22 +02:00
|
|
|
));
|
|
|
|
if (!empty($tag)) {
|
|
|
|
$cluster['GalaxyCluster']['tag_count'] = count($tag['EventTag']);
|
|
|
|
$cluster['GalaxyCluster']['tag_id'] = $tag['Tag']['id'];
|
|
|
|
}
|
2019-02-14 10:30:58 +01:00
|
|
|
} else {
|
|
|
|
throw new NotFoundException('Cluster not found.');
|
2018-07-19 11:48:22 +02:00
|
|
|
}
|
2018-11-23 14:11:33 +01:00
|
|
|
if ($this->_isRest()) {
|
|
|
|
$cluster['GalaxyCluster']['Galaxy'] = $cluster['Galaxy'];
|
|
|
|
$cluster['GalaxyCluster']['GalaxyElement'] = $cluster['GalaxyElement'];
|
2020-05-25 10:04:07 +02:00
|
|
|
return $this->RestResponse->viewData($cluster, $this->response->type());
|
|
|
|
// return $this->RestResponse->viewData(array('GalaxyCluster' => $cluster['GalaxyCluster']), $this->response->type());
|
2018-11-23 14:11:33 +01:00
|
|
|
} else {
|
2020-04-15 15:35:52 +02:00
|
|
|
$cluster = $this->GalaxyCluster->attachExtendByInfo($this->Auth->user(), $cluster);
|
|
|
|
$cluster = $this->GalaxyCluster->attachExtendFromInfo($this->Auth->user(), $cluster);
|
2018-11-23 14:11:33 +01:00
|
|
|
$this->set('id', $id);
|
2020-04-15 08:46:21 +02:00
|
|
|
$this->set('galaxy_id', $cluster['GalaxyCluster']['galaxy_id']);
|
2018-11-23 14:11:33 +01:00
|
|
|
$this->set('cluster', $cluster);
|
2020-04-15 14:50:02 +02:00
|
|
|
$this->set('defaultCluster', $cluster['GalaxyCluster']['default']);
|
2020-05-20 10:33:33 +02:00
|
|
|
if (!empty($cluster['GalaxyCluster']['extended_from'])) {
|
2020-04-30 16:28:47 +02:00
|
|
|
$newVersionAvailable = $cluster['GalaxyCluster']['extended_from']['GalaxyCluster']['version'] > $cluster['GalaxyCluster']['extends_version'];
|
2020-04-30 13:34:21 +02:00
|
|
|
} else {
|
|
|
|
$newVersionAvailable = false;
|
|
|
|
}
|
2020-04-30 08:36:02 +02:00
|
|
|
$this->set('newVersionAvailable', $newVersionAvailable);
|
2020-05-28 15:23:40 +02:00
|
|
|
$this->loadModel('Attribute');
|
|
|
|
$distributionLevels = $this->Attribute->distributionLevels;
|
|
|
|
$this->set('distributionLevels', $distributionLevels);
|
2018-11-23 14:11:33 +01:00
|
|
|
}
|
2018-07-19 11:48:22 +02:00
|
|
|
}
|
2016-12-22 17:30:27 +01:00
|
|
|
|
2020-04-15 11:49:50 +02:00
|
|
|
public function add($galaxyId)
|
|
|
|
{
|
|
|
|
$this->loadModel('Attribute');
|
|
|
|
$distributionLevels = $this->Attribute->distributionLevels;
|
|
|
|
unset($distributionLevels[5]);
|
|
|
|
$initialDistribution = 3;
|
|
|
|
$configuredDistribution = Configure::check('MISP.default_attribute_distribution');
|
|
|
|
if ($configuredDistribution != null && $configuredDistribution != 'event') {
|
|
|
|
$initialDistribution = $configuredDistribution;
|
|
|
|
}
|
|
|
|
$this->loadModel('SharingGroup');
|
|
|
|
$sgs = $this->SharingGroup->fetchAllAuthorised($this->Auth->user(), 'name', 1);
|
|
|
|
|
|
|
|
if (isset($this->params['named']['forkUuid'])) {
|
|
|
|
$forkUuid = $this->params['named']['forkUuid'];
|
|
|
|
$origCluster = $this->GalaxyCluster->fetchGalaxyClusters($this->Auth->user(), array(
|
2020-04-22 08:40:18 +02:00
|
|
|
'conditions' => array('GalaxyCluster.uuid' => $forkUuid),
|
2020-04-15 11:49:50 +02:00
|
|
|
), true);
|
|
|
|
if (!empty($origCluster)) {
|
|
|
|
$origCluster = $origCluster[0];
|
|
|
|
$origClusterMeta = $origCluster['GalaxyCluster'];
|
|
|
|
if (empty($this->request->data)) {
|
|
|
|
$this->request->data = $origCluster;
|
|
|
|
unset($this->request->data['GalaxyCluster']['id']);
|
|
|
|
unset($this->request->data['GalaxyCluster']['uuid']);
|
|
|
|
foreach ($origCluster['GalaxyElement'] as $k => $element) {
|
|
|
|
unset($origCluster['GalaxyElement'][$k]['id']);
|
|
|
|
unset($origCluster['GalaxyElement'][$k]['galaxy_cluster_id']);
|
|
|
|
}
|
2020-06-05 11:00:02 +02:00
|
|
|
$this->request->data['GalaxyCluster']['extends_uuid'] = $origCluster['GalaxyCluster']['uuid'];
|
|
|
|
$this->request->data['GalaxyCluster']['extends_version'] = $origCluster['GalaxyCluster']['version'];
|
2020-04-15 11:49:50 +02:00
|
|
|
$this->request->data['GalaxyCluster']['elements'] = json_encode($origCluster['GalaxyElement']);
|
2020-04-30 13:34:21 +02:00
|
|
|
$this->request->data['GalaxyCluster']['elementsDict'] = $origCluster['GalaxyElement'];
|
2020-04-15 11:49:50 +02:00
|
|
|
$this->request->data['GalaxyCluster']['authors'] = json_encode($origCluster['GalaxyCluster']['authors']);
|
|
|
|
}
|
|
|
|
$this->set('origCluster', $origCluster);
|
|
|
|
$this->set('origClusterMeta', $origClusterMeta);
|
|
|
|
} else {
|
|
|
|
throw new NotFoundException('Forked cluster not found.');
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if ($this->request->is('post') || $this->request->is('put')) {
|
|
|
|
$cluster = $this->request->data;
|
|
|
|
$errors = array();
|
|
|
|
if (empty($cluster['GalaxyCluster']['elements'])) {
|
2020-06-05 11:00:02 +02:00
|
|
|
$cluster['GalaxyCluster']['elements'] = array();
|
2020-04-15 11:49:50 +02:00
|
|
|
} else {
|
|
|
|
$decoded = json_decode($cluster['GalaxyCluster']['elements'], true);
|
2020-06-05 11:00:02 +02:00
|
|
|
if (is_null($decoded)) {
|
|
|
|
$this->GalaxyCluster->validationErrors['values'][] = __('Invalid JSON');
|
|
|
|
$errors[] = sprintf(__('Invalid JSON'));
|
2020-04-15 11:49:50 +02:00
|
|
|
}
|
2020-06-05 11:00:02 +02:00
|
|
|
$cluster['GalaxyCluster']['elements'] = $decoded;
|
2020-04-15 11:49:50 +02:00
|
|
|
}
|
2020-06-05 11:00:02 +02:00
|
|
|
if (!empty($cluster['GalaxyCluster']['extends_uuid'])) {
|
|
|
|
$extendId = $this->Toolbox->findIdByUuid($this->GalaxyCluster, $cluster['GalaxyCluster']['extends_uuid']);
|
|
|
|
$extendedCluster = $this->GalaxyCluster->fetchGalaxyClusters(
|
|
|
|
$this->Auth->user(),
|
|
|
|
array('conditions' => array('GalaxyCluster.id' => $extendId))
|
|
|
|
);
|
|
|
|
if (!empty($extendedCluster)) {
|
|
|
|
$cluster['GalaxyCluster']['extends_uuid'] = $extendedCluster[0]['GalaxyCluster']['uuid'];
|
|
|
|
if (empty($cluster['GalaxyCluster']['extends_version'])) {
|
|
|
|
$cluster['GalaxyCluster']['extends_version'] = $extendedCluster[0]['GalaxyCluster']['version'];
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
$cluster['GalaxyCluster']['extends_uuid'] = '';
|
|
|
|
}
|
2020-04-15 11:49:50 +02:00
|
|
|
} else {
|
|
|
|
$cluster['GalaxyCluster']['extends_uuid'] = '';
|
|
|
|
}
|
|
|
|
if ($cluster['GalaxyCluster']['distribution'] != 4) {
|
|
|
|
$cluster['GalaxyCluster']['sharing_group_id'] = null;
|
|
|
|
}
|
|
|
|
$saveSuccess = $this->GalaxyCluster->saveCluster($this->Auth->user(), $cluster);
|
|
|
|
if (!$saveSuccess) {
|
|
|
|
foreach($this->GalaxyCluster->validationErrors as $validationError) {
|
|
|
|
$errors[] = $validationError;
|
|
|
|
}
|
|
|
|
}
|
2020-06-05 11:00:02 +02:00
|
|
|
|
2020-04-15 11:49:50 +02:00
|
|
|
if (!empty($errors)) {
|
2020-06-05 11:00:02 +02:00
|
|
|
$message = implode(', ', implode(' ', $errors));
|
|
|
|
if ($this->_isRest()) {
|
|
|
|
return $this->RestResponse->saveFailResponse('GalaxyCluster', 'add', $this->GalaxyCluster->id, $message, $this->response->type());
|
|
|
|
} else {
|
|
|
|
$this->Flash->error($message);
|
|
|
|
}
|
2020-04-15 11:49:50 +02:00
|
|
|
} else {
|
2020-06-05 11:00:02 +02:00
|
|
|
$message = __('Galaxy cluster saved');
|
|
|
|
if ($this->_isRest()) {
|
|
|
|
return $this->RestResponse->saveSuccessResponse('GalaxyCluster', 'add', $this->GalaxyCluster->id, $this->response->type());
|
|
|
|
} else {
|
|
|
|
$this->Flash->success($message);
|
|
|
|
$this->redirect(array('controller' => 'galaxy_clusters', 'action' => 'view', $this->GalaxyCluster->id));
|
|
|
|
}
|
2020-04-15 11:49:50 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
$this->set('galaxy_id', $galaxyId);
|
|
|
|
$this->set('distributionLevels', $distributionLevels);
|
|
|
|
$this->set('initialDistribution', $initialDistribution);
|
|
|
|
$this->set('sharingGroups', $sgs);
|
|
|
|
$this->set('action', 'add');
|
|
|
|
}
|
|
|
|
|
|
|
|
public function edit($id)
|
|
|
|
{
|
2020-04-15 14:50:02 +02:00
|
|
|
if (Validation::uuid($id)) {
|
|
|
|
$temp = $this->GalaxyCluster->find('first', array(
|
|
|
|
'recursive' => -1,
|
|
|
|
'fields' => array('GalaxyCluster.id', 'GalaxyCluster.uuid'),
|
|
|
|
'conditions' => array('GalaxyCluster.uuid' => $id)
|
|
|
|
));
|
|
|
|
if ($temp === null) {
|
2020-05-07 15:15:14 +02:00
|
|
|
throw new NotFoundException(__('Invalid galaxy cluster'));
|
2020-04-15 14:50:02 +02:00
|
|
|
}
|
2020-04-20 16:11:18 +02:00
|
|
|
$id = $temp['GalaxyCluster']['id'];
|
2020-04-15 14:50:02 +02:00
|
|
|
} elseif (!is_numeric($id)) {
|
|
|
|
throw new NotFoundException(__('Invalid galaxy cluster'));
|
|
|
|
}
|
|
|
|
$conditions = array('conditions' => array('GalaxyCluster.id' => $id));
|
|
|
|
$cluster = $this->GalaxyCluster->fetchGalaxyClusters($this->Auth->user(), $conditions, true);
|
|
|
|
if (empty($cluster)) {
|
2020-05-07 15:15:14 +02:00
|
|
|
throw new NotFoundException(__('Invalid galaxy cluster'));
|
2020-04-15 14:50:02 +02:00
|
|
|
}
|
|
|
|
$cluster = $cluster[0];
|
|
|
|
if ($cluster['GalaxyCluster']['default']) {
|
|
|
|
throw new MethodNotAllowedException('Default galaxy cluster cannot be edited');
|
|
|
|
}
|
2020-04-21 10:11:26 +02:00
|
|
|
$this->GalaxyCluster->data = array('GalaxyCluster' => $cluster['GalaxyCluster'], 'GalaxyElement' => $cluster['GalaxyElement']);
|
2020-04-15 14:50:02 +02:00
|
|
|
|
|
|
|
$this->loadModel('Attribute');
|
|
|
|
$distributionLevels = $this->Attribute->distributionLevels;
|
|
|
|
unset($distributionLevels[5]);
|
|
|
|
$initialDistribution = 3;
|
|
|
|
$configuredDistribution = Configure::check('MISP.default_attribute_distribution');
|
|
|
|
if ($configuredDistribution != null && $configuredDistribution != 'event') {
|
|
|
|
$initialDistribution = $configuredDistribution;
|
|
|
|
}
|
|
|
|
$this->loadModel('SharingGroup');
|
|
|
|
$sgs = $this->SharingGroup->fetchAllAuthorised($this->Auth->user(), 'name', 1);
|
|
|
|
|
|
|
|
$origCluster = $this->GalaxyCluster->fetchGalaxyClusters($this->Auth->user(), array(
|
|
|
|
'conditions' => array('uuid' => $cluster['GalaxyCluster']['extends_uuid']),
|
|
|
|
), false);
|
|
|
|
|
|
|
|
if (!empty($origCluster)) {
|
|
|
|
$origCluster = $origCluster[0];
|
|
|
|
$this->set('forkUuid', $cluster['GalaxyCluster']['extends_uuid']);
|
|
|
|
$origClusterMeta = $origCluster['GalaxyCluster'];
|
|
|
|
$this->set('origCluster', $origCluster);
|
|
|
|
$this->set('origClusterMeta', $origClusterMeta);
|
|
|
|
}
|
|
|
|
if ($this->request->is('post') || $this->request->is('put')) {
|
|
|
|
$cluster = $this->request->data;
|
|
|
|
$errors = array();
|
|
|
|
if (!isset($cluster['GalaxyCluster']['uuid'])) {
|
|
|
|
$cluster['GalaxyCluster']['uuid'] = $this->GalaxyCluster->data['GalaxyCluster']['uuid']; // freeze the uuid
|
|
|
|
}
|
|
|
|
if (!isset($cluster['GalaxyCluster']['id'])) {
|
|
|
|
$cluster['GalaxyCluster']['id'] = $id;
|
|
|
|
}
|
|
|
|
if (empty($cluster['GalaxyCluster']['elements'])) {
|
|
|
|
$cluster['GalaxyCluster']['elements'] = array();
|
|
|
|
} else {
|
|
|
|
$decoded = json_decode($cluster['GalaxyCluster']['elements'], true);
|
|
|
|
if (is_null($decoded)) {
|
|
|
|
$this->GalaxyCluster->validationErrors['values'][] = __('Invalid JSON');
|
|
|
|
$errors[] = sprintf(__('Invalid JSON'));
|
|
|
|
}
|
|
|
|
$cluster['GalaxyCluster']['elements'] = $decoded;
|
|
|
|
}
|
|
|
|
if (empty($cluster['GalaxyCluster']['authors'])) {
|
|
|
|
$cluster['GalaxyCluster']['authors'] = [];
|
|
|
|
} else {
|
|
|
|
$decoded = json_decode($cluster['GalaxyCluster']['authors'], true);
|
|
|
|
if (is_null($decoded)) { // authors might be comma separated
|
|
|
|
$decoded = array_map('trim', explode(',', $cluster['GalaxyCluster']['authors']));
|
|
|
|
}
|
|
|
|
$cluster['GalaxyCluster']['authors'] = $decoded;
|
|
|
|
}
|
|
|
|
$cluster['GalaxyCluster']['authors'] = json_encode($cluster['GalaxyCluster']['authors']);
|
|
|
|
if (!empty($errors)) {
|
2020-06-05 11:00:02 +02:00
|
|
|
$message = implode(', ', implode(' ', $errors));
|
|
|
|
if ($this->_isRest()) {
|
|
|
|
return $this->RestResponse->saveFailResponse('GalaxyCluster', 'edit', $cluster['GalaxyCluster']['id'], $message, $this->response->type());
|
|
|
|
} else {
|
|
|
|
$this->Flash->error($message);
|
|
|
|
}
|
2020-04-15 14:50:02 +02:00
|
|
|
} else {
|
|
|
|
$errors = $this->GalaxyCluster->editCluster($this->Auth->user(), $cluster);
|
|
|
|
if (!empty($errors)) {
|
2020-06-05 11:00:02 +02:00
|
|
|
$message = implode(', ', implode(' ', $errors));
|
|
|
|
if ($this->_isRest()) {
|
|
|
|
return $this->RestResponse->saveFailResponse('GalaxyCluster', 'edit', $cluster['GalaxyCluster']['id'], $message, $this->response->type());
|
|
|
|
} else {
|
|
|
|
$this->Flash->error($message);
|
|
|
|
}
|
2020-04-15 14:50:02 +02:00
|
|
|
} else {
|
2020-06-05 11:00:02 +02:00
|
|
|
$message = __('Galaxy cluster saved');
|
|
|
|
if ($this->_isRest()) {
|
|
|
|
return $this->RestResponse->saveSuccessResponse('GalaxyCluster', 'edit', $cluster['GalaxyCluster']['id'], $this->response->type());
|
|
|
|
} else {
|
|
|
|
$this->Flash->success($message);
|
|
|
|
$this->redirect(array('controller' => 'galaxy_clusters', 'action' => 'view', $this->GalaxyCluster->id));
|
|
|
|
}
|
2020-04-15 14:50:02 +02:00
|
|
|
}
|
|
|
|
}
|
2020-06-05 11:00:02 +02:00
|
|
|
|
2020-04-15 14:50:02 +02:00
|
|
|
} else {
|
2020-04-21 10:11:26 +02:00
|
|
|
$this->GalaxyCluster->data['GalaxyCluster']['elements'] = json_encode($this->GalaxyCluster->data['GalaxyElement']);
|
2020-04-30 13:34:21 +02:00
|
|
|
$this->GalaxyCluster->data['GalaxyCluster']['elementsDict'] = $this->GalaxyCluster->data['GalaxyElement'];
|
2020-04-15 14:50:02 +02:00
|
|
|
$this->GalaxyCluster->data['GalaxyCluster']['authors'] = json_encode($this->GalaxyCluster->data['GalaxyCluster']['authors']);
|
|
|
|
$this->request->data = $this->GalaxyCluster->data;
|
|
|
|
}
|
|
|
|
$fieldDesc = array(
|
|
|
|
'authors' => __('Valid JSON array or comma separated'),
|
|
|
|
'elements' => __('Valid JSON array composed from Object of the form {key: keyname, value: actualValue}'),
|
|
|
|
'distribution' => Hash::extract($this->Attribute->distributionDescriptions, '{n}.formdesc'),
|
|
|
|
);
|
|
|
|
$this->set('fieldDesc', $fieldDesc);
|
|
|
|
$this->set('distributionLevels', $distributionLevels);
|
|
|
|
$this->set('initialDistribution', $initialDistribution);
|
|
|
|
$this->set('sharingGroups', $sgs);
|
|
|
|
$this->set('galaxy_id', $cluster['GalaxyCluster']['galaxy_id']);
|
|
|
|
$this->set('clusterId', $id);
|
|
|
|
$this->set('defaultCluster', $cluster['GalaxyCluster']['default']);
|
|
|
|
$this->set('action', 'edit');
|
|
|
|
$this->render('add');
|
2020-04-15 11:49:50 +02:00
|
|
|
}
|
|
|
|
|
2018-07-19 11:48:22 +02:00
|
|
|
public function attachToEvent($event_id, $tag_name)
|
|
|
|
{
|
|
|
|
$this->loadModel('Event');
|
|
|
|
$this->Event->id = $event_id;
|
|
|
|
$this->Event->recursive = -1;
|
|
|
|
$event = $this->Event->read(array(), $event_id);
|
|
|
|
if (empty($event)) {
|
|
|
|
throw new MethodNotAllowedException('Invalid Event.');
|
|
|
|
}
|
|
|
|
if (!$this->_isSiteAdmin() && !$this->userRole['perm_sync']) {
|
|
|
|
if (!$this->userRole['perm_tagger'] || ($this->Auth->user('org_id') !== $event['Event']['org_id'] && $this->Auth->user('org_id') !== $event['Event']['orgc_id'])) {
|
|
|
|
throw new MethodNotAllowedException('Invalid Event.');
|
|
|
|
}
|
|
|
|
}
|
|
|
|
$tag = $this->Event->EventTag->Tag->find('first', array('conditions' => array('Tag.name' => $tag_name), 'recursive' => -1));
|
|
|
|
if (empty($tag)) {
|
|
|
|
$this->Event->EventTag->Tag->create();
|
|
|
|
$this->Event->EventTag->Tag->save(array('name' => $tag_name, 'colour' => '#0088cc', 'exportable' => 1));
|
|
|
|
$tag_id = $this->Event->EventTag->Tag->id;
|
|
|
|
} else {
|
|
|
|
$tag_id = $tag['Tag']['id'];
|
|
|
|
}
|
|
|
|
$existingEventTag = $this->Event->EventTag->find('first', array('conditions' => array('EventTag.tag_id' => $tag_id, 'EventTag.event_id' => $event_id), 'recursive' => -1));
|
|
|
|
if (empty($existingEventTag)) {
|
|
|
|
$cluster = $this->GalaxyCluster->find('first', array(
|
|
|
|
'recursive' => -1,
|
|
|
|
'conditions' => array('GalaxyCluster.tag_name' => $existingEventTag['Tag']['name'])
|
|
|
|
));
|
|
|
|
$this->Event->EventTag->create();
|
|
|
|
$this->Event->EventTag->save(array('EventTag.tag_id' => $tag_id, 'EventTag.event_id' => $event_id));
|
|
|
|
$this->Log = ClassRegistry::init('Log');
|
|
|
|
$this->Log->create();
|
|
|
|
$this->Log->save(array(
|
|
|
|
'org' => $this->Auth->user('Organisation')['name'],
|
|
|
|
'model' => 'Event',
|
|
|
|
'model_id' => $event_id,
|
|
|
|
'email' => $this->Auth->user('email'),
|
|
|
|
'action' => 'galaxy',
|
|
|
|
'title' => 'Attached ' . $cluster['GalaxyCluster']['value'] . ' (' . $cluster['GalaxyCluster']['id'] . ') to event (' . $event_id . ')',
|
|
|
|
'change' => ''
|
|
|
|
));
|
|
|
|
$event['Event']['published'] = 0;
|
|
|
|
$date = new DateTime();
|
|
|
|
$event['Event']['timestamp'] = $date->getTimestamp();
|
|
|
|
$this->Event->save($event);
|
|
|
|
$this->Flash->success('Galaxy attached.');
|
|
|
|
} else {
|
|
|
|
$this->Flash->error('Galaxy already attached.');
|
|
|
|
}
|
|
|
|
$this->redirect($this->referer());
|
|
|
|
}
|
2016-12-22 17:30:27 +01:00
|
|
|
|
2018-07-19 11:48:22 +02:00
|
|
|
public function detach($target_id, $target_type, $tag_id)
|
|
|
|
{
|
|
|
|
$this->loadModel('Event');
|
|
|
|
if ($target_type == 'attribute') {
|
|
|
|
$attribute = $this->Event->Attribute->find('first', array(
|
|
|
|
'recursive' => -1,
|
|
|
|
'fields' => array('id', 'event_id'),
|
|
|
|
'conditions' => array('Attribute.id' => $target_id)
|
|
|
|
));
|
|
|
|
if (empty($attribute)) {
|
|
|
|
throw new MethodNotAllowedException('Invalid Attribute.');
|
|
|
|
}
|
|
|
|
$event_id = $attribute['Attribute']['event_id'];
|
|
|
|
} elseif ($target_type == 'event') {
|
|
|
|
$event_id = $target_id;
|
2019-01-16 15:59:49 +01:00
|
|
|
} elseif ($target_type === 'tag_collection') {
|
2019-01-17 09:29:35 +01:00
|
|
|
// pass
|
2018-07-19 11:48:22 +02:00
|
|
|
} else {
|
|
|
|
throw new MethodNotAllowedException('Invalid options');
|
|
|
|
}
|
2019-01-17 09:29:35 +01:00
|
|
|
|
|
|
|
if ($target_type === 'tag_collection') {
|
|
|
|
$tag_collection = $this->GalaxyCluster->Tag->TagCollectionTag->TagCollection->fetchTagCollection($this->Auth->user(), array(
|
|
|
|
'conditions' => array('TagCollection.id' => $target_id),
|
|
|
|
'contain' => array('Organisation', 'TagCollectionTag' => array('Tag'))
|
|
|
|
));
|
|
|
|
if (empty($tag_collection)) {
|
|
|
|
throw new MethodNotAllowedException('Invalid Tag Collection');
|
|
|
|
}
|
|
|
|
$tag_collection = $tag_collection[0];
|
2019-01-18 11:57:04 +01:00
|
|
|
if (!$this->_isSiteAdmin()) {
|
|
|
|
if (!$this->userRole['perm_tag_editor'] || $this->Auth->user('org_id') !== $tag_collection['TagCollection']['org_id']) {
|
|
|
|
throw new MethodNotAllowedException('Invalid Tag Collection');
|
|
|
|
}
|
2019-01-17 09:29:35 +01:00
|
|
|
}
|
|
|
|
} else {
|
|
|
|
$this->Event->id = $event_id;
|
|
|
|
$this->Event->recursive = -1;
|
|
|
|
$event = $this->Event->read(array(), $event_id);
|
|
|
|
if (empty($event)) {
|
2018-07-19 11:48:22 +02:00
|
|
|
throw new MethodNotAllowedException('Invalid Event.');
|
|
|
|
}
|
2019-01-17 09:29:35 +01:00
|
|
|
if (!$this->_isSiteAdmin() && !$this->userRole['perm_sync']) {
|
|
|
|
if (!$this->userRole['perm_tagger'] || ($this->Auth->user('org_id') !== $event['Event']['org_id'] && $this->Auth->user('org_id') !== $event['Event']['orgc_id'])) {
|
|
|
|
throw new MethodNotAllowedException('Invalid Event.');
|
|
|
|
}
|
|
|
|
}
|
2018-07-19 11:48:22 +02:00
|
|
|
}
|
2019-01-17 09:29:35 +01:00
|
|
|
|
2018-07-19 11:48:22 +02:00
|
|
|
if ($target_type == 'attribute') {
|
|
|
|
$existingTargetTag = $this->Event->Attribute->AttributeTag->find('first', array(
|
|
|
|
'conditions' => array('AttributeTag.tag_id' => $tag_id, 'AttributeTag.attribute_id' => $target_id),
|
|
|
|
'recursive' => -1,
|
|
|
|
'contain' => array('Tag')
|
|
|
|
));
|
|
|
|
} elseif ($target_type == 'event') {
|
|
|
|
$existingTargetTag = $this->Event->EventTag->find('first', array(
|
|
|
|
'conditions' => array('EventTag.tag_id' => $tag_id, 'EventTag.event_id' => $target_id),
|
|
|
|
'recursive' => -1,
|
|
|
|
'contain' => array('Tag')
|
|
|
|
));
|
2019-01-17 09:29:35 +01:00
|
|
|
} elseif ($target_type == 'tag_collection') {
|
|
|
|
$existingTargetTag = $this->GalaxyCluster->Tag->TagCollectionTag->find('first', array(
|
|
|
|
'conditions' => array('TagCollectionTag.tag_id' => $tag_id, 'TagCollectionTag.tag_collection_id' => $target_id),
|
|
|
|
'recursive' => -1,
|
|
|
|
'contain' => array('Tag')
|
|
|
|
));
|
2018-07-19 11:48:22 +02:00
|
|
|
}
|
2018-05-14 23:20:09 +02:00
|
|
|
|
2018-07-19 11:48:22 +02:00
|
|
|
if (empty($existingTargetTag)) {
|
|
|
|
$this->Flash->error('Galaxy not attached.');
|
|
|
|
} else {
|
|
|
|
$cluster = $this->GalaxyCluster->find('first', array(
|
|
|
|
'recursive' => -1,
|
|
|
|
'conditions' => array('GalaxyCluster.tag_name' => $existingTargetTag['Tag']['name'])
|
|
|
|
));
|
|
|
|
if ($target_type == 'event') {
|
|
|
|
$result = $this->Event->EventTag->delete($existingTargetTag['EventTag']['id']);
|
|
|
|
} elseif ($target_type == 'attribute') {
|
|
|
|
$result = $this->Event->Attribute->AttributeTag->delete($existingTargetTag['AttributeTag']['id']);
|
2019-01-17 09:29:35 +01:00
|
|
|
} elseif ($target_type == 'tag_collection') {
|
|
|
|
$result = $this->GalaxyCluster->Tag->TagCollectionTag->delete($existingTargetTag['TagCollectionTag']['id']);
|
2018-07-19 11:48:22 +02:00
|
|
|
}
|
|
|
|
if ($result) {
|
|
|
|
$event['Event']['published'] = 0;
|
|
|
|
$date = new DateTime();
|
|
|
|
$event['Event']['timestamp'] = $date->getTimestamp();
|
|
|
|
$this->Event->save($event);
|
|
|
|
$this->Flash->success('Galaxy successfully detached.');
|
|
|
|
$this->Log = ClassRegistry::init('Log');
|
|
|
|
$this->Log->create();
|
|
|
|
$this->Log->save(array(
|
|
|
|
'org' => $this->Auth->user('Organisation')['name'],
|
|
|
|
'model' => ucfirst($target_type),
|
|
|
|
'model_id' => $target_id,
|
|
|
|
'email' => $this->Auth->user('email'),
|
|
|
|
'action' => 'galaxy',
|
|
|
|
'title' => 'Detached ' . $cluster['GalaxyCluster']['value'] . ' (' . $cluster['GalaxyCluster']['id'] . ') from ' . $target_type . ' (' . $target_id . ')',
|
|
|
|
'change' => ''
|
|
|
|
));
|
|
|
|
} else {
|
|
|
|
$this->Flash->error('Could not detach galaxy from event.');
|
|
|
|
}
|
|
|
|
}
|
|
|
|
$this->redirect($this->referer());
|
|
|
|
}
|
2018-09-12 19:16:34 +02:00
|
|
|
|
2020-05-07 12:30:05 +02:00
|
|
|
// TODO: Add support for custom cluster deletion
|
2018-11-23 14:11:33 +01:00
|
|
|
public function delete($id)
|
|
|
|
{
|
2020-05-07 12:30:05 +02:00
|
|
|
if ($this->request->is('post')) {
|
|
|
|
$result = false;
|
|
|
|
$galaxy_cluster = $this->GalaxyCluster->find('first', array(
|
|
|
|
'recursive' => -1,
|
|
|
|
'conditions' => array('GalaxyCluster.id' => $id)
|
|
|
|
));
|
|
|
|
if (!empty($galaxy_cluster)) {
|
|
|
|
$result = $this->GalaxyCluster->delete($id, true);
|
|
|
|
$galaxy_id = $galaxy_cluster['GalaxyCluster']['galaxy_id'];
|
|
|
|
}
|
|
|
|
if ($result) {
|
|
|
|
$message = 'Galaxy cluster successfuly deleted.';
|
|
|
|
if ($this->_isRest()) {
|
|
|
|
return $this->RestResponse->saveSuccessResponse('GalaxyCluster', 'delete', $id, $this->response->type());
|
2018-11-23 14:11:33 +01:00
|
|
|
} else {
|
2020-05-07 12:30:05 +02:00
|
|
|
$this->Flash->success($message);
|
|
|
|
$this->redirect(array('controller' => 'galaxies', 'action' => 'view', $galaxy_id));
|
2018-11-23 14:11:33 +01:00
|
|
|
}
|
|
|
|
} else {
|
2020-05-07 12:30:05 +02:00
|
|
|
$message = 'Galaxy cluster could not be deleted.';
|
|
|
|
if ($this->_isRest()) {
|
|
|
|
return $this->RestResponse->saveFailResponse('GalaxyCluster', 'delete', $id, $message, $this->response->type());
|
2018-11-23 14:11:33 +01:00
|
|
|
} else {
|
2020-05-07 12:30:05 +02:00
|
|
|
$this->Flash->error($message);
|
|
|
|
$this->redirect(array('controller' => 'taxonomies', 'action' => 'index'));
|
2018-11-23 14:11:33 +01:00
|
|
|
}
|
|
|
|
}
|
2020-05-07 12:30:05 +02:00
|
|
|
} else {
|
|
|
|
if ($this->request->is('ajax')) {
|
|
|
|
$this->set('id', $id);
|
|
|
|
$this->render('ajax/galaxy_cluster_delete_confirmation');
|
|
|
|
} else {
|
|
|
|
throw new MethodNotAllowedException('This function can only be reached via AJAX.');
|
|
|
|
}
|
2018-11-23 14:11:33 +01:00
|
|
|
}
|
|
|
|
}
|
2019-03-20 14:28:08 +01:00
|
|
|
|
|
|
|
public function viewGalaxyMatrix($id) {
|
|
|
|
if (!$this->request->is('ajax')) {
|
|
|
|
throw new MethodNotAllowedException('This function can only be reached via AJAX.');
|
|
|
|
}
|
|
|
|
|
|
|
|
$cluster = $this->GalaxyCluster->find('first', array(
|
|
|
|
'conditions' => array('id' => $id)
|
|
|
|
));
|
|
|
|
if (empty($cluster)) {
|
|
|
|
throw new Exception("Invalid Galaxy Cluster.");
|
|
|
|
}
|
|
|
|
$this->loadModel('Event');
|
|
|
|
$mitreAttackGalaxyId = $this->GalaxyCluster->Galaxy->getMitreAttackGalaxyId();
|
|
|
|
$attackPatternTagNames = $this->GalaxyCluster->find('list', array(
|
|
|
|
'conditions' => array('galaxy_id' => $mitreAttackGalaxyId),
|
|
|
|
'fields' => array('tag_name')
|
|
|
|
));
|
|
|
|
|
|
|
|
$cluster = $cluster['GalaxyCluster'];
|
|
|
|
$tag_name = $cluster['tag_name'];
|
|
|
|
|
2019-05-02 14:57:05 +02:00
|
|
|
// fetch all event ids having the requested cluster
|
|
|
|
$eventIds = $this->Event->EventTag->find('list', array(
|
|
|
|
'contain' => array('Tag'),
|
|
|
|
'conditions' => array(
|
|
|
|
'Tag.name' => $tag_name
|
|
|
|
),
|
|
|
|
'fields' => array('event_id'),
|
|
|
|
'recursive' => -1
|
|
|
|
));
|
|
|
|
|
2019-03-20 14:28:08 +01:00
|
|
|
// fetch all attribute ids having the requested cluster
|
2019-05-02 14:57:05 +02:00
|
|
|
$attributes = $this->Event->Attribute->AttributeTag->find('all', array(
|
2019-03-20 14:28:08 +01:00
|
|
|
'contain' => array('Tag'),
|
|
|
|
'conditions' => array(
|
|
|
|
'Tag.name' => $tag_name
|
|
|
|
),
|
2019-05-02 14:57:05 +02:00
|
|
|
'fields' => array('attribute_id', 'event_id'),
|
2019-03-20 14:28:08 +01:00
|
|
|
'recursive' => -1
|
|
|
|
));
|
2019-05-02 14:57:05 +02:00
|
|
|
$attributeIds = array();
|
|
|
|
$additional_event_ids = array();
|
|
|
|
foreach ($attributes as $attribute) {
|
|
|
|
$attributeIds[] = $attribute['AttributeTag']['attribute_id'];
|
|
|
|
$additional_event_ids[$attribute['AttributeTag']['event_id']] = $attribute['AttributeTag']['event_id'];
|
|
|
|
}
|
|
|
|
$additional_event_ids = array_keys($additional_event_ids);
|
|
|
|
$eventIds = array_merge($eventIds, $additional_event_ids);
|
2019-05-02 15:00:06 +02:00
|
|
|
unset($attributes);
|
|
|
|
unset($additional_event_ids);
|
2019-05-02 14:57:05 +02:00
|
|
|
|
2019-03-20 14:28:08 +01:00
|
|
|
// fetch all related tags belonging to attack pattern
|
2019-05-02 14:57:05 +02:00
|
|
|
$eventTags = $this->Event->EventTag->find('all', array(
|
2019-03-20 14:28:08 +01:00
|
|
|
'contain' => array('Tag'),
|
|
|
|
'conditions' => array(
|
2019-05-02 14:57:05 +02:00
|
|
|
'event_id' => $eventIds,
|
2019-03-20 14:28:08 +01:00
|
|
|
'Tag.name' => $attackPatternTagNames
|
|
|
|
),
|
|
|
|
'fields' => array('Tag.name, COUNT(DISTINCT event_id) as tag_count'),
|
|
|
|
'recursive' => -1,
|
|
|
|
'group' => array('Tag.name')
|
|
|
|
));
|
|
|
|
|
2019-05-02 14:57:05 +02:00
|
|
|
// fetch all related tags belonging to attack pattern or belonging to an event having this cluster
|
|
|
|
$attributeTags = $this->Event->Attribute->AttributeTag->find('all', array(
|
2019-03-20 14:28:08 +01:00
|
|
|
'contain' => array('Tag'),
|
|
|
|
'conditions' => array(
|
2019-05-02 14:57:05 +02:00
|
|
|
'OR' => array(
|
|
|
|
'event_id' => $eventIds,
|
|
|
|
'attribute_id' => $attributeIds
|
|
|
|
),
|
2019-03-20 14:28:08 +01:00
|
|
|
'Tag.name' => $attackPatternTagNames
|
|
|
|
),
|
|
|
|
'fields' => array('Tag.name, COUNT(DISTINCT event_id) as tag_count'),
|
|
|
|
'recursive' => -1,
|
|
|
|
'group' => array('Tag.name')
|
|
|
|
));
|
|
|
|
|
|
|
|
$scores = array();
|
|
|
|
foreach ($attributeTags as $tag) {
|
|
|
|
$tagName = $tag['Tag']['name'];
|
|
|
|
$scores[$tagName] = intval($tag[0]['tag_count']);
|
|
|
|
}
|
|
|
|
foreach ($eventTags as $tag) {
|
|
|
|
$tagName = $tag['Tag']['name'];
|
|
|
|
if (isset($scores[$tagName])) {
|
|
|
|
$scores[$tagName] = $scores[$tagName] + intval($tag[0]['tag_count']);
|
|
|
|
} else {
|
|
|
|
$scores[$tagName] = intval($tag[0]['tag_count']);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
$maxScore = count($scores) > 0 ? max(array_values($scores)) : 0;
|
2019-05-13 15:07:38 +02:00
|
|
|
$matrixData = $this->GalaxyCluster->Galaxy->getMatrix($mitreAttackGalaxyId, $scores);
|
2019-03-20 14:28:08 +01:00
|
|
|
$tabs = $matrixData['tabs'];
|
|
|
|
$matrixTags = $matrixData['matrixTags'];
|
|
|
|
$killChainOrders = $matrixData['killChain'];
|
|
|
|
$instanceUUID = $matrixData['instance-uuid'];
|
|
|
|
|
|
|
|
App::uses('ColourGradientTool', 'Tools');
|
|
|
|
$gradientTool = new ColourGradientTool();
|
|
|
|
$colours = $gradientTool->createGradientFromValues($scores);
|
|
|
|
$this->set('target_type', 'attribute');
|
|
|
|
$this->set('columnOrders', $killChainOrders);
|
|
|
|
$this->set('tabs', $tabs);
|
|
|
|
$this->set('scores', $scores);
|
|
|
|
$this->set('maxScore', $maxScore);
|
|
|
|
if (!empty($colours)) {
|
|
|
|
$this->set('colours', $colours['mapping']);
|
|
|
|
$this->set('interpolation', $colours['interpolation']);
|
|
|
|
}
|
|
|
|
$this->set('pickingMode', false);
|
|
|
|
$this->set('defaultTabName', 'mitre-attack');
|
|
|
|
$this->set('removeTrailling', 2);
|
|
|
|
|
|
|
|
$this->render('cluster_matrix');
|
|
|
|
}
|
2020-04-30 16:28:47 +02:00
|
|
|
|
|
|
|
public function updateCluster($clusterId)
|
|
|
|
{
|
|
|
|
if (Validation::uuid($clusterId)) {
|
|
|
|
$temp = $this->GalaxyCluster->find('first', array(
|
|
|
|
'recursive' => -1,
|
|
|
|
'fields' => array('GalaxyCluster.id', 'GalaxyCluster.uuid'),
|
|
|
|
'conditions' => array('GalaxyCluster.uuid' => $clusterId)
|
|
|
|
));
|
|
|
|
if ($temp === null) {
|
|
|
|
throw new NotFoundException('Invalid galaxy cluster');
|
|
|
|
}
|
|
|
|
$clusterId = $temp['GalaxyCluster']['id'];
|
|
|
|
} elseif (!is_numeric($clusterId)) {
|
|
|
|
throw new NotFoundException(__('Invalid galaxy cluster'));
|
|
|
|
}
|
|
|
|
$conditions = array('conditions' => array('GalaxyCluster.id' => $clusterId));
|
|
|
|
$cluster = $this->GalaxyCluster->fetchGalaxyClusters($this->Auth->user(), $conditions, true);
|
|
|
|
if (empty($cluster)) {
|
|
|
|
throw new NotFoundException('Invalid galaxy cluster');
|
|
|
|
}
|
|
|
|
$cluster = $cluster[0];
|
|
|
|
if ($cluster['GalaxyCluster']['default']) {
|
|
|
|
throw new MethodNotAllowedException(__('Default galaxy cluster cannot be updated'));
|
|
|
|
}
|
|
|
|
if (empty($cluster['GalaxyCluster']['extends_uuid'])) {
|
|
|
|
throw new NotFoundException(__('Galaxy cluster is not a fork'));
|
|
|
|
}
|
|
|
|
$conditions = array('conditions' => array('GalaxyCluster.uuid' => $cluster['GalaxyCluster']['extends_uuid']));
|
|
|
|
$parentCluster = $this->GalaxyCluster->fetchGalaxyClusters($this->Auth->user(), $conditions, true);
|
|
|
|
if (empty($parentCluster)) {
|
|
|
|
throw new NotFoundException('Invalid parent galaxy cluster');
|
|
|
|
}
|
|
|
|
$parentCluster = $parentCluster[0];
|
|
|
|
$forkVersion = $cluster['GalaxyCluster']['extends_version'];
|
|
|
|
$parentVersion = $parentCluster['GalaxyCluster']['version'];
|
|
|
|
if ($this->request->is('post') || $this->request->is('put')) {
|
2020-05-04 16:20:09 +02:00
|
|
|
$elements = array();
|
|
|
|
foreach ($this->request->data['GalaxyCluster'] as $k => $jElement) {
|
|
|
|
$element = json_decode($jElement, true);
|
|
|
|
$elements[] = array(
|
|
|
|
'key' => $element['key'],
|
|
|
|
'value' => $element['value'],
|
|
|
|
);
|
|
|
|
}
|
|
|
|
$cluster['GalaxyCluster']['elements'] = $elements;
|
|
|
|
$cluster['GalaxyCluster']['extends_version'] = $parentVersion;
|
|
|
|
$errors = $this->GalaxyCluster->editCluster($this->Auth->user(), $cluster, $fromPull=false, $fieldList=array('extends_version'));
|
2020-04-30 16:28:47 +02:00
|
|
|
if (!empty($errors)) {
|
|
|
|
$flashErrorMessage = implode(', ', $errors);
|
|
|
|
$this->Flash->error($flashErrorMessage);
|
|
|
|
} else {
|
|
|
|
$this->Flash->success(__('Cluster updated to the newer version'));
|
|
|
|
$this->redirect(array('controller' => 'galaxy_clusters', 'action' => 'view', $clusterId));
|
|
|
|
}
|
|
|
|
}
|
|
|
|
$missingElements = array();
|
|
|
|
forEach($parentCluster['GalaxyElement'] as $k => $parentElement) {
|
|
|
|
$found = false;
|
|
|
|
forEach($cluster['GalaxyElement'] as $k => $clusterElement) {
|
|
|
|
if ($parentElement['key'] == $clusterElement['key'] &&
|
|
|
|
$parentElement['value'] == $clusterElement['value']) {
|
|
|
|
$found = true;
|
|
|
|
break; // element exists in parent
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if (!$found) {
|
|
|
|
$missingElements[] = $parentElement;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
$this->set('missingElements', $missingElements);
|
|
|
|
$this->set('parentElements', $parentCluster['GalaxyElement']);
|
|
|
|
$this->set('clusterElements', $cluster['GalaxyElement']);
|
|
|
|
$this->set('forkVersion', $forkVersion);
|
|
|
|
$this->set('parentVersion', $parentVersion);
|
|
|
|
$this->set('newVersionAvailable', $parentVersion > $forkVersion);
|
|
|
|
$this->set('id', $clusterId);
|
|
|
|
$this->set('galaxy_id', $cluster['GalaxyCluster']['galaxy_id']);
|
|
|
|
$this->set('defaultCluster', $cluster['GalaxyCluster']['default']);
|
|
|
|
$this->set('cluster', $cluster);
|
|
|
|
}
|
2020-05-06 07:59:57 +02:00
|
|
|
|
2020-05-06 08:18:51 +02:00
|
|
|
public function viewRelations($id)
|
2020-05-06 07:59:57 +02:00
|
|
|
{
|
|
|
|
if (!$this->request->is('ajax')) {
|
|
|
|
throw new MethodNotAllowedException('This function can only be reached via AJAX.');
|
|
|
|
}
|
|
|
|
$conditions = array('conditions' => array('GalaxyCluster.id' => $id));
|
|
|
|
$cluster = $this->GalaxyCluster->fetchGalaxyClusters($this->Auth->user(), $conditions, true);
|
|
|
|
if (empty($cluster)) {
|
|
|
|
throw new NotFoundException('Invalid galaxy cluster');
|
|
|
|
}
|
|
|
|
$cluster = $cluster[0];
|
2020-05-06 11:44:53 +02:00
|
|
|
$existingRelations = $this->GalaxyCluster->GalaxyClusterRelation->getExistingRelationships();
|
|
|
|
$cluster = $this->GalaxyCluster->attachClusterToRelations($this->Auth->user(), $cluster);
|
2020-05-07 16:49:14 +02:00
|
|
|
|
2020-05-13 11:01:16 +02:00
|
|
|
App::uses('ClusterRelationsTreeTool', 'Tools');
|
|
|
|
$grapher = new ClusterRelationsTreeTool();
|
|
|
|
$grapher->construct($this->Auth->user(), $this->GalaxyCluster);
|
|
|
|
$tree = $grapher->getTree($cluster);
|
2020-05-07 16:49:14 +02:00
|
|
|
|
2020-05-06 11:44:53 +02:00
|
|
|
$this->set('existingRelations', $existingRelations);
|
2020-05-06 07:59:57 +02:00
|
|
|
$this->set('cluster', $cluster);
|
2020-05-11 16:25:53 +02:00
|
|
|
$relations = $this->GalaxyCluster->GalaxyClusterRelation->fetchRelations($this->Auth->user(), array(
|
|
|
|
'conditions' => array(
|
2020-05-25 10:04:07 +02:00
|
|
|
'GalaxyClusterRelation.galaxy_cluster_uuid' => $cluster['GalaxyCluster']['uuid']
|
2020-05-11 16:25:53 +02:00
|
|
|
),
|
2020-05-29 10:26:11 +02:00
|
|
|
'contain' => array('SharingGroup', 'TargetCluster', 'GalaxyClusterRelationTag' => array('Tag'))
|
2020-05-11 16:25:53 +02:00
|
|
|
));
|
|
|
|
$this->set('relations', $relations);
|
2020-05-06 11:44:53 +02:00
|
|
|
$this->set('tree', $tree);
|
2020-05-07 16:17:44 +02:00
|
|
|
$this->loadModel('Attribute');
|
|
|
|
$distributionLevels = $this->Attribute->distributionLevels;
|
|
|
|
unset($distributionLevels[4]);
|
|
|
|
unset($distributionLevels[5]);
|
|
|
|
$this->set('distributionLevels', $distributionLevels);
|
2020-05-06 07:59:57 +02:00
|
|
|
}
|
2020-05-13 11:01:16 +02:00
|
|
|
|
|
|
|
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->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');
|
|
|
|
}
|
2016-12-05 00:47:34 +01:00
|
|
|
}
|