mirror of https://github.com/MISP/MISP
Merge branch '2.4' of https://github.com/MISP/MISP into rework_modules
commit
b7b4002fc7
|
@ -1172,6 +1172,9 @@ installCore () {
|
|||
# install lief
|
||||
$SUDO_WWW ${PATH_TO_MISP}/venv/bin/pip install https://github.com/lief-project/packages/raw/lief-master-latest/pylief-0.9.0.dev.zip
|
||||
|
||||
# install zmq needed by mispzmq
|
||||
$SUDO_WWW ${PATH_TO_MISP}/venv/bin/pip install zmq
|
||||
|
||||
# install python-magic
|
||||
$SUDO_WWW ${PATH_TO_MISP}/venv/bin/pip install python-magic
|
||||
|
||||
|
@ -1269,7 +1272,8 @@ coreCAKE () {
|
|||
$SUDO_WWW $RUN_PHP -- $CAKE Admin setSetting "MISP.python_bin" "${PATH_TO_MISP}/venv/bin/python"
|
||||
|
||||
# Set default role
|
||||
$SUDO_WWW $RUN_PHP -- $CAKE setDefaultRole 3
|
||||
# TESTME: The following seem defunct, please test.
|
||||
# $SUDO_WWW $RUN_PHP -- $CAKE setDefaultRole 3
|
||||
|
||||
# Tune global time outs
|
||||
$SUDO_WWW $RUN_PHP -- $CAKE Admin setSetting "Session.autoRegenerate" 0
|
||||
|
@ -2113,6 +2117,9 @@ installMISPonKali () {
|
|||
# install python-magic
|
||||
$SUDO_WWW ${PATH_TO_MISP}/venv/bin/pip install python-magic 2> /dev/null > /dev/null
|
||||
|
||||
# install zmq needed by mispzmq
|
||||
$SUDO_WWW ${PATH_TO_MISP}/venv/bin/pip install zmq 2> /dev/null > /dev/null
|
||||
|
||||
# Install Crypt_GPG and Console_CommandLine
|
||||
debug "Installing pear Console_CommandLine"
|
||||
pear install ${PATH_TO_MISP}/INSTALL/dependencies/Console_CommandLine/package.xml
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
; Generated by RHash v1.3.8 on 2019-05-30 at 14:36.25
|
||||
; Generated by RHash v1.3.8 on 2019-06-13 at 09:09.32
|
||||
; Written by Kravchenko Aleksey (Akademgorodok) - http://rhash.sf.net/
|
||||
;
|
||||
; 93871 14:36.25 2019-05-30 INSTALL.sh
|
||||
INSTALL.sh DE23B5D224757A8AB2941D8E15D73F10872D5106 ABEE81992478478406197EEC1891FA7CBDC5B32575447DD6865511B1DE48EC6F D7B9CA78779343C0CD47C9184DCA17DEFA24FA1B6BB35441F574AC40ED5A5AD68738BA91676E528AFC2488B44EC935C6 1FFDD293EF9FD53F80813B33839187ECF00B68FDDECA11327508ACABB99B45F45017CFF4AF2B70CF82D27B4AEEB75C34434B3AA00AD52D3AFC8405E77B8CF348
|
||||
; 94127 09:09.32 2019-06-13 INSTALL.sh
|
||||
INSTALL.sh BE7DE7EC5AA24D277F5F752E59356BAD26DC6EF7 E3ACE0081A95A94771EFE51AB8EDEE10CE5687F07A4C36DFD791B9B5F7E128DA 715AE909E454D2A74EEAF8A83D38F82534CB17B9C2BBDF5927251F08BD34651CF46D3260506ACC2BD3F26370E3A89696 24C56E075B7D4415517614C35A255A1D8217495A6A658F6B344A5D98AC24BD9A903E85EC3DC0C25CA89070EF0C0FB82D114ED7FA96D8120179DF4AEF0B1914ED
|
||||
|
|
|
@ -1 +1 @@
|
|||
de23b5d224757a8ab2941d8e15d73f10872d5106 INSTALL.sh
|
||||
be7de7ec5aa24d277f5f752e59356bad26dc6ef7 INSTALL.sh
|
||||
|
|
|
@ -1 +1 @@
|
|||
abee81992478478406197eec1891fa7cbdc5b32575447dd6865511b1de48ec6f INSTALL.sh
|
||||
e3ace0081a95a94771efe51ab8edee10ce5687f07a4c36dfd791b9b5f7e128da INSTALL.sh
|
||||
|
|
|
@ -1 +1 @@
|
|||
d7b9ca78779343c0cd47c9184dca17defa24fa1b6bb35441f574ac40ed5a5ad68738ba91676e528afc2488b44ec935c6 INSTALL.sh
|
||||
715ae909e454d2a74eeaf8a83d38f82534cb17b9c2bbdf5927251f08bd34651cf46d3260506acc2bd3f26370e3a89696 INSTALL.sh
|
||||
|
|
|
@ -1 +1 @@
|
|||
1ffdd293ef9fd53f80813b33839187ecf00b68fddeca11327508acabb99b45f45017cff4af2b70cf82d27b4aeeb75c34434b3aa00ad52d3afc8405e77b8cf348 INSTALL.sh
|
||||
24c56e075b7d4415517614c35a255a1d8217495a6a658f6b344a5d98ac24bd9a903e85ec3dc0c25ca89070ef0c0fb82d114ed7fa96d8120179df4aef0b1914ed INSTALL.sh
|
||||
|
|
|
@ -465,6 +465,9 @@ installMISPonKali () {
|
|||
# install python-magic
|
||||
$SUDO_WWW ${PATH_TO_MISP}/venv/bin/pip install python-magic 2> /dev/null > /dev/null
|
||||
|
||||
# install zmq needed by mispzmq
|
||||
$SUDO_WWW ${PATH_TO_MISP}/venv/bin/pip install zmq 2> /dev/null > /dev/null
|
||||
|
||||
# Install Crypt_GPG and Console_CommandLine
|
||||
debug "Installing pear Console_CommandLine"
|
||||
pear install ${PATH_TO_MISP}/INSTALL/dependencies/Console_CommandLine/package.xml
|
||||
|
|
|
@ -1 +1 @@
|
|||
{"major":2, "minor":4, "hotfix":108}
|
||||
{"major":2, "minor":4, "hotfix":109}
|
||||
|
|
|
@ -46,7 +46,7 @@ class AppController extends Controller
|
|||
|
||||
public $helpers = array('Utility', 'OrgImg', 'FontAwesome');
|
||||
|
||||
private $__queryVersion = '73';
|
||||
private $__queryVersion = '76';
|
||||
public $pyMispVersion = '2.4.106';
|
||||
public $phpmin = '7.0';
|
||||
public $phprec = '7.2';
|
||||
|
|
|
@ -1277,7 +1277,7 @@ class AttributesController extends AppController
|
|||
}
|
||||
if ($this->request->is('ajax')) {
|
||||
if ($this->request->is('post')) {
|
||||
if ($this->__delete($id, $hard)) {
|
||||
if ($this->Attribute->deleteAttribute($id, $this->Auth->user(), $hard)) {
|
||||
return new CakeResponse(array('body'=> json_encode(array('saved' => true, 'success' => 'Attribute deleted.')), 'status'=>200, 'type' => 'json'));
|
||||
} else {
|
||||
return new CakeResponse(array('body'=> json_encode(array('saved' => false, 'errors' => 'Attribute was not deleted.')), 'status'=>200, 'type' => 'json'));
|
||||
|
@ -1291,7 +1291,7 @@ class AttributesController extends AppController
|
|||
if (!$this->request->is('post') && !$this->_isRest()) {
|
||||
throw new MethodNotAllowedException();
|
||||
}
|
||||
if ($this->__delete($id, $hard)) {
|
||||
if ($this->Attribute->deleteAttribute($id, $this->Auth->user(), $hard)) {
|
||||
if ($this->_isRest() || $this->response->type() === 'application/json') {
|
||||
$this->set('message', 'Attribute deleted.');
|
||||
$this->set('_serialize', array('message'));
|
||||
|
@ -1360,77 +1360,6 @@ class AttributesController extends AppController
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
// unification of the actual delete for the multi-select
|
||||
private function __delete($id, $hard = false)
|
||||
{
|
||||
$this->Attribute->id = $id;
|
||||
if (!$this->Attribute->exists()) {
|
||||
return false;
|
||||
}
|
||||
$result = $this->Attribute->find('first', array(
|
||||
'conditions' => array('Attribute.id' => $id),
|
||||
'fields' => array('Attribute.*'),
|
||||
'contain' => array('Event' => array(
|
||||
'fields' => array('Event.*')
|
||||
)),
|
||||
));
|
||||
if (empty($result)) {
|
||||
throw new MethodNotAllowedException(__('Attribute not found or not authorised.'));
|
||||
}
|
||||
|
||||
// check for permissions
|
||||
if (!$this->_isSiteAdmin()) {
|
||||
if ($result['Event']['locked']) {
|
||||
if ($this->Auth->user('org_id') != $result['Event']['org_id'] || !$this->userRole['perm_sync']) {
|
||||
throw new MethodNotAllowedException(__('Attribute not found or not authorised.'));
|
||||
}
|
||||
} else {
|
||||
if ($this->Auth->user('org_id') != $result['Event']['orgc_id']) {
|
||||
throw new MethodNotAllowedException(__('Attribute not found or not authorised.'));
|
||||
}
|
||||
}
|
||||
}
|
||||
$date = new DateTime();
|
||||
if ($hard) {
|
||||
$save = $this->Attribute->delete($id);
|
||||
} else {
|
||||
if (Configure::read('Security.sanitise_attribute_on_delete')) {
|
||||
$result['Attribute']['category'] = 'Other';
|
||||
$result['Attribute']['type'] = 'comment';
|
||||
$result['Attribute']['value'] = 'deleted';
|
||||
$result['Attribute']['comment'] = '';
|
||||
$result['Attribute']['to_ids'] = 0;
|
||||
}
|
||||
$result['Attribute']['deleted'] = 1;
|
||||
$result['Attribute']['timestamp'] = $date->getTimestamp();
|
||||
$save = $this->Attribute->save($result);
|
||||
$object_refs = $this->Attribute->Object->ObjectReference->find('all', array(
|
||||
'conditions' => array(
|
||||
'ObjectReference.referenced_type' => 0,
|
||||
'ObjectReference.referenced_id' => $id,
|
||||
),
|
||||
'recursive' => -1
|
||||
));
|
||||
foreach ($object_refs as $ref) {
|
||||
$ref['ObjectReference']['deleted'] = 1;
|
||||
$this->Attribute->Object->ObjectReference->save($ref);
|
||||
}
|
||||
}
|
||||
// attachment will be deleted with the beforeDelete() function in the Model
|
||||
if ($save) {
|
||||
// We have just deleted the attribute, let's also check if there are any shadow attributes that were attached to it and delete them
|
||||
$this->loadModel('ShadowAttribute');
|
||||
$this->ShadowAttribute->deleteAll(array('ShadowAttribute.old_id' => $id), false);
|
||||
|
||||
// remove the published flag from the event
|
||||
$this->Attribute->Event->unpublishEvent($result['Event']['id']);
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
public function deleteSelected($id = false, $hard = false)
|
||||
{
|
||||
if (!$this->request->is('post')) {
|
||||
|
@ -1497,11 +1426,11 @@ class AttributesController extends AppController
|
|||
$successes = array();
|
||||
foreach ($attributes as $a) {
|
||||
if ($hard) {
|
||||
if ($this->__delete($a['Attribute']['id'], true)) {
|
||||
if ($this->Attribute->deleteAttribute($a['Attribute']['id'], $this->Auth->user(), true)) {
|
||||
$successes[] = $a['Attribute']['id'];
|
||||
}
|
||||
} else {
|
||||
if ($this->__delete($a['Attribute']['id'], $a['Attribute']['deleted'] == 1 ? true : false)) {
|
||||
if ($this->Attribute->deleteAttribute($a['Attribute']['id'], $this->Auth->user(), $a['Attribute']['deleted'] == 1 ? true : false)) {
|
||||
$successes[] = $a['Attribute']['id'];
|
||||
}
|
||||
}
|
||||
|
|
|
@ -75,6 +75,7 @@ class ACLComponent extends Component
|
|||
'delete' => array(),
|
||||
'edit' => array(),
|
||||
'index' => array(),
|
||||
'massDelete' => array()
|
||||
),
|
||||
'eventDelegations' => array(
|
||||
'acceptDelegation' => array('perm_add'),
|
||||
|
@ -250,6 +251,8 @@ class ACLComponent extends Component
|
|||
'edit' => array('perm_add'),
|
||||
'get_row' => array('perm_add'),
|
||||
'orphanedObjectDiagnostics' => array(),
|
||||
'proposeObjectsFromAttributes' => array('*'),
|
||||
'groupAttributesIntoObject' => array('perm_add'),
|
||||
'revise_object' => array('perm_add'),
|
||||
'view' => array('*'),
|
||||
),
|
||||
|
|
|
@ -27,13 +27,25 @@ class EventBlacklistsController extends AppController
|
|||
|
||||
public function index()
|
||||
{
|
||||
$passedArgsArray = array();
|
||||
$passedArgs = $this->passedArgs;
|
||||
$params = array();
|
||||
$validParams = array('event_uuid', 'comment');
|
||||
$validParams = array('event_uuid', 'comment', 'event_info', 'event_orgc');
|
||||
foreach ($validParams as $validParam) {
|
||||
if (!empty($this->params['named'][$validParam])) {
|
||||
$params[$validParam] = $this->params['named'][$validParam];
|
||||
}
|
||||
}
|
||||
if (!empty($this->params['named']['searchall'])) {
|
||||
$params['AND']['OR'] = array(
|
||||
'event_uuid' => $this->params['named']['searchall'],
|
||||
'comment' => $this->params['named']['searchall'],
|
||||
'event_info' => $this->params['named']['searchall'],
|
||||
'event_orgc' => $this->params['named']['searchall']
|
||||
);
|
||||
}
|
||||
$this->set('passedArgs', json_encode($passedArgs));
|
||||
$this->set('passedArgsArray', $passedArgsArray);
|
||||
$this->BlackList->index($this->_isRest(), $params);
|
||||
}
|
||||
|
||||
|
@ -51,4 +63,39 @@ class EventBlacklistsController extends AppController
|
|||
{
|
||||
$this->BlackList->delete($this->_isRest(), $id);
|
||||
}
|
||||
|
||||
public function massDelete()
|
||||
{
|
||||
if ($this->request->is('post') || $this->request->is('put')) {
|
||||
$ids = $this->request->data['EventBlacklist']['ids'];
|
||||
$event_ids = json_decode($ids, true);
|
||||
if (empty($event_ids)) {
|
||||
throw new NotFoundException(__('Invalid event IDs.'));
|
||||
}
|
||||
$result = $this->EventBlacklist->deleteAll(array('EventBlacklist.id' => $event_ids));
|
||||
if ($result) {
|
||||
if ($this->_isRest()) {
|
||||
return $this->RestResponse->saveSuccessResponse('EventBlacklist', 'Deleted', $ids, $this->response->type());
|
||||
} else {
|
||||
$this->Flash->success('Event deleted.');
|
||||
$this->redirect(array('controller' => 'eventBlacklists', 'action' => 'index'));
|
||||
}
|
||||
} else {
|
||||
$error = __('Failed to delete Event from EventBlacklist. Error: ') . PHP_EOL . h($result);
|
||||
if ($this->_isRest()) {
|
||||
return $this->RestResponse->saveFailResponse('EventBlacklist', 'Deleted', false, $error, $this->response->type());
|
||||
} else {
|
||||
$this->Flash->error($error);
|
||||
$this->redirect(array('controller' => 'eventBlacklists', 'action' => 'index'));
|
||||
}
|
||||
}
|
||||
} else {
|
||||
$ids = json_decode($this->request->query('ids'), true);
|
||||
if (empty($ids)) {
|
||||
throw new NotFoundException(__('Invalid event IDs.'));
|
||||
|
||||
}
|
||||
$this->set('event_ids', $ids);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -4913,7 +4913,12 @@ class EventsController extends AppController
|
|||
throw new Exception("Invalid options.");
|
||||
}
|
||||
|
||||
$scoresDataAttr = $this->Event->Attribute->AttributeTag->getTagScores($eventId, $matrixTags);
|
||||
$event = $this->Event->fetchEvent($this->Auth->user(), array('eventid' => $eventId, 'metadata' => true));
|
||||
if (empty($event)) {
|
||||
throw new NotFoundException(__('Event not found or you are not authorised to view it.'));
|
||||
}
|
||||
|
||||
$scoresDataAttr = $this->Event->Attribute->AttributeTag->getTagScores($this->Auth->user(), $eventId, $matrixTags);
|
||||
$scoresDataEvent = $this->Event->EventTag->getTagScores($eventId, $matrixTags);
|
||||
$maxScore = 0;
|
||||
$scoresData = array();
|
||||
|
@ -4967,6 +4972,7 @@ class EventsController extends AppController
|
|||
}
|
||||
// end FIXME
|
||||
|
||||
$this->Galaxy->sortMatrixByScore($tabs, $scores);
|
||||
if ($this->_isRest()) {
|
||||
$json = array('matrix' => $tabs, 'scores' => $scores, 'instance-uuid' => $instanceUUID);
|
||||
$this->response->type('json');
|
||||
|
|
|
@ -450,7 +450,7 @@ class GalaxyClustersController extends AppController
|
|||
}
|
||||
|
||||
$maxScore = count($scores) > 0 ? max(array_values($scores)) : 0;
|
||||
$matrixData = $this->GalaxyCluster->Galaxy->getMatrix($mitreAttackGalaxyId);
|
||||
$matrixData = $this->GalaxyCluster->Galaxy->getMatrix($mitreAttackGalaxyId, $scores);
|
||||
$tabs = $matrixData['tabs'];
|
||||
$matrixTags = $matrixData['matrixTags'];
|
||||
$killChainOrders = $matrixData['killChain'];
|
||||
|
|
|
@ -989,4 +989,154 @@ class ObjectsController extends AppController
|
|||
$this->set('captured', $capturedObjects);
|
||||
$this->set('unmapped', $unmappedAttributes);
|
||||
}
|
||||
|
||||
function proposeObjectsFromAttributes($event_id, $selected_attributes='[]')
|
||||
{
|
||||
if (!$this->request->is('ajax')) {
|
||||
throw new MethodNotAllowedException(__('This action can only be reached via AJAX.'));
|
||||
}
|
||||
$selected_attributes = json_decode($selected_attributes, true);
|
||||
$res = $this->MispObject->validObjectsFromAttributeTypes($this->Auth->user(), $event_id, $selected_attributes);
|
||||
$potential_templates = $res['templates'];
|
||||
$attribute_types = $res['types'];
|
||||
usort($potential_templates, function($a, $b) {
|
||||
if ($a['ObjectTemplate']['id'] == $b['ObjectTemplate']['id']) {
|
||||
return 0;
|
||||
} else if (is_array($a['ObjectTemplate']['compatibility']) && is_array($b['ObjectTemplate']['compatibility'])) {
|
||||
return count($a['ObjectTemplate']['compatibility']) > count($b['ObjectTemplate']['compatibility']) ? 1 : -1;
|
||||
} else if (is_array($a['ObjectTemplate']['compatibility']) && !is_array($b['ObjectTemplate']['compatibility'])) {
|
||||
return 1;
|
||||
} else if (!is_array($a['ObjectTemplate']['compatibility']) && is_array($b['ObjectTemplate']['compatibility'])) {
|
||||
return -1;
|
||||
} else { // sort based on invalidTypes count
|
||||
return count($a['ObjectTemplate']['invalidTypes']) > count($b['ObjectTemplate']['invalidTypes']) ? 1 : -1;
|
||||
}
|
||||
});
|
||||
$this->set('potential_templates', $potential_templates);
|
||||
$this->set('selected_types', $attribute_types);
|
||||
$this->set('event_id', $event_id);
|
||||
}
|
||||
|
||||
function groupAttributesIntoObject($event_id, $selected_template, $selected_attribute_ids='[]')
|
||||
{
|
||||
$event = $this->MispObject->Event->find('first', array(
|
||||
'recursive' => -1,
|
||||
'fields' => array('Event.id', 'Event.uuid', 'Event.orgc_id', 'Event.publish_timestamp'),
|
||||
'conditions' => array('Event.id' => $event_id)
|
||||
));
|
||||
if (empty($event) || (!$this->_isSiteAdmin() && $event['Event']['orgc_id'] != $this->Auth->user('org_id'))) {
|
||||
throw new NotFoundException(__('Invalid event.'));
|
||||
}
|
||||
$hard_delete_attribute = $event['Event']['publish_timestamp'] == 0;
|
||||
if (!$this->request->is('ajax')) {
|
||||
throw new MethodNotAllowedException(__('This action can only be reached via AJAX.'));
|
||||
}
|
||||
if ($this->request->is('post')) {
|
||||
$template = $this->MispObject->ObjectTemplate->find('first', array(
|
||||
'recursive' => -1,
|
||||
'conditions' => array('ObjectTemplate.id' => $selected_template, 'ObjectTemplate.active' => true)
|
||||
));
|
||||
if (empty($template)) {
|
||||
throw new NotFoundException(__('Invalid template.'));
|
||||
}
|
||||
$distribution = $this->request->data['Object']['distribution'];
|
||||
$sharing_group_id = $this->request->data['Object']['sharing_group_id'];
|
||||
$comment = $this->request->data['Object']['comment'];
|
||||
$selected_attribute_ids = json_decode($this->request->data['Object']['selectedAttributeIds'], true);
|
||||
$selected_object_relation_mapping = json_decode($this->request->data['Object']['selectedObjectRelationMapping'], true);
|
||||
if ($distribution == 4) {
|
||||
$sg = $this->MispObject->SharingGroup->find('first', array(
|
||||
'conditions' => array('SharingGroup.id' => $sharing_group_id),
|
||||
'recursive' => -1,
|
||||
'fields' => array('SharingGroup.id', 'SharingGroup.name'),
|
||||
'order' => false
|
||||
));
|
||||
if (empty($sg)) {
|
||||
throw new NotFoundException(__('Invalid sharing group.'));
|
||||
}
|
||||
} else {
|
||||
$sharing_group_id = 0;
|
||||
}
|
||||
$object = array(
|
||||
'Object' => array(
|
||||
'distribution' => $distribution,
|
||||
'sharing_group_id' => $sharing_group_id,
|
||||
'comment' => $comment,
|
||||
),
|
||||
'Attribute' => array()
|
||||
);
|
||||
$result = $this->MispObject->groupAttributesIntoObject($this->Auth->user(), $event_id, $object, $template, $selected_attribute_ids, $selected_object_relation_mapping, $hard_delete_attribute);
|
||||
if (is_numeric($result)) {
|
||||
$this->MispObject->Event->unpublishEvent($event_id);
|
||||
return $this->RestResponse->saveSuccessResponse('Objects', 'Created from Attributes', $result, $this->response->type());
|
||||
} else {
|
||||
$error = __('Failed to create an Object from Attributes. Error: ') . PHP_EOL . h($result);
|
||||
return $this->RestResponse->saveFailResponse('Objects', 'Created from Attributes', false, $error, $this->response->type());
|
||||
}
|
||||
} else {
|
||||
$selected_attribute_ids = json_decode($selected_attribute_ids, true);
|
||||
$selected_attributes = $this->MispObject->Attribute->fetchAttributes($this->Auth->user(), array('conditions' => array(
|
||||
'Attribute.id' => $selected_attribute_ids,
|
||||
'Attribute.event_id' => $event_id,
|
||||
'Attribute.object_id' => 0
|
||||
)));
|
||||
if (empty($selected_attributes)) {
|
||||
throw new MethodNotAllowedException(__('No Attribute selected.'));
|
||||
}
|
||||
$template = $this->MispObject->ObjectTemplate->find('first', array(
|
||||
'recursive' => -1,
|
||||
'conditions' => array('ObjectTemplate.id' => $selected_template, 'ObjectTemplate.active' => true),
|
||||
'contain' => 'ObjectTemplateElement'
|
||||
));
|
||||
if (empty($template)) {
|
||||
throw new NotFoundException(__('Invalid template.'));
|
||||
}
|
||||
$conformity_result = $this->MispObject->ObjectTemplate->checkTemplateConformityBasedOnTypes($template, $selected_attributes);
|
||||
$skipped_attributes = 0;
|
||||
foreach ($selected_attributes as $i => $attribute) {
|
||||
if (in_array($attribute['Attribute']['type'], $conformity_result['invalidTypes'])) {
|
||||
unset($selected_attributes[$i]);
|
||||
$array_position = array_search($attribute['Attribute']['id'], $selected_attribute_ids);
|
||||
unset($selected_attribute_ids[$array_position]);
|
||||
$skipped_attributes++;
|
||||
}
|
||||
}
|
||||
$object_relations = array();
|
||||
foreach ($template['ObjectTemplateElement'] as $template_element) {
|
||||
$object_relations[$template_element['type']][] = $template_element;
|
||||
}
|
||||
|
||||
$object_references = $this->MispObject->ObjectReference->find('all', array(
|
||||
'conditions' => array(
|
||||
'ObjectReference.referenced_id' => $selected_attribute_ids,
|
||||
),
|
||||
'recursive' => -1
|
||||
));
|
||||
|
||||
foreach ($object_references as $i => $object_reference) {
|
||||
$temp_object = $this->MispObject->find('first', array('id' => $object_reference['ObjectReference']['object_id'], 'recursive' => -1));
|
||||
$temp_attribute = $this->MispObject->Attribute->find('first', array('id' => $object_reference['ObjectReference']['referenced_id'], 'recursive' => -1));
|
||||
if (!empty($temp_object) && !empty($temp_attribute)) {
|
||||
$temp_object = $temp_object['Object'];
|
||||
$temp_attribute = $temp_attribute['Attribute'];
|
||||
$object_references[$i]['ObjectReference']['object_name'] = $temp_object['name'];
|
||||
$object_references[$i]['ObjectReference']['attribute_name'] = sprintf('%s/%s: "%s"', $temp_attribute['category'], $temp_attribute['type'], $temp_attribute['value']);
|
||||
}
|
||||
}
|
||||
|
||||
$distributionData = $this->MispObject->Event->Attribute->fetchDistributionData($this->Auth->user());
|
||||
$this->set('event_id', $event_id);
|
||||
$this->set('hard_delete_attribute', $hard_delete_attribute);
|
||||
$this->set('distributionData', $distributionData);
|
||||
$this->set('distributionLevels', $this->MispObject->Attribute->distributionLevels);
|
||||
$this->set('selectedTemplateTd', $selected_template);
|
||||
$this->set('selectedAttributeIds', $selected_attribute_ids);
|
||||
$this->set('template', $template);
|
||||
$this->set('object_relations', $object_relations);
|
||||
$this->set('attributes', $selected_attributes);
|
||||
$this->set('skipped_attributes', $skipped_attributes);
|
||||
$this->set('object_references', $object_references);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -1921,94 +1921,149 @@ class UsersController extends AppController
|
|||
} else {
|
||||
$galaxy_id = $mitre_galaxy_id;
|
||||
}
|
||||
$matrixData = $this->Galaxy->getMatrix($galaxy_id);
|
||||
|
||||
$tabs = $matrixData['tabs'];
|
||||
$matrixTags = $matrixData['matrixTags'];
|
||||
$killChainOrders = $matrixData['killChain'];
|
||||
$instanceUUID = $matrixData['instance-uuid'];
|
||||
|
||||
$scoresDataAttr = $this->Event->Attribute->AttributeTag->getTagScores(0, $matrixTags);
|
||||
$scoresDataEvent = $this->Event->EventTag->getTagScores(0, $matrixTags);
|
||||
$scoresData = array();
|
||||
foreach (array_keys($scoresDataAttr['scores'] + $scoresDataEvent['scores']) as $key) {
|
||||
$scoresData[$key] = (isset($scoresDataAttr['scores'][$key]) ? $scoresDataAttr['scores'][$key] : 0) + (isset($scoresDataEvent['scores'][$key]) ? $scoresDataEvent['scores'][$key] : 0);
|
||||
$organisations = $this->User->Organisation->find('all', array(
|
||||
'recursive' => -1,
|
||||
));
|
||||
array_unshift($organisations, array('Organisation' => array('id' => 0, 'name' => 'All')));
|
||||
$this->set('organisations', $organisations);
|
||||
$picked_organisation = 0;
|
||||
if (isset($params['organisation']) && $params['organisation'] != 0) {
|
||||
$org = $this->User->Organisation->find('first', array(
|
||||
'recursive' => -1,
|
||||
'conditions' => array('id' => $params['organisation']),
|
||||
));
|
||||
if (!empty($org)) {
|
||||
$picked_organisation = $org;
|
||||
$this->set('picked_organisation', $picked_organisation);
|
||||
} else {
|
||||
$this->set('picked_organisation', array('Organisation' => array('id' => '')));
|
||||
}
|
||||
} else {
|
||||
$this->set('picked_organisation', array('Organisation' => array('id' => '')));
|
||||
}
|
||||
$maxScore = max($scoresDataAttr['maxScore'], $scoresDataEvent['maxScore']);
|
||||
$scores = $scoresData;
|
||||
// FIXME: temporary fix: add the score of deprecated mitre galaxies to the new one (for the stats)
|
||||
if ($matrixData['galaxy']['id'] == $mitre_galaxy_id) {
|
||||
$mergedScore = array();
|
||||
foreach ($scoresData as $tag => $v) {
|
||||
$predicateValue = explode(':', $tag, 2)[1];
|
||||
$predicateValue = explode('=', $predicateValue, 2);
|
||||
$predicate = $predicateValue[0];
|
||||
$clusterValue = $predicateValue[1];
|
||||
$mappedTag = '';
|
||||
$mappingWithoutExternalId = array();
|
||||
if ($predicate == 'mitre-attack-pattern') {
|
||||
$mappedTag = $tag;
|
||||
$name = explode(" ", $tag);
|
||||
$name = join(" ", array_slice($name, 0, -2)); // remove " - external_id"
|
||||
$mappingWithoutExternalId[$name] = $tag;
|
||||
} else {
|
||||
$name = explode(" ", $clusterValue);
|
||||
$name = join(" ", array_slice($name, 0, -2)); // remove " - external_id"
|
||||
if (isset($mappingWithoutExternalId[$name])) {
|
||||
$mappedTag = $mappingWithoutExternalId[$name];
|
||||
|
||||
$rest_response_empty = true;
|
||||
$ignore_score = false;
|
||||
if (
|
||||
isset($params['dateFrom'])
|
||||
|| isset($params['dateTo'])
|
||||
|| isset($params['organisation']) && $params['organisation'] != 0
|
||||
) { // use restSearch
|
||||
$ignore_score = true;
|
||||
$filters = array();
|
||||
if (isset($params['dateFrom'])) {
|
||||
$filters['from'] = $params['dateFrom'];
|
||||
$this->set('dateFrom', $params['dateFrom']);
|
||||
}
|
||||
if (isset($params['dateTo'])) {
|
||||
$filters['to'] = $params['dateTo'];
|
||||
$this->set('dateTo', $params['dateTo']);
|
||||
}
|
||||
if (isset($params['organisation'])) {
|
||||
$filters['org'] = $params['organisation'];
|
||||
}
|
||||
$elementCounter = 0;
|
||||
$renderView = '';
|
||||
$final = $this->Event->restSearch($this->Auth->user(), 'attack', $filters, false, false, $elementCounter, $renderView);
|
||||
|
||||
$final = json_decode($final, true);
|
||||
if (!empty($final)) {
|
||||
$rest_response_empty = false;
|
||||
foreach ($final as $key => $data) {
|
||||
$this->set($key, $data);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// No need for restSearch or result is empty
|
||||
if ($rest_response_empty) {
|
||||
$matrixData = $this->Galaxy->getMatrix($galaxy_id);
|
||||
$tabs = $matrixData['tabs'];
|
||||
$matrixTags = $matrixData['matrixTags'];
|
||||
$killChainOrders = $matrixData['killChain'];
|
||||
$instanceUUID = $matrixData['instance-uuid'];
|
||||
if ($ignore_score) {
|
||||
$scores_uniform = array('scores' => array(), 'maxScore' => 0);
|
||||
} else {
|
||||
$scores_uniform = $this->Event->EventTag->getTagScoresUniform(0, $matrixTags);
|
||||
}
|
||||
$scores = $scores_uniform['scores'];
|
||||
$maxScore = $scores_uniform['maxScore'];
|
||||
// FIXME: temporary fix: add the score of deprecated mitre galaxies to the new one (for the stats)
|
||||
if ($matrixData['galaxy']['id'] == $mitre_galaxy_id) {
|
||||
$mergedScore = array();
|
||||
foreach ($scores as $tag => $v) {
|
||||
$predicateValue = explode(':', $tag, 2)[1];
|
||||
$predicateValue = explode('=', $predicateValue, 2);
|
||||
$predicate = $predicateValue[0];
|
||||
$clusterValue = $predicateValue[1];
|
||||
$mappedTag = '';
|
||||
$mappingWithoutExternalId = array();
|
||||
if ($predicate == 'mitre-attack-pattern') {
|
||||
$mappedTag = $tag;
|
||||
$name = explode(" ", $tag);
|
||||
$name = join(" ", array_slice($name, 0, -2)); // remove " - external_id"
|
||||
$mappingWithoutExternalId[$name] = $tag;
|
||||
} else {
|
||||
$adjustedTagName = $this->Galaxy->GalaxyCluster->find('list', array(
|
||||
'group' => array('GalaxyCluster.id', 'GalaxyCluster.tag_name'),
|
||||
'conditions' => array('GalaxyCluster.tag_name LIKE' => 'misp-galaxy:mitre-attack-pattern=' . $name . '% T%'),
|
||||
'fields' => array('GalaxyCluster.tag_name')
|
||||
));
|
||||
$adjustedTagName = array_values($adjustedTagName)[0];
|
||||
$mappingWithoutExternalId[$name] = $adjustedTagName;
|
||||
$mappedTag = $mappingWithoutExternalId[$name];
|
||||
$name = explode(" ", $clusterValue);
|
||||
$name = join(" ", array_slice($name, 0, -2)); // remove " - external_id"
|
||||
if (isset($mappingWithoutExternalId[$name])) {
|
||||
$mappedTag = $mappingWithoutExternalId[$name];
|
||||
} else {
|
||||
$adjustedTagName = $this->Galaxy->GalaxyCluster->find('list', array(
|
||||
'group' => array('GalaxyCluster.id', 'GalaxyCluster.tag_name'),
|
||||
'conditions' => array('GalaxyCluster.tag_name LIKE' => 'misp-galaxy:mitre-attack-pattern=' . $name . '% T%'),
|
||||
'fields' => array('GalaxyCluster.tag_name')
|
||||
));
|
||||
if (!empty($adjustedTagName)) {
|
||||
$adjustedTagName = array_values($adjustedTagName)[0];
|
||||
$mappingWithoutExternalId[$name] = $adjustedTagName;
|
||||
$mappedTag = $mappingWithoutExternalId[$name];
|
||||
}
|
||||
}
|
||||
}
|
||||
if (isset($mergedScore[$mappedTag])) {
|
||||
$mergedScore[$mappedTag] += $v;
|
||||
} else {
|
||||
$mergedScore[$mappedTag] = $v;
|
||||
}
|
||||
}
|
||||
$scores = $mergedScore;
|
||||
$maxScore = !empty($mergedScore) ? max(array_values($mergedScore)) : 0;
|
||||
}
|
||||
// end FIXME
|
||||
|
||||
if (isset($mergedScore[$mappedTag])) {
|
||||
$mergedScore[$mappedTag] += $v;
|
||||
} else {
|
||||
$mergedScore[$mappedTag] = $v;
|
||||
$this->Galaxy->sortMatrixByScore($tabs, $scores);
|
||||
if ($this->_isRest()) {
|
||||
$json = array('matrix' => $tabs, 'scores' => $scores, 'instance-uuid' => $instanceUUID);
|
||||
return $this->RestResponse->viewData($json, $this->response->type());
|
||||
} else {
|
||||
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);
|
||||
if ($matrixData['galaxy']['id'] == $mitre_galaxy_id) {
|
||||
$this->set('defaultTabName', "mitre-attack");
|
||||
$this->set('removeTrailling', 2);
|
||||
}
|
||||
|
||||
$this->set('galaxyName', $matrixData['galaxy']['name']);
|
||||
$this->set('galaxyId', $matrixData['galaxy']['id']);
|
||||
$matrixGalaxies = $this->Galaxy->getAllowedMatrixGalaxies();
|
||||
$this->set('matrixGalaxies', $matrixGalaxies);
|
||||
}
|
||||
$scores = $mergedScore;
|
||||
$maxScore = max(array_values($mergedScore));
|
||||
}
|
||||
// end FIXME
|
||||
|
||||
if ($this->_isRest()) {
|
||||
$json = array('matrix' => $tabs, 'scores' => $scores, 'instance-uuid' => $instanceUUID);
|
||||
return $this->RestResponse->viewData($json, $this->response->type());
|
||||
} else {
|
||||
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);
|
||||
if ($matrixData['galaxy']['id'] == $mitre_galaxy_id) {
|
||||
$this->set('defaultTabName', "mitre-attack");
|
||||
$this->set('removeTrailling', 2);
|
||||
}
|
||||
|
||||
$this->set('galaxyName', $matrixData['galaxy']['name']);
|
||||
$this->set('galaxyId', $matrixData['galaxy']['id']);
|
||||
$matrixGalaxies = $this->Galaxy->getAllowedMatrixGalaxies();
|
||||
$this->set('matrixGalaxies', $matrixGalaxies);
|
||||
|
||||
$this->render('statistics_galaxymatrix');
|
||||
}
|
||||
$this->render('statistics_galaxymatrix');
|
||||
}
|
||||
|
||||
public function verifyGPG($full = false)
|
||||
|
|
|
@ -11,6 +11,7 @@ class AttackExport
|
|||
public $non_restrictive_export = true;
|
||||
public $renderView = 'attack_view';
|
||||
|
||||
private $__matrixData = null;
|
||||
private $__clusterCounts = array();
|
||||
private $__attackGalaxy = 'mitre-attack-pattern';
|
||||
private $__galaxy_id = 0;
|
||||
|
@ -20,7 +21,6 @@ class AttackExport
|
|||
private $__matrixTags = false;
|
||||
private $__killChainOrders = false;
|
||||
private $__instanceUUID = false;
|
||||
private $__scope = 'Event';
|
||||
|
||||
public function handler($data, $options = array())
|
||||
{
|
||||
|
@ -28,35 +28,34 @@ class AttackExport
|
|||
$this->__GalaxyModel = ClassRegistry::init('Galaxy');
|
||||
}
|
||||
$this->__attackGalaxy = empty($options['filters']['attackGalaxy']) ? $this->__attackGalaxy : $options['filters']['attackGalaxy'];
|
||||
$temp = $this->__GalaxyModel->find('first', array(
|
||||
if (empty($this->__galaxy_id)) {
|
||||
$temp = $this->__GalaxyModel->find('first', array(
|
||||
'recursive' => -1,
|
||||
'fields' => array('id', 'name'),
|
||||
'conditions' => array('Galaxy.type' => $this->__attackGalaxy, 'Galaxy.namespace !=' => 'deprecated'),
|
||||
));
|
||||
if (empty($temp)) {
|
||||
return '';
|
||||
} else {
|
||||
$this->__galaxy_id = $temp['Galaxy']['id'];
|
||||
$this->__galaxy_name = $temp['Galaxy']['name'];
|
||||
}
|
||||
$matrixData = $this->__GalaxyModel->getMatrix($this->__galaxy_id);
|
||||
if (empty($this->__tabs)) {
|
||||
$this->__tabs = $matrixData['tabs'];
|
||||
$this->__matrixTags = $matrixData['matrixTags'];
|
||||
$this->__killChainOrders = $matrixData['killChain'];
|
||||
$this->__instanceUUID = $matrixData['instance-uuid'];
|
||||
}
|
||||
$this->__scope = empty($options['scope']) ? 'Event' : $options['scope'];
|
||||
$clusterData = array();
|
||||
if ($this->__scope === 'Event') {
|
||||
$clusterData = $this->__aggregate($data, $clusterData);
|
||||
if (!empty($data['Attribute'])) {
|
||||
foreach ($data['Attribute'] as $attribute) {
|
||||
$clusterData = $this->__aggregate($attribute, $clusterData);
|
||||
}
|
||||
));
|
||||
if (empty($temp)) {
|
||||
return '';
|
||||
} else {
|
||||
$this->__galaxy_id = $temp['Galaxy']['id'];
|
||||
$this->__galaxy_name = $temp['Galaxy']['name'];
|
||||
}
|
||||
}
|
||||
if (empty($this->__matrixData)) {
|
||||
$this->__matrixData = $this->__GalaxyModel->getMatrix($this->__galaxy_id);
|
||||
}
|
||||
if (empty($this->__tabs)) {
|
||||
$this->__tabs = $this->__matrixData['tabs'];
|
||||
$this->__matrixTags = $this->__matrixData['matrixTags'];
|
||||
$this->__killChainOrders = $this->__matrixData['killChain'];
|
||||
$this->__instanceUUID = $this->__matrixData['instance-uuid'];
|
||||
}
|
||||
|
||||
$clusterData = $this->__aggregate($data, array());
|
||||
if (!empty($data['Attribute'])) {
|
||||
foreach ($data['Attribute'] as $attribute) {
|
||||
$clusterData = $this->__aggregate($attribute, $clusterData);
|
||||
}
|
||||
} else {
|
||||
$clusterData = $this->__aggregate($data, $clusterData);
|
||||
}
|
||||
|
||||
foreach ($clusterData as $key => $value) {
|
||||
|
@ -99,11 +98,12 @@ class AttackExport
|
|||
$maxScore = $clusterCount;
|
||||
}
|
||||
}
|
||||
$this->__GalaxyModel->sortMatrixByScore($this->__tabs, $this->__clusterCounts);
|
||||
App::uses('ColourGradientTool', 'Tools');
|
||||
$gradientTool = new ColourGradientTool();
|
||||
$colours = $gradientTool->createGradientFromValues($this->__clusterCounts);
|
||||
$result = array(
|
||||
'target_type' => strtolower($this->__scope),
|
||||
'target_type' => 'event',
|
||||
'columnOrders' => $this->__killChainOrders,
|
||||
'tabs' => $this->__tabs,
|
||||
'scores' => $this->__clusterCounts,
|
||||
|
@ -114,6 +114,10 @@ class AttackExport
|
|||
$result['colours'] = $colours['mapping'];
|
||||
$result['interpolation'] = $colours['interpolation'];
|
||||
}
|
||||
if ($this->__galaxy_id == $this->__GalaxyModel->getMitreAttackGalaxyId()) {
|
||||
$result['defaultTabName'] = 'mitre-attack';
|
||||
$result['removeTrailling'] = 2;
|
||||
}
|
||||
$result['galaxyName'] = $this->__galaxy_name;
|
||||
$result['galaxyId'] = $this->__galaxy_id;
|
||||
$matrixGalaxies = $this->__GalaxyModel->getAllowedMatrixGalaxies();
|
||||
|
|
|
@ -392,8 +392,7 @@ class Attribute extends AppModel
|
|||
'yara-json' => array('json', 'YaraExport', 'json'),
|
||||
'rpz' => array('txt', 'RPZExport', 'rpz'),
|
||||
'csv' => array('csv', 'CsvExport', 'csv'),
|
||||
'cache' => array('txt', 'CacheExport', 'cache'),
|
||||
'attack' => array('html', 'AttackExport', 'html')
|
||||
'cache' => array('txt', 'CacheExport', 'cache')
|
||||
);
|
||||
|
||||
// FIXME we need a better way to list the defaultCategories knowing that new attribute types will continue to appear in the future. We should generate this dynamically or use a function using the default_category of the $typeDefinitions
|
||||
|
@ -3168,8 +3167,10 @@ class Attribute extends AppModel
|
|||
}
|
||||
if (!empty($results[$key])) {
|
||||
if (!empty($options['includeGalaxy'])) {
|
||||
$results[$key] = $this->Event->massageTags($results[$key], 'Attribute');
|
||||
$results[$key] = $this->Event->massageTags($results[$key], 'Event');
|
||||
$massaged_attribute = $this->Event->massageTags($results[$key], 'Attribute');
|
||||
$massaged_event = $this->Event->massageTags($results[$key], 'Event');
|
||||
$massaged_attribute['Galaxy'] = array_merge_recursive($massaged_attribute['Galaxy'], $massaged_event['Galaxy']);
|
||||
$results[$key] = $massaged_attribute;
|
||||
}
|
||||
$attributes[] = $results[$key];
|
||||
}
|
||||
|
@ -3803,7 +3804,6 @@ class Attribute extends AppModel
|
|||
} else {
|
||||
$date = new DateTime();
|
||||
$attribute['timestamp'] = $date->getTimestamp();
|
||||
;
|
||||
}
|
||||
} else {
|
||||
$this->create();
|
||||
|
@ -3909,6 +3909,72 @@ class Attribute extends AppModel
|
|||
return true;
|
||||
}
|
||||
|
||||
public function deleteAttribute($id, $user, $hard = false)
|
||||
{
|
||||
$this->id = $id;
|
||||
if (!$this->exists()) {
|
||||
return false;
|
||||
}
|
||||
$result = $this->find('first', array(
|
||||
'conditions' => array('Attribute.id' => $id),
|
||||
'recursive' => -1,
|
||||
'contain' => array('Event')
|
||||
));
|
||||
if (empty($result)) {
|
||||
throw new MethodNotAllowedException(__('Attribute not found or not authorised.'));
|
||||
}
|
||||
|
||||
// check for permissions
|
||||
if (!$user['Role']['perm_site_admin']) {
|
||||
if ($result['Event']['locked']) {
|
||||
if ($user['org_id'] != $result['Event']['org_id'] || !$user['Role']['perm_sync']) {
|
||||
throw new MethodNotAllowedException(__('Attribute not found or not authorised.'));
|
||||
}
|
||||
} else {
|
||||
if ($user['org_id'] != $result['Event']['orgc_id']) {
|
||||
throw new MethodNotAllowedException(__('Attribute not found or not authorised.'));
|
||||
}
|
||||
}
|
||||
}
|
||||
$date = new DateTime();
|
||||
if ($hard) {
|
||||
$save = $this->delete($id);
|
||||
} else {
|
||||
if (Configure::read('Security.sanitise_attribute_on_delete')) {
|
||||
$result['Attribute']['category'] = 'Other';
|
||||
$result['Attribute']['type'] = 'comment';
|
||||
$result['Attribute']['value'] = 'deleted';
|
||||
$result['Attribute']['comment'] = '';
|
||||
$result['Attribute']['to_ids'] = 0;
|
||||
}
|
||||
$result['Attribute']['deleted'] = 1;
|
||||
$result['Attribute']['timestamp'] = $date->getTimestamp();
|
||||
$save = $this->save($result);
|
||||
$object_refs = $this->Object->ObjectReference->find('all', array(
|
||||
'conditions' => array(
|
||||
'ObjectReference.referenced_type' => 0,
|
||||
'ObjectReference.referenced_id' => $id,
|
||||
),
|
||||
'recursive' => -1
|
||||
));
|
||||
foreach ($object_refs as $ref) {
|
||||
$ref['ObjectReference']['deleted'] = 1;
|
||||
$this->Object->ObjectReference->save($ref);
|
||||
}
|
||||
}
|
||||
// attachment will be deleted with the beforeDelete() function in the Model
|
||||
if ($save) {
|
||||
// We have just deleted the attribute, let's also check if there are any shadow attributes that were attached to it and delete them
|
||||
$this->Event->ShadowAttribute->deleteAll(array('ShadowAttribute.old_id' => $id), false);
|
||||
|
||||
// remove the published flag from the event
|
||||
$this->Event->unpublishEvent($result['Event']['id']);
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
public function attachValidationWarnings($adata)
|
||||
{
|
||||
if (!$this->__fTool) {
|
||||
|
|
|
@ -111,45 +111,58 @@ class AttributeTag extends AppModel
|
|||
));
|
||||
}
|
||||
|
||||
public function getTagScores($eventId=0, $allowedTags=array())
|
||||
// Fetch all tags attached to attribute belonging to supplied event. No ACL if user not provided
|
||||
public function getTagScores($user=false, $eventId=0, $allowedTags=array())
|
||||
{
|
||||
// get score of galaxy
|
||||
$db = $this->getDataSource();
|
||||
$statementArray = array(
|
||||
'fields' => array('attr_tag.tag_id as id', 'count(attr_tag.tag_id) as value'),
|
||||
'table' => $db->fullTableName($this),
|
||||
'alias' => 'attr_tag',
|
||||
'group' => 'tag_id'
|
||||
);
|
||||
if ($eventId != 0) {
|
||||
$statementArray['conditions'] = array('event_id' => $eventId);
|
||||
}
|
||||
// tag along with its occurence in the event
|
||||
$subQuery = $db->buildStatement(
|
||||
$statementArray,
|
||||
$this
|
||||
);
|
||||
$subQueryExpression = $db->expression($subQuery)->value;
|
||||
// get related galaxies
|
||||
$attributeTagScores = $this->query("SELECT name, value FROM (" . $subQueryExpression . ") AS score, tags WHERE tags.id=score.id;");
|
||||
|
||||
// arrange data
|
||||
$scores = array();
|
||||
$maxScore = 0;
|
||||
foreach ($attributeTagScores as $item) {
|
||||
$score = $item['score']['value'];
|
||||
$name = $item['tags']['name'];
|
||||
if (in_array($name, $allowedTags)) {
|
||||
$maxScore = $score > $maxScore ? $score : $maxScore;
|
||||
$scores[$name] = $score;
|
||||
if ($user === false) {
|
||||
$conditions = array('Tag.id !=' => null);
|
||||
if ($eventId != 0) {
|
||||
$conditions['event_id'] = $eventId;
|
||||
}
|
||||
$attribute_tag_scores = $this->find('all', array(
|
||||
'recursive' => -1,
|
||||
'conditions' => $conditions,
|
||||
'contain' => array(
|
||||
'Tag' => array(
|
||||
'conditions' => array('name' => $allowedTags)
|
||||
)
|
||||
),
|
||||
'fields' => array('Tag.name', 'AttributeTag.event_id')
|
||||
));
|
||||
$scores = array('scores' => array(), 'maxScore' => 0);
|
||||
foreach ($attribute_tag_scores as $attribute_tag_score) {
|
||||
$tag_name = $attribute_tag_score['Tag']['name'];
|
||||
if (!isset($scores['scores'][$tag_name])) {
|
||||
$scores['scores'][$tag_name] = 0;
|
||||
}
|
||||
$scores['scores'][$tag_name]++;
|
||||
$scores['maxScore'] = $scores['scores'][$tag_name] > $scores['maxScore'] ? $scores['scores'][$tag_name] : $scores['maxScore'];
|
||||
}
|
||||
} else {
|
||||
$allowed_tag_lookup_table = array_flip($allowedTags);
|
||||
$attributes = $this->Attribute->fetchAttributes($user, array('conditions' => array(
|
||||
'Attribute.event_id' => $eventId
|
||||
)));
|
||||
$scores = array('scores' => array(), 'maxScore' => 0);
|
||||
foreach ($attributes as $attribute) {
|
||||
foreach ($attribute['AttributeTag'] as $tag) {
|
||||
$tag_name = $tag['Tag']['name'];
|
||||
if (isset($allowed_tag_lookup_table[$tag_name])) {
|
||||
if (!isset($scores['scores'][$tag_name])) {
|
||||
$scores['scores'][$tag_name] = 0;
|
||||
}
|
||||
$scores['scores'][$tag_name]++;
|
||||
$scores['maxScore'] = $scores['scores'][$tag_name] > $scores['maxScore'] ? $scores['scores'][$tag_name] : $scores['maxScore'];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return array('scores' => $scores, 'maxScore' => $maxScore);
|
||||
return $scores;
|
||||
}
|
||||
|
||||
|
||||
// find all tags that belong to a list of attributes (contained in the same event)
|
||||
public function getAttributesTags($user, $requestedEventId, $attributeIds=false) {
|
||||
public function getAttributesTags($user, $requestedEventId, $attributeIds=false, $includeGalaxies=false) {
|
||||
$conditions = array('Attribute.event_id' => $requestedEventId);
|
||||
if (is_array($attributeIds) && $attributeIds !== false) {
|
||||
$conditions['Attribute.id'] = $attributeIds;
|
||||
|
@ -169,12 +182,11 @@ class AttributeTag extends AppModel
|
|||
'recursive' => -1,
|
||||
'fields' => array('GalaxyCluster.tag_name', 'GalaxyCluster.id'),
|
||||
));
|
||||
|
||||
$allTags = array();
|
||||
foreach ($attributes as $attribute) {
|
||||
$attributeTags = $attribute['AttributeTag'];
|
||||
foreach ($attributeTags as $k => $attributeTag) {
|
||||
if (!isset($cluster_names[$attributeTag['Tag']['name']])) {
|
||||
if ($includeGalaxies || !isset($cluster_names[$attributeTag['Tag']['name']])) {
|
||||
$allTags[$attributeTag['Tag']['id']] = $attributeTag['Tag'];
|
||||
}
|
||||
}
|
||||
|
|
|
@ -154,7 +154,7 @@ class EventTag extends AppModel
|
|||
}
|
||||
return $tags;
|
||||
}
|
||||
|
||||
|
||||
public function countForTag($tag_id, $user)
|
||||
{
|
||||
return $this->find('count', array(
|
||||
|
@ -163,39 +163,96 @@ class EventTag extends AppModel
|
|||
));
|
||||
}
|
||||
|
||||
public function getTagScores($eventId=0, $allowedTags=array())
|
||||
public function getTagScores($eventId=0, $allowedTags=array(), $propagateToAttribute=false)
|
||||
{
|
||||
// get score of galaxy
|
||||
$db = $this->getDataSource();
|
||||
$statementArray = array(
|
||||
'fields' => array('event_tag.tag_id as id', 'count(event_tag.tag_id) as value'),
|
||||
'table' => $db->fullTableName($this),
|
||||
'alias' => 'event_tag',
|
||||
'group' => 'tag_id'
|
||||
);
|
||||
if ($eventId != 0) {
|
||||
$statementArray['conditions'] = array('event_id' => $eventId);
|
||||
if ($propagateToAttribute) {
|
||||
$eventTagScores = $this->find('all', array(
|
||||
'recursive' => -1,
|
||||
'conditions' => array('Tag.id !=' => null),
|
||||
'contain' => array(
|
||||
'Event',
|
||||
'Tag' => array(
|
||||
'conditions' => array('name' => $allowedTags)
|
||||
)
|
||||
),
|
||||
'fields' => array('Tag.name', 'Event.attribute_count')
|
||||
));
|
||||
} else {
|
||||
$conditions = array('Tag.id !=' => null);
|
||||
if ($eventId != 0) {
|
||||
$conditions['event_id'] = $eventId;
|
||||
}
|
||||
$eventTagScores = $this->find('all', array(
|
||||
'recursive' => -1,
|
||||
'conditions' => $conditions,
|
||||
'contain' => array(
|
||||
'Tag' => array(
|
||||
'conditions' => array('name' => $allowedTags)
|
||||
)
|
||||
),
|
||||
'group' => 'tag_id',
|
||||
'fields' => array('Tag.name', 'EventTag.tag_id', 'count(EventTag.tag_id) as score')
|
||||
));
|
||||
}
|
||||
// tag along with its occurence in the event
|
||||
$subQuery = $db->buildStatement(
|
||||
$statementArray,
|
||||
$this
|
||||
);
|
||||
$subQueryExpression = $db->expression($subQuery)->value;
|
||||
// get related galaxies
|
||||
$attributeTagScores = $this->query("SELECT name, value FROM (" . $subQueryExpression . ") AS score, tags WHERE tags.id=score.id;");
|
||||
|
||||
// arrange data
|
||||
$scores = array();
|
||||
$maxScore = 0;
|
||||
foreach ($attributeTagScores as $item) {
|
||||
$score = $item['score']['value'];
|
||||
$name = $item['tags']['name'];
|
||||
foreach ($eventTagScores as $item) {
|
||||
$score = isset($item['Event']) ? $item['Event']['attribute_count'] : $item[0]['score'];
|
||||
$name = $item['Tag']['name'];
|
||||
if (in_array($name, $allowedTags)) {
|
||||
$maxScore = $score > $maxScore ? $score : $maxScore;
|
||||
$scores[$name] = $score;
|
||||
if (!isset($scores[$name])) {
|
||||
$scores[$name] = 0;
|
||||
}
|
||||
$scores[$name] += $score;
|
||||
}
|
||||
}
|
||||
return array('scores' => $scores, 'maxScore' => $maxScore);
|
||||
}
|
||||
|
||||
// Fetch all tags contained in an event (both event and attributes) ignoring the occurence. No ACL
|
||||
public function getTagScoresUniform($eventId=0, $allowedTags=array())
|
||||
{
|
||||
$conditions = array('Tag.id !=' => null);
|
||||
if ($eventId != 0) {
|
||||
$conditions['event_id'] = $eventId;
|
||||
}
|
||||
$event_tag_scores = $this->find('all', array(
|
||||
'recursive' => -1,
|
||||
'conditions' => $conditions,
|
||||
'contain' => array(
|
||||
'Tag' => array(
|
||||
'conditions' => array('name' => $allowedTags)
|
||||
)
|
||||
),
|
||||
'fields' => array('Tag.name', 'EventTag.event_id')
|
||||
));
|
||||
$attribute_tag_scores = $this->Event->Attribute->AttributeTag->find('all', array(
|
||||
'recursive' => -1,
|
||||
'conditions' => $conditions,
|
||||
'contain' => array(
|
||||
'Tag' => array(
|
||||
'conditions' => array('name' => $allowedTags)
|
||||
)
|
||||
),
|
||||
'fields' => array('Tag.name', 'AttributeTag.event_id')
|
||||
));
|
||||
|
||||
$score_aggregation = array();
|
||||
foreach ($event_tag_scores as $event_tag_score) {
|
||||
$score_aggregation[$event_tag_score['Tag']['name']][$event_tag_score['EventTag']['event_id']] = 1;
|
||||
}
|
||||
foreach ($attribute_tag_scores as $attribute_tag_score) {
|
||||
$score_aggregation[$attribute_tag_score['Tag']['name']][$attribute_tag_score['AttributeTag']['event_id']] = 1;
|
||||
}
|
||||
$scores = array('scores' => array(), 'maxScore' => 0);
|
||||
foreach ($score_aggregation as $name => $array_ids) {
|
||||
$event_count = count($array_ids);
|
||||
$scores['scores'][$name] = $event_count;
|
||||
$scores['maxScore'] = $event_count > $scores['maxScore'] ? $event_count : $scores['maxScore'];
|
||||
}
|
||||
return $scores;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -397,7 +397,7 @@ class Galaxy extends AppModel
|
|||
return $galaxies;
|
||||
}
|
||||
|
||||
public function getMatrix($galaxy_id)
|
||||
public function getMatrix($galaxy_id, $scores=array())
|
||||
{
|
||||
$conditions = array('Galaxy.id' => $galaxy_id);
|
||||
$contains = array(
|
||||
|
@ -454,18 +454,7 @@ class Galaxy extends AppModel
|
|||
}
|
||||
$matrixData['tabs'] = $cols;
|
||||
|
||||
foreach ($matrixData['tabs'] as $k => $v) {
|
||||
foreach ($matrixData['tabs'][$k] as $kc => $v2) {
|
||||
// sort clusters in the kill chains
|
||||
usort(
|
||||
$matrixData['tabs'][$k][$kc],
|
||||
function($a, $b) {
|
||||
return strcmp($a['value'], $b['value']);
|
||||
}
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
$this->sortMatrixByScore($matrixData['tabs'], $scores);
|
||||
// #FIXME temporary fix: retreive tag name of deprecated mitre galaxies (for the stats)
|
||||
if ($galaxy['Galaxy']['id'] == $this->getMitreAttackGalaxyId()) {
|
||||
$names = array('Enterprise Attack - Attack Pattern', 'Pre Attack - Attack Pattern', 'Mobile Attack - Attack Pattern');
|
||||
|
@ -486,4 +475,34 @@ class Galaxy extends AppModel
|
|||
$matrixData['matrixTags'] = array_keys($matrixData['matrixTags']);
|
||||
return $matrixData;
|
||||
}
|
||||
|
||||
public function sortMatrixByScore(&$tabs, $scores)
|
||||
{
|
||||
foreach (array_keys($tabs) as $i) {
|
||||
foreach (array_keys($tabs[$i]) as $j) {
|
||||
// major ordering based on score, minor based on alphabetical
|
||||
usort($tabs[$i][$j], function ($a, $b) use($scores) {
|
||||
if ($a['tag_name'] == $b['tag_name']) {
|
||||
return 0;
|
||||
}
|
||||
if (isset($scores[$a['tag_name']]) && isset($scores[$b['tag_name']])) {
|
||||
if ($scores[$a['tag_name']] < $scores[$b['tag_name']]) {
|
||||
$ret = 1;
|
||||
} else if ($scores[$a['tag_name']] == $scores[$b['tag_name']]) {
|
||||
$ret = strcmp($a['value'], $b['value']);
|
||||
} else {
|
||||
$ret = -1;
|
||||
}
|
||||
} else if (isset($scores[$a['tag_name']])) {
|
||||
$ret = -1;
|
||||
} else if (isset($scores[$b['tag_name']])) {
|
||||
$ret = 1;
|
||||
} else { // none are set
|
||||
$ret = strcmp($a['value'], $b['value']);
|
||||
}
|
||||
return $ret;
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -725,4 +725,114 @@ class MispObject extends AppModel
|
|||
}
|
||||
return count($orphans);
|
||||
}
|
||||
|
||||
public function validObjectsFromAttributeTypes($user, $event_id, $selected_attribute_ids)
|
||||
{
|
||||
$attributes = $this->Attribute->fetchAttributes($user,
|
||||
array(
|
||||
'conditions' => array(
|
||||
'Attribute.id' => $selected_attribute_ids,
|
||||
'Attribute.event_id' => $event_id,
|
||||
'Attribute.object_id' => 0
|
||||
),
|
||||
)
|
||||
);
|
||||
if (empty($attributes)) {
|
||||
return array('templates' => array(), 'types' => array());
|
||||
}
|
||||
$attribute_types = array();
|
||||
foreach ($attributes as $i => $attribute) {
|
||||
$attribute_types[$attribute['Attribute']['type']] = 1;
|
||||
$attributes[$i]['Attribute']['object_relation'] = $attribute['Attribute']['type'];
|
||||
}
|
||||
$attribute_types = array_keys($attribute_types);
|
||||
|
||||
$potential_templates = $this->ObjectTemplate->find('all', array(
|
||||
'recursive' => -1,
|
||||
'fields' => array(
|
||||
'ObjectTemplate.id',
|
||||
'ObjectTemplate.name',
|
||||
'COUNT(ObjectTemplateElement.type) as type_count'
|
||||
),
|
||||
'conditions' => array(
|
||||
'ObjectTemplate.active' => true,
|
||||
'ObjectTemplateElement.type' => $attribute_types
|
||||
),
|
||||
'joins' => array(
|
||||
array(
|
||||
'table' => 'object_template_elements',
|
||||
'alias' => 'ObjectTemplateElement',
|
||||
'type' => 'RIGHT',
|
||||
'fields' => array('ObjectTemplateElement.object_relation', 'ObjectTemplateElement.type'),
|
||||
'conditions' => array('ObjectTemplate.id = ObjectTemplateElement.object_template_id')
|
||||
)
|
||||
),
|
||||
'group' => 'ObjectTemplate.name',
|
||||
'order' => 'type_count DESC'
|
||||
));
|
||||
|
||||
$potential_template_ids = Hash::extract($potential_templates, '{n}.ObjectTemplate.id');
|
||||
$templates = $this->ObjectTemplate->find('all', array(
|
||||
'recursive' => -1,
|
||||
'conditions' => array('id' => $potential_template_ids),
|
||||
'contain' => 'ObjectTemplateElement'
|
||||
));
|
||||
|
||||
foreach ($templates as $i => $template) {
|
||||
$res = $this->ObjectTemplate->checkTemplateConformityBasedOnTypes($template, $attributes);
|
||||
$templates[$i]['ObjectTemplate']['compatibility'] = $res['valid'] ? true : $res['missingTypes'];
|
||||
$templates[$i]['ObjectTemplate']['invalidTypes'] = $res['invalidTypes'];
|
||||
$templates[$i]['ObjectTemplate']['invalidTypesMultiple'] = $res['invalidTypesMultiple'];
|
||||
}
|
||||
return array('templates' => $templates, 'types' => $attribute_types);
|
||||
}
|
||||
|
||||
public function groupAttributesIntoObject($user, $event_id, $object, $template, $selected_attribute_ids, $selected_object_relation_mapping, $hard_delete_attribute)
|
||||
{
|
||||
$saved_object_id = $this->saveObject($object, $event_id, $template, $user);
|
||||
if (!is_numeric($saved_object_id)) {
|
||||
return $saved_object_id;
|
||||
}
|
||||
|
||||
$saved_object = $this->find('first', array(
|
||||
'recursive' => -1,
|
||||
'conditions' => array('Object.id' => $saved_object_id)
|
||||
));
|
||||
|
||||
$existing_attributes = $this->Attribute->fetchAttributes($user, array('conditions' => array(
|
||||
'Attribute.id' => $selected_attribute_ids,
|
||||
'Attribute.event_id' => $event_id,
|
||||
'Attribute.object_id' => 0
|
||||
)));
|
||||
|
||||
if (empty($existing_attributes)) {
|
||||
return __('Selected Attributes do not exist.');
|
||||
}
|
||||
$event = array('Event' => $existing_attributes[0]['Event']);
|
||||
|
||||
// Duplicate the attribute and its context, otherwise connected instances will drop the duplicated UUID
|
||||
foreach ($existing_attributes as $i => $existing_attribute) {
|
||||
if (isset($selected_object_relation_mapping[$existing_attribute['Attribute']['id']])) {
|
||||
$sightings = $this->Event->Sighting->attachToEvent($event, $user, $existing_attribute['Attribute']['id']);
|
||||
$object_relation = $selected_object_relation_mapping[$existing_attribute['Attribute']['id']];
|
||||
$created_attribute = $existing_attribute['Attribute'];
|
||||
unset($created_attribute['timestamp']);
|
||||
unset($created_attribute['id']);
|
||||
unset($created_attribute['uuid']);
|
||||
$created_attribute['object_relation'] = $object_relation;
|
||||
$created_attribute['object_id'] = $saved_object['Object']['id'];
|
||||
if (isset($existing_attribute['AttributeTag'])) {
|
||||
$created_attribute['AttributeTag'] = $existing_attribute['AttributeTag'];
|
||||
}
|
||||
if (!empty($sightings)) {
|
||||
$created_attribute['Sighting'] = $sightings;
|
||||
}
|
||||
$saved_object['Attribute'][$i] = $created_attribute;
|
||||
$this->Attribute->captureAttribute($created_attribute, $event_id, $user, $saved_object['Object']['id']);
|
||||
$this->Attribute->deleteAttribute($existing_attribute['Attribute']['id'], $user, $hard_delete_attribute);
|
||||
}
|
||||
}
|
||||
return $saved_object['Object']['id'];
|
||||
|
||||
}
|
||||
}
|
||||
|
|
|
@ -204,6 +204,74 @@ class ObjectTemplate extends AppModel
|
|||
return true;
|
||||
}
|
||||
|
||||
public function checkTemplateConformityBasedOnTypes($template, $attributes)
|
||||
{
|
||||
$to_return = array('valid' => true, 'missingTypes' => array());
|
||||
if (!empty($template['ObjectTemplate']['requirements'])) {
|
||||
// check for all required attributes
|
||||
if (!empty($template['ObjectTemplate']['requirements']['required'])) {
|
||||
foreach ($template['ObjectTemplate']['requirements']['required'] as $requiredField) {
|
||||
$requiredType = Hash::extract($template['ObjectTemplateElement'], sprintf('{n}[object_relation=%s].type', $requiredField))[0];
|
||||
$found = false;
|
||||
foreach ($attributes as $attribute) {
|
||||
if ($attribute['Attribute']['type'] == $requiredType) {
|
||||
$found = true;
|
||||
}
|
||||
}
|
||||
if (!$found) {
|
||||
$to_return = array('valid' => false, 'missingTypes' => array($requiredType));
|
||||
}
|
||||
}
|
||||
}
|
||||
// check for all required one of attributes
|
||||
if (!empty($template['ObjectTemplate']['requirements']['requiredOneOf'])) {
|
||||
$found = false;
|
||||
$all_required_type = array();
|
||||
foreach ($template['ObjectTemplate']['requirements']['requiredOneOf'] as $requiredField) {
|
||||
$requiredType = Hash::extract($template['ObjectTemplateElement'], sprintf('{n}[object_relation=%s].type', $requiredField));
|
||||
$requiredType = empty($requiredType) ? NULL : $requiredType[0];
|
||||
$all_required_type[] = $requiredType;
|
||||
foreach ($attributes as $attribute) {
|
||||
if ($attribute['Attribute']['type'] == $requiredType) {
|
||||
$found = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (!$found) {
|
||||
$to_return = array('valid' => false, 'missingTypes' => $all_required_type);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// at this point, an object could created; checking if all attribute are valids
|
||||
$valid_types = array();
|
||||
$to_return['invalidTypes'] = array();
|
||||
$to_return['invalidTypesMultiple'] = array();
|
||||
foreach ($template['ObjectTemplateElement'] as $templateElement) {
|
||||
$valid_types[$templateElement['type']] = $templateElement['multiple'];
|
||||
}
|
||||
$check_for_multiple_type = array();
|
||||
foreach ($attributes as $attribute) {
|
||||
if (isset($valid_types[$attribute['Attribute']['type']])) {
|
||||
if (!$valid_types[$attribute['Attribute']['type']]) { // is not multiple
|
||||
if (isset($check_for_multiple_type[$attribute['Attribute']['type']])) {
|
||||
$to_return['invalidTypesMultiple'][] = $attribute['Attribute']['type'];
|
||||
} else {
|
||||
$check_for_multiple_type[$attribute['Attribute']['type']] = 1;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
$to_return['invalidTypes'][] = $attribute['Attribute']['type'];
|
||||
}
|
||||
}
|
||||
$to_return['invalidTypes'] = array_unique($to_return['invalidTypes']);
|
||||
$to_return['invalidTypesMultiple'] = array_unique($to_return['invalidTypesMultiple']);
|
||||
if (!empty($to_return['invalidTypesMultiple'])) {
|
||||
$to_return['valid'] = false;
|
||||
}
|
||||
return $to_return;
|
||||
}
|
||||
|
||||
// simple test to see if there are any object templates - if not trigger update
|
||||
public function populateIfEmpty($user)
|
||||
{
|
||||
|
|
|
@ -24,11 +24,21 @@
|
|||
$full = $isAclTagger && $tagAccess;
|
||||
$tagData = "";
|
||||
foreach ($tags as $tag) {
|
||||
if (empty($tag['Tag'])) {
|
||||
$tag['Tag'] = $tag;
|
||||
}
|
||||
if (empty($tag['Tag']['colour'])) {
|
||||
$tag['Tag']['colour'] = '#0088cc';
|
||||
}
|
||||
$aStyle = 'display:inline-block; background-color:' . h($tag['Tag']['colour']) . ';color:' . $this->TextColour->getTextColour($tag['Tag']['colour']) . ';';
|
||||
$aClass = $full ? 'tagFirstHalf' : 'tag';
|
||||
$aText = h($tag['Tag']['name']);
|
||||
$aSearchTagUrl = $baseurl . '/events/index/searchtag: ' . h($tag['Tag']['id']);
|
||||
$span1 = sprintf('<a href="%s" style="%s" class="%s">%s</a>', $aSearchTagUrl, $aStyle, $aClass, $aText);
|
||||
if (!empty($tag['Tag']['id'])) {
|
||||
$aSearchTagUrl = $baseurl . '/events/index/searchtag: ' . h($tag['Tag']['id']);
|
||||
$span1 = sprintf('<a href="%s" style="%s" class="%s">%s</a>', $aSearchTagUrl, $aStyle, $aClass, $aText);
|
||||
} else {
|
||||
$aSpan1 = sprintf('<span style="%s" class="%s">%s</span>', $aStyle, $aClass, $aText);
|
||||
}
|
||||
$span2 = '';
|
||||
if ($full) {
|
||||
$spanClass = "tagSecondHalf useCursorPointer noPrint";
|
||||
|
|
|
@ -79,6 +79,15 @@
|
|||
'onClick' => 'popoverPopup',
|
||||
'onClickParams' => array('this', 'selected/attribute', 'galaxies', 'selectGalaxyNamespace')
|
||||
),
|
||||
array(
|
||||
'id' => 'group-into-object-button',
|
||||
'title' => __('Group selected Attributes into an Object'),
|
||||
'class' => 'mass-select hidden',
|
||||
'fa-icon' => 'object-group',
|
||||
'fa-source' => 'fa',
|
||||
'onClick' => 'proposeObjectsFromSelectedAttributes',
|
||||
'onClickParams' => array('this', $event['Event']['id'])
|
||||
),
|
||||
array(
|
||||
'id' => 'multi-delete-button',
|
||||
'title' => __('Delete selected Attributes'),
|
||||
|
|
|
@ -101,12 +101,12 @@ foreach($tabs as $tabName => $column):
|
|||
</div>
|
||||
<?php endif; ?>
|
||||
|
||||
<div id="matrix_container" class="fixed-table-container-inner" style="max-height: 670px;" data-picking-mode="<?php echo $pickingMode ? 'true' : 'false'; ?>">
|
||||
<div id="matrix_container" class="fixed-table-container-inner" style="" data-picking-mode="<?php echo $pickingMode ? 'true' : 'false'; ?>">
|
||||
<div class="tab-content">
|
||||
<?php foreach($tabs as $tabName => $column): ?>
|
||||
<div class="tab-pane <?php echo $tabName==$defaultTabName ? "active" : ""; ?>" id="tabMatrix-<?php echo h($tabName); ?>">
|
||||
<div class="header-background"></div>
|
||||
<div class="fixed-table-container-inner" style="max-height: 670px;">
|
||||
<div class="fixed-table-container-inner" style="">
|
||||
<table class="table table-condensed matrix-table">
|
||||
<thead>
|
||||
<tr>
|
||||
|
@ -116,7 +116,10 @@ foreach($tabs as $tabName => $column):
|
|||
?>
|
||||
<th>
|
||||
<?php echo h(ucfirst($name)); ?>
|
||||
<div class="th-inner"><?php echo h(ucfirst($name)); ?></div>
|
||||
<div class="th-inner" style="flex-direction: column; align-items: flex-start; padding-top: 3px;">
|
||||
<span><?php echo h(ucfirst($name)); ?></span>
|
||||
<i style="font-size: smaller;"><?php echo sprintf(__('(%s items)'), isset($column[$co]) ? count($column[$co]) : 0); ?></i>
|
||||
</div>
|
||||
</th>
|
||||
|
||||
<?php endforeach; ?>
|
||||
|
@ -197,5 +200,5 @@ foreach($tabs as $tabName => $column):
|
|||
</select>
|
||||
</div>
|
||||
<div class="templateChoiceButton btn-matrix-submit submit-container hide"><?php echo __('Submit'); ?></div>
|
||||
<div role="button" tabindex="0" aria-label="<?php echo __('Cancel');?>" title="<?php echo __('Cancel');?>" class="templateChoiceButton templateChoiceButtonLast" onClick="cancelPopoverForm('#popover_form_large');"><?php echo __('Cancel'); ?></div>
|
||||
<div role="button" tabindex="0" aria-label="<?php echo __('Cancel');?>" title="<?php echo __('Cancel');?>" class="templateChoiceButton templateChoiceButtonLast" onClick="cancelPopoverForm('#popover_matrix');"><?php echo __('Cancel'); ?></div>
|
||||
<?php endif; ?>
|
||||
|
|
|
@ -16,8 +16,36 @@
|
|||
?>
|
||||
</ul>
|
||||
</div>
|
||||
<div>
|
||||
<?php
|
||||
$data = array(
|
||||
'children' => array(
|
||||
array(
|
||||
'children' => array(
|
||||
array(
|
||||
'class' => 'hidden mass-select',
|
||||
'fa-icon' => 'trash',
|
||||
'onClick' => "multiSelectDeleteEventBlacklist",
|
||||
'onClickParams' => array('1', '0')
|
||||
)
|
||||
)
|
||||
),
|
||||
array(
|
||||
'type' => 'search',
|
||||
'button' => __('Filter'),
|
||||
'placeholder' => __('Enter value to search'),
|
||||
'data' => '',
|
||||
)
|
||||
)
|
||||
);
|
||||
echo $this->element('/genericElements/ListTopBar/scaffold', array('data' => $data));
|
||||
?>
|
||||
</div>
|
||||
<table class="table table-striped table-hover table-condensed">
|
||||
<tr>
|
||||
<th>
|
||||
<input class="select_all select" type="checkbox" title="<?php echo __('Select all');?>" role="button" tabindex="0" aria-label="<?php echo __('Select all events on current page');?>" onClick="toggleAllCheckboxes();" />
|
||||
</th>
|
||||
<th><?php echo $this->Paginator->sort('id');?></th>
|
||||
<th><?php echo $this->Paginator->sort('org');?></th>
|
||||
<th><?php echo $this->Paginator->sort('event_uuid', __('Event UUID'));?></th>
|
||||
|
@ -28,6 +56,9 @@
|
|||
</tr><?php
|
||||
foreach ($response as $item): ?>
|
||||
<tr>
|
||||
<td style="width:10px;">
|
||||
<input class="select" type="checkbox" data-id="<?php echo h($item['EventBlacklist']['id']); ?>" aria-label="select <?php echo h($item['EventBlacklist']['id'])?>" />
|
||||
</td>
|
||||
<td class="short"><?php echo h($item['EventBlacklist']['id']); ?> </td>
|
||||
<td class="short"><?php echo (isset($item['EventBlacklist']['event_orgc']) ? h($item['EventBlacklist']['event_orgc']) : ' '); ?></td>
|
||||
<td class="short"><?php echo h($item['EventBlacklist']['event_uuid']); ?> </td>
|
||||
|
@ -35,7 +66,7 @@ foreach ($response as $item): ?>
|
|||
<td class="short"><?php echo (isset($item['EventBlacklist']['event_info']) ? h($item['EventBlacklist']['event_info']) : ' '); ?></td>
|
||||
<td class="short"><?php echo (isset($item['EventBlacklist']['comment']) ? h($item['EventBlacklist']['comment']) : ' '); ?></td>
|
||||
<td class="short action-links">
|
||||
<a href="<?php echo $baseurl;?>/eventBlacklists/edit/<?php echo h($item['EventBlacklist']['id']); ?>"><span class="fa fa-edit" title=<?php echo __('Edit')?> role="button" tabindex="0" aria-label="Edit blacklist entry"> </span></a>
|
||||
<a href="<?php echo $baseurl;?>/eventBlacklists/edit/<?php echo h($item['EventBlacklist']['id']); ?>"><span class="fa fa-edit black" title=<?php echo __('Edit')?> role="button" tabindex="0" aria-label="Edit blacklist entry"> </span></a>
|
||||
<?php echo $this->Form->postLink('', array('action' => 'delete', h($item['EventBlacklist']['id'])), array('class' => 'fa fa-trash', 'title' => __('Delete'), 'aria-label' => __('Delete')), __('Are you sure you want to delete the blacklist entry for the event UUID %s?', h($item['EventBlacklist']['event_uuid']))); ?>
|
||||
</td>
|
||||
</tr><?php
|
||||
|
@ -59,6 +90,25 @@ endforeach; ?>
|
|||
</div>
|
||||
|
||||
</div>
|
||||
<script type="text/javascript">
|
||||
$(document).ready(function(){
|
||||
popoverStartup();
|
||||
$('.select').on('change', function() {
|
||||
listCheckboxesChecked();
|
||||
});
|
||||
$('.select').on('change', function() {
|
||||
listCheckboxesChecked();
|
||||
});
|
||||
$('#quickFilterButton').click(function() {
|
||||
runIndexQuickFilter();
|
||||
});
|
||||
$('#quickFilterField').on('keypress', function (e) {
|
||||
if(e.which === 13) {
|
||||
runIndexQuickFilter();
|
||||
}
|
||||
});
|
||||
});
|
||||
</script>
|
||||
<?php
|
||||
echo $this->element('/genericElements/SideMenu/side_menu', array('menuList' => 'admin', 'menuItem' => 'eventBlacklists'));
|
||||
?>
|
||||
|
|
|
@ -0,0 +1,29 @@
|
|||
<div class="confirmation">
|
||||
<?php
|
||||
echo $this->Form->create('EventBlacklist', array('style' => 'margin:0px;', 'id' => 'PromptForm'));
|
||||
echo $this->Form->input('ids', array(
|
||||
'type' => 'hidden',
|
||||
'div' => 'hidden',
|
||||
'value' => json_encode($event_ids)
|
||||
));
|
||||
?>
|
||||
<legend><?php echo __('Delete blacklisted events'); ?></legend>
|
||||
<div style="padding-left:5px;padding-right:5px;padding-bottom:5px;">
|
||||
<p><?php echo __('Are you sure you want to delete from the blacklist the selected events?'); ?></p>
|
||||
<table>
|
||||
<tr>
|
||||
<td style="vertical-align:top">
|
||||
<span role="button" tabindex="0" aria-label="Publish" title="Publish" id="PromptYesButton" class="btn btn-primary" onClick="submitPublish()">Yes</span>
|
||||
</td>
|
||||
<td style="width:540px;">
|
||||
</td>
|
||||
<td style="vertical-align:top;">
|
||||
<span role="button" tabindex="0" aria-label="Cancel" title="Cancel" class="btn btn-inverse" id="PromptNoButton" onClick="cancelPrompt();">No</span>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
</div>
|
||||
<?php
|
||||
echo $this->Form->end();
|
||||
?>
|
||||
</div>
|
|
@ -10,7 +10,7 @@ App::uses('AppHelper', 'View/Helper');
|
|||
$g = hexdec(substr($RGB, 3, 2));
|
||||
$b = hexdec(substr($RGB, 5, 2));
|
||||
$average = ((2 * $r) + $b + (3 * $g))/6;
|
||||
if ($average < 128) {
|
||||
if ($average < 127) {
|
||||
return 'white';
|
||||
} else {
|
||||
return 'black';
|
||||
|
|
|
@ -40,6 +40,7 @@
|
|||
<body>
|
||||
<div id="popover_form" class="ajax_popover_form"></div>
|
||||
<div id="popover_form_large" class="ajax_popover_form ajax_popover_form_large"></div>
|
||||
<div id="popover_matrix" class="ajax_popover_form ajax_popover_matrix"></div>
|
||||
<div id="popover_box" class="popover_box"></div>
|
||||
<div id="screenshot_box" class="screenshot_box"></div>
|
||||
<div id="confirmation_box" class="confirmation_box"></div>
|
||||
|
|
|
@ -0,0 +1,179 @@
|
|||
<button class="btn btn-inverse" onclick="showObjectProposition()"><i class="fas fa-chevron-left"></i></button>
|
||||
<?php
|
||||
echo $this->Form->create('Object', array('url' => $baseurl . '/objects/groupAttributesIntoObject/' . $event_id . '/' . $selectedTemplateTd));
|
||||
?>
|
||||
<dl style="margin-top: 10px;">
|
||||
<dt><?php echo __('Object Template');?></dt>
|
||||
<dd><a href="<?php echo $baseurl . '/ObjectTemplates/view/' . h($template['ObjectTemplate']['id']) ?>"><?php echo Inflector::humanize(h($template['ObjectTemplate']['name'])) . ' v' . h($template['ObjectTemplate']['version']); ?></a></dd>
|
||||
<dt><?php echo __('Description');?></dt>
|
||||
<dd><?php echo h($template['ObjectTemplate']['description']); ?></dd>
|
||||
<dt><?php echo __('Meta category');?></dt>
|
||||
<dd><?php echo h($template['ObjectTemplate']['meta-category']); ?></dd>
|
||||
<dt><?php echo __('Distribution');?></dt>
|
||||
<dd>
|
||||
<?php echo $this->Form->input('Object.distribution', array(
|
||||
'class' => 'Object_distribution_select',
|
||||
'options' => $distributionData['levels'],
|
||||
'default' => $distributionData['initial'],
|
||||
'label' => false,
|
||||
'style' => 'margin-bottom:5px;',
|
||||
'div' => false
|
||||
)); ?>
|
||||
<?php echo $this->Form->input('Object.sharing_group_id', array(
|
||||
'class' => 'Object_sharing_group_id_select',
|
||||
'options' => $distributionData['sgs'],
|
||||
'label' => false,
|
||||
'div' => false,
|
||||
'style' => 'display:none;margin-bottom:5px;',
|
||||
'value' => 0
|
||||
)); ?>
|
||||
<dt><?php echo __('Comment');?></dt>
|
||||
<dd>
|
||||
<?php echo $this->Form->input('Object.comment', array(
|
||||
'type' => 'textarea',
|
||||
'style' => 'height:20px;width:400px;',
|
||||
'required' => false,
|
||||
'allowEmpty' => true,
|
||||
'label' => false,
|
||||
'div' => false
|
||||
)); ?>
|
||||
<div class="hidden">
|
||||
<?php
|
||||
echo $this->Form->input('selectedTemplateId', array('type' => 'hidden', 'value' => $selectedTemplateTd));
|
||||
echo $this->Form->input('selectedAttributeIds', array('type' => 'hidden', 'value' => json_encode($selectedAttributeIds)));
|
||||
echo $this->Form->input('selectedObjectRelationMapping', array('value' => ''));
|
||||
echo $this->Form->end();
|
||||
?>
|
||||
</div>
|
||||
</dl>
|
||||
|
||||
<div style="border: 2px solid #3465a4 ; border-radius: 3px; overflow: hidden;">
|
||||
<table class="table table-striped table-condensed" style="margin-bottom: 0px;">
|
||||
<thead>
|
||||
<tr>
|
||||
<th><?php echo __('ID'); ?></th>
|
||||
<th><?php echo __('Name :: Type'); ?></th>
|
||||
<th><?php echo __('Date'); ?></th>
|
||||
<th><?php echo __('Category'); ?></th>
|
||||
<th><?php echo __('Value'); ?></th>
|
||||
<th><?php echo __('Distribution'); ?></th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody id='attributeMappingBody'>
|
||||
<?php foreach ($attributes as $attribute): ?>
|
||||
<tr>
|
||||
<td id="isAttributeId"><?php echo h($attribute['Attribute']['id']); ?></td>
|
||||
<td>
|
||||
<span style="display: block;">
|
||||
<select id="isAttributeMapping" style="margin-bottom: 5px;" onchange="updateObjectRelationDescription(this);">
|
||||
<?php foreach ($object_relations[$attribute['Attribute']['type']] as $object_relation): ?>
|
||||
<option value="<?php echo h($object_relation['object_relation']); ?>" title="<?php echo h($object_relation['description']); ?>"><?php echo h($object_relation['object_relation']); ?></option>
|
||||
<?php endforeach; ?>
|
||||
</select>
|
||||
:: <?php echo h($attribute['Attribute']['type']); ?>
|
||||
</span>
|
||||
<i id="objectRelationDescription" class="apply_css_arrow"><?php echo h($object_relations[$attribute['Attribute']['type']][0]['description']); ?></i>
|
||||
</td>
|
||||
<td style="min-width: 75px;"><?php echo h(date('Y-m-d', $attribute['Attribute']['timestamp'])); ?></td>
|
||||
<td><?php echo h($attribute['Attribute']['category']); ?></td>
|
||||
<td style="white-space: nowrap;"><?php echo h($attribute['Attribute']['value']); ?></td>
|
||||
<td><?php echo h($distributionLevels[$attribute['Attribute']['distribution']]); ?></td>
|
||||
</tr>
|
||||
<?php endforeach; ?>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
|
||||
<?php if ($skipped_attributes > 0): ?>
|
||||
<div class="alert" style="margin-top: 15px;">
|
||||
<strong><?php echo __('Skipped'); ?></strong> <?php echo h($skipped_attributes) . __(' Attribute(s)') ?>
|
||||
</div>
|
||||
<?php endif; ?>
|
||||
|
||||
<?php if (!empty($object_references)): ?>
|
||||
<div class="alert alert-danger" style="margin-top: 15px;">
|
||||
<strong><?php echo __('Dropped Object references'); ?></strong>
|
||||
<div><?php echo __('As these Attributes are converted into an Objects, the meaning of the Refences might change. If you whish to preserve the References, you will have to created them after the merge. Take note of them!') ?></div>
|
||||
<div><?php echo __('The following References will be dropped after the merge:') ?></div>
|
||||
<div style="max-height: 170px; overflow-y: auto; border: 1px solid #e6cace; border-radius: 4px; padding: 5px;">
|
||||
<table style="margin: 2px;">
|
||||
<?php foreach ($object_references as $object_reference): ?>
|
||||
<?php $object_reference = $object_reference['ObjectReference']; ?>
|
||||
<tr>
|
||||
<td><span style="margin-right: 5px;">•</span></td>
|
||||
<td><?php echo sprintf('<strong>%s</strong> (%s)', h($object_reference['object_name']), h($object_reference['object_id'])); ?></td>
|
||||
<td style="text-align: center;">
|
||||
<div style="display: inline-block; position: relative; margin: 10px 10px 0px 10px; top: -8px;">
|
||||
<span style=""><?php echo h($object_reference['relationship_type']); ?></span>
|
||||
<i class="fas fa-long-arrow-alt-right" style="font-size: x-large; position: absolute; left: calc(50% - 10px); top: 10px;"></i>
|
||||
</div>
|
||||
</td>
|
||||
<td><?php echo sprintf('<strong>%s</strong> (%s)', h($object_reference['attribute_name']), h($object_reference['referenced_id'])); ?></td>
|
||||
<?php if ($object_reference['comment'] !== ''): ?>
|
||||
<td><span style="margin: 0px 10px;">-</span></td>
|
||||
<td style="margin-left: 10px"><?php echo h($object_reference['comment']); ?></td>
|
||||
<?php endif; ?>
|
||||
</tr>
|
||||
<?php endforeach; ?>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
<?php endif; ?>
|
||||
|
||||
|
||||
<div style="margin-top: 15px; text-align: center;">
|
||||
<div>
|
||||
<button class="btn btn-primary" onclick="submitMergeAttributeIntoObjectForm(this);"><?php echo __('Merge above Attributes into an Object'); ?></button>
|
||||
</div>
|
||||
<span class="red bold" data-original-title="" title="">
|
||||
<?php echo sprintf(__('Selected Attributes will be %s deleted'), '<strong style="font-size: medium">' . ($hard_delete_attribute ? __('hard') : __('soft')) . '</strong>'); ?>
|
||||
</span>
|
||||
</div>
|
||||
|
||||
<script>
|
||||
$(".Object_distribution_select").change(function() {
|
||||
checkAndEnable($(this).parent().find('.Object_sharing_group_id_select'), $(this).val() == 4);
|
||||
});
|
||||
|
||||
function submitMergeAttributeIntoObjectForm(btn) {
|
||||
var $btn = $(btn);
|
||||
var $form = $('#ObjectGroupAttributesIntoObjectForm');
|
||||
var attribute_mapping = {};
|
||||
$('#attributeMappingBody').find('tr').each(function() {
|
||||
var $tr = $(this);
|
||||
var attr_id = $tr.find('#isAttributeId').text();
|
||||
var attr_mapping = $tr.find('#isAttributeMapping').val();
|
||||
attribute_mapping[attr_id] = attr_mapping;
|
||||
});
|
||||
$('#ObjectSelectedObjectRelationMapping').val(JSON.stringify(attribute_mapping));
|
||||
var btn_text_backup = '';
|
||||
$.ajax({
|
||||
data: $form.serialize(),
|
||||
beforeSend: function (XMLHttpRequest) {
|
||||
btn_text_backup = $btn.text();
|
||||
$btn.html('<it class="fa fa-spinner fa-spin"></it>');
|
||||
},
|
||||
success:function (data, textStatus) {
|
||||
if (data.errors !== undefined) {
|
||||
showMessage('fail', responseArray.errors);
|
||||
$btn.text(btn_text_backup);
|
||||
return false;
|
||||
} else {
|
||||
location.reload();
|
||||
}
|
||||
},
|
||||
error:function() {
|
||||
showMessage('fail', 'Could not merge Attributes into an Object.');
|
||||
showObjectProposition();
|
||||
},
|
||||
type:"post",
|
||||
url: $form.attr('action')
|
||||
});
|
||||
}
|
||||
|
||||
function updateObjectRelationDescription(changed) {
|
||||
var $select = $(changed);
|
||||
var text = $select.find(":selected").attr('title');
|
||||
$select.parent().parent().find('#objectRelationDescription').text(text);
|
||||
}
|
||||
</script>
|
|
@ -0,0 +1,85 @@
|
|||
<div style="max-width: 1000px; max-height: 800px; overflow-y: auto; min-height: 400px; min-width: 700px;">
|
||||
<div>
|
||||
<?php echo !empty($selected_types) ? '<strong>' . __('Selected types: ') . '</strong>' : ''; ?>
|
||||
<?php foreach ($selected_types as $type): ?>
|
||||
<span class="label label-info"><?php echo h($type) ?></span>
|
||||
<?php endforeach; ?>
|
||||
</div>
|
||||
<?php if (empty($potential_templates)): ?>
|
||||
<?php echo __('No matching Object.'); ?>
|
||||
<?php else: ?>
|
||||
<table id="tableGroupAttributeIntoObject" class="table table-condensed table-hover">
|
||||
<thead>
|
||||
<tr>
|
||||
<th><?php echo __('Template'); ?></th>
|
||||
<th><?php echo __('Object name'); ?></th>
|
||||
<th><?php echo __('Category'); ?></th>
|
||||
<th><?php echo __('Description'); ?></th>
|
||||
<th title="<?php echo __('Compatiblity or Attribute type missing from the selection'); ?>"><?php echo __('Compatiblity'); ?></th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<?php foreach ($potential_templates as $i => $potential_template): ?>
|
||||
<tr class="useCursorPointer" style="<?php echo $potential_template['ObjectTemplate']['compatibility'] === true ? '' : 'cursor: not-allowed;' ?>" data-objecttemplateid="<?php echo h($potential_template['ObjectTemplate']['id']); ?>" data-enabled="<?php echo $potential_template['ObjectTemplate']['compatibility'] === true ? 'true' : 'false'; ?>">
|
||||
<td class="ignoreSelection">
|
||||
<a href="<?php echo $baseurl . '/ObjectTemplates/view/' . h($potential_template['ObjectTemplate']['id']) ?>"><?php echo h($potential_template['ObjectTemplate']['id']); ?></a>
|
||||
</td>
|
||||
<td><?php echo h($potential_template['ObjectTemplate']['name']); ?></td>
|
||||
<td><?php echo h($potential_template['ObjectTemplate']['meta-category']); ?></td>
|
||||
<?php
|
||||
$v = h($potential_template['ObjectTemplate']['description']);
|
||||
$v = strlen($v) > 100 ? substr($v, 0, 100) . '...' : $v;
|
||||
?>
|
||||
<td style="max-width: 500px;" title="<?php echo h($potential_template['ObjectTemplate']['description']); ?>">
|
||||
<?php echo $v; ?>
|
||||
</td>
|
||||
<?php if ($potential_template['ObjectTemplate']['compatibility'] === true): ?>
|
||||
<td>
|
||||
<i class="fa fa-check" style="font-size: medium;" title="<?php echo __('This Object is compatible for the merge'); ?>"></i>
|
||||
<?php if (!empty($potential_template['ObjectTemplate']['invalidTypes'])): ?>
|
||||
<?php foreach ($potential_template['ObjectTemplate']['invalidTypes'] as $type): ?>
|
||||
<span class="label label-warning" title="<?php echo __('This Attribute type cannot be part of this Object template. If you merge the selected Attributes into this object, all Attribute having this type will be ignored.'); ?>"><?php echo h($type); ?></span>
|
||||
<?php endforeach; ?>
|
||||
<?php endif; ?>
|
||||
</td>
|
||||
<?php else: ?>
|
||||
<td style="max-width: 500px;">
|
||||
<?php foreach ($potential_template['ObjectTemplate']['compatibility'] as $type): ?>
|
||||
<span class="label label-important" title="<?php echo __('This Attribute type is missing from the selection. Add it to the selection to be able to merge the selected Attributes into this Object.'); ?>"><?php echo h($type); ?></span>
|
||||
<?php endforeach; ?>
|
||||
<?php foreach ($potential_template['ObjectTemplate']['invalidTypesMultiple'] as $type): ?>
|
||||
<span class="label" title="<?php echo __('This Attribute type is not allowed to be present multiple time in this Object. Consider only picking one.'); ?>"><?php echo h($type); ?></span>
|
||||
<?php endforeach; ?>
|
||||
</td>
|
||||
<?php endif; ?>
|
||||
</tr>
|
||||
<?php endforeach; ?>
|
||||
</tbody>
|
||||
</table>
|
||||
<div id="resultPreview" class="hidden" style="height: calc(100% - 20px);"></div>
|
||||
<?php endif; ?>
|
||||
</div>
|
||||
|
||||
<script>
|
||||
$('#tableGroupAttributeIntoObject > tbody > tr[data-enabled="true"] > td:not(.ignoreSelection)').click(function() {
|
||||
var object_template_id = $(this).parent().data('objecttemplateid');
|
||||
if (object_template_id !== undefined) {
|
||||
var $parentDIV = $('#tableGroupAttributeIntoObject').parent();
|
||||
var bb = $parentDIV[0].getBoundingClientRect();
|
||||
$parentDIV.css({height: bb.height, width: bb.width});
|
||||
$('#tableGroupAttributeIntoObject').toggle('slide');
|
||||
$('#resultPreview').show().html('<div style="align-items: center; justify-content: center; display: flex; height: 100%; width: 100%"><i class="fas fa-spinner fa-spin" style="font-size: xx-large;"></i></div>');
|
||||
$.get('<?php echo $baseurl . '/objects/groupAttributesIntoObject/' . h($event_id) . '/' ?>' + object_template_id + '/' + getSelected(), function(data) {
|
||||
$('#resultPreview').html(data);
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
function showObjectProposition() {
|
||||
$('#resultPreview').html('');
|
||||
$('#tableGroupAttributeIntoObject').toggle('slide', {
|
||||
direction: 'left',
|
||||
});
|
||||
$('#resultPreview').hide();
|
||||
}
|
||||
</script>
|
|
@ -5,19 +5,65 @@
|
|||
?>
|
||||
<p style="margin-bottom: 40px;"><?php echo sprintf(__('A heatmap showing the usage of %s.'), $galaxyName);?></p>
|
||||
|
||||
<select id="galaxyMatrixPicker" onchange="this.options[this.selectedIndex].value && (window.location = window.location.pathname.replace(/\/*galaxy_id:\d+/, '') + '/' + 'galaxy_id:' + this.options[this.selectedIndex].value);" >
|
||||
<?php foreach ($matrixGalaxies as $k => $galaxy): ?>
|
||||
<option value="<?php echo h($galaxy['Galaxy']['id']); ?>" <?php echo $galaxy['Galaxy']['id'] == $galaxyId ? 'selected' : ''; ?> ><?php echo h($galaxy['Galaxy']['name']); ?></option>
|
||||
<?php endforeach; ?>
|
||||
</select>
|
||||
<div style="height: 80px;">
|
||||
<div class="input select">
|
||||
<label>Galaxy</label>
|
||||
<select id="galaxyMatrixPicker" data-toggle="chosen">
|
||||
<?php foreach ($matrixGalaxies as $k => $galaxy): ?>
|
||||
<option value="<?php echo h($galaxy['Galaxy']['id']); ?>" <?php echo $galaxy['Galaxy']['id'] == $galaxyId ? 'selected' : ''; ?> ><?php echo h($galaxy['Galaxy']['name']); ?></option>
|
||||
<?php endforeach; ?>
|
||||
</select>
|
||||
</div>
|
||||
<div class="input select">
|
||||
<label>Organisation</label>
|
||||
<select id="organisationPicker" data-toggle="chosen">
|
||||
<?php foreach ($organisations as $k => $org): ?>
|
||||
<option value="<?php echo isset($org['Organisation']['id']) ? h($org['Organisation']['id']) : ''; ?>" <?php echo $org['Organisation']['id'] == $picked_organisation['Organisation']['id'] ? 'selected' : ''; ?> ><?php echo h($org['Organisation']['name']); ?></option>
|
||||
<?php endforeach; ?>
|
||||
</select>
|
||||
</div>
|
||||
<div style="display: inline-block;">
|
||||
<label>Dates</label>
|
||||
<input id="dateFrom" class="datepicker" placeholder="from" value="<?php echo isset($dateFrom) ? h($dateFrom) : ''; ?>"></input>
|
||||
<i class="fas fa-arrow-right"></i>
|
||||
<input id="dateTo" class="datepicker" placeholder="to" value="<?php echo isset($dateTo) ? h($dateTo) : ''; ?>"></input>
|
||||
</div>
|
||||
<button id="btnSubmit" class="btn btn-primary"><?php echo __('Submit') ?></button>
|
||||
</div>
|
||||
|
||||
<div id="attackmatrix_div" style="position: relative; border: solid 1px;" class="statistics_attack_matrix">
|
||||
<?php
|
||||
echo $this->element('view_galaxy_matrix');
|
||||
?>
|
||||
<div id="attackmatrix_div" style="position: relative; border: solid 1px;" class="statistics_attack_matrix">
|
||||
<?php
|
||||
echo $this->element('view_galaxy_matrix');
|
||||
?>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
<script>
|
||||
$(document).ready(function() {
|
||||
$('#btnSubmit').click(function() {
|
||||
var value = $('#galaxyMatrixPicker').val();
|
||||
var organisation = $('#organisationPicker').val();
|
||||
var dateFrom = $('#dateFrom').val();
|
||||
var dateTo = $('#dateTo').val();
|
||||
var eventTagsOnAttributes = $('#eventTagsOnAttributes').is(':checked');
|
||||
var url = '<?php echo $baseurl; ?>/users/statistics/galaxyMatrix/galaxy_id:' + value
|
||||
if (organisation) {
|
||||
url += '/' + 'organisation:' + organisation;
|
||||
}
|
||||
if (dateFrom) {
|
||||
url += '/' + 'dateFrom:' + dateFrom;
|
||||
}
|
||||
if (dateTo) {
|
||||
url += '/' + 'dateTo:' + dateTo;
|
||||
}
|
||||
$(this).text('').append('<i class="fas fa-spinner fa-spin"></i>')
|
||||
window.location = url;
|
||||
});
|
||||
|
||||
$('[data-toggle="chosen"]').chosen();
|
||||
|
||||
})
|
||||
</script>
|
||||
|
||||
<?php
|
||||
echo $this->element('/genericElements/SideMenu/side_menu', array('menuList' => 'globalActions', 'menuItem' => 'statistics'));
|
||||
|
|
|
@ -1 +1 @@
|
|||
Subproject commit 8c69da1fd9c0be2ec742370f4918f0f88554644f
|
||||
Subproject commit 0ebe2c50a7a04ae2108e0c32da058826cf15387c
|
|
@ -22,6 +22,7 @@ import time
|
|||
import uuid
|
||||
import base64
|
||||
import stix2misp_mapping
|
||||
import stix_edh
|
||||
import stix.extensions.marking.ais
|
||||
from mixbox.namespaces import NamespaceNotFoundError
|
||||
from operator import attrgetter
|
||||
|
@ -1207,7 +1208,9 @@ def _update_namespaces():
|
|||
# can add additional ones whenever it is needed
|
||||
ADDITIONAL_NAMESPACES = [
|
||||
Namespace('http://us-cert.gov/ciscp', 'CISCP',
|
||||
'http://www.us-cert.gov/sites/default/files/STIX_Namespace/ciscp_vocab_v1.1.1.xsd')
|
||||
'http://www.us-cert.gov/sites/default/files/STIX_Namespace/ciscp_vocab_v1.1.1.xsd'),
|
||||
Namespace('http://taxii.mitre.org/messages/taxii_xml_binding-1.1', 'TAXII',
|
||||
'http://docs.oasis-open.org/cti/taxii/v1.1.1/cs01/schemas/TAXII-XMLMessageBinding-Schema.xsd')
|
||||
]
|
||||
for namespace in ADDITIONAL_NAMESPACES:
|
||||
register_namespace(namespace)
|
||||
|
|
|
@ -49,6 +49,9 @@ td.matrix-interaction.cell-picked {
|
|||
overflow-y: auto;
|
||||
max-height: 670px;
|
||||
}
|
||||
#popover_matrix div.fixed-table-container-inner {
|
||||
max-height: calc(80vh - 100px);
|
||||
}
|
||||
|
||||
.extra-wrap {
|
||||
width: 100%;
|
||||
|
|
|
@ -853,6 +853,14 @@ a.proposal_link_red:hover {
|
|||
left: calc(50% - 700px);
|
||||
}
|
||||
|
||||
.ajax_popover_matrix {
|
||||
width: 96vw;
|
||||
min-width: 1400px;
|
||||
left: 2vw;
|
||||
max-height: 80vh;
|
||||
position: absolute;
|
||||
}
|
||||
|
||||
.popover_box {
|
||||
display:none;
|
||||
position: fixed;
|
||||
|
|
|
@ -1,6 +1,4 @@
|
|||
(function () {
|
||||
var minWidth = 1400;
|
||||
var savedTopOffset;
|
||||
var clusterNameToIdMapping = new Map();
|
||||
var typeaheadDataMatrixSearch;
|
||||
var pickedGalaxies = [];
|
||||
|
@ -13,13 +11,6 @@
|
|||
|
||||
$('#attack-matrix-tabscontroller span').off('click.tab').on('click.tab', function (e) {
|
||||
$(this).tab('show');
|
||||
var jfilter = '.info_container_eventgraph_network';
|
||||
var colNum = $(jfilter+' .matrix-table > thead > tr > th :visible').length;
|
||||
$('#attackmatrix_div').css('min-width', 100*colNum);
|
||||
jfilter = '.ajax_popover_form';
|
||||
var colNum = $(jfilter+' .matrix-table > thead > tr > th :visible').length;
|
||||
$('#popover_form_large').css('min-width', 100*colNum);
|
||||
adapt_position_from_viewport(100*colNum);
|
||||
});
|
||||
|
||||
// form
|
||||
|
@ -31,7 +22,7 @@
|
|||
|
||||
$('.ajax_popover_form .btn-matrix-submit').click(function() {
|
||||
makeTagging(pickedGalaxies);
|
||||
cancelPopoverForm('#popover_form_large');
|
||||
cancelPopoverForm('#popover_matrix');
|
||||
});
|
||||
var scoredCells = $('.ajax_popover_form .heatCell').filter(function() {
|
||||
return $(this).attr('data-score') > 0;
|
||||
|
@ -177,24 +168,8 @@
|
|||
$(jfilter + ' #matrix-heatmap-legend-caret-value').text(score);
|
||||
}
|
||||
|
||||
function adapt_position_from_viewport(minOverwrite) {
|
||||
minOverwrite = minOverwrite !== undefined ? minOverwrite : minWidth;
|
||||
minOverwrite = minWidth > minOverwrite ? minWidth : minOverwrite;
|
||||
if($(window).width()*0.5+700 <= minOverwrite) {
|
||||
var topOff = $('#popover_form_large').offset().top;
|
||||
savedTopOffset = topOff >= $(document).scrollTop() ? topOff - $(document).scrollTop() : topOff;
|
||||
$('#popover_form_large').css({
|
||||
position: 'absolute',
|
||||
left: '10px',
|
||||
top: savedTopOffset+$(document).scrollTop()+'px'
|
||||
});
|
||||
} else {
|
||||
$('#popover_form_large').css({
|
||||
position: 'absolute',
|
||||
left: '',
|
||||
top: savedTopOffset
|
||||
});
|
||||
}
|
||||
function adapt_position_from_viewport() {
|
||||
$('#popover_matrix').css('top', document.documentElement.scrollTop + 120 + 'px');
|
||||
}
|
||||
|
||||
function matrixContextualMenu(cell, x, y, tagName, tagId, func_name) {
|
||||
|
|
|
@ -845,6 +845,22 @@ function multiSelectToggleFeeds(on, cache) {
|
|||
});
|
||||
}
|
||||
|
||||
function multiSelectDeleteEventBlacklist(on, cache) {
|
||||
var selected = [];
|
||||
$(".select").each(function() {
|
||||
if ($(this).is(":checked")) {
|
||||
var temp = $(this).data("id");
|
||||
if (temp != null) {
|
||||
selected.push(temp);
|
||||
}
|
||||
}
|
||||
});
|
||||
$.get("/eventBlacklists/massDelete?ids=" + JSON.stringify(selected), function(data) {
|
||||
$("#confirmation_box").html(data);
|
||||
openPopup("#confirmation_box");
|
||||
});
|
||||
}
|
||||
|
||||
function multiSelectAction(event, context) {
|
||||
var settings = {
|
||||
deleteAttributes: {
|
||||
|
@ -913,6 +929,11 @@ function addSelectedTaxonomies(taxonomy) {
|
|||
});
|
||||
}
|
||||
|
||||
function proposeObjectsFromSelectedAttributes(clicked, event_id) {
|
||||
var selectedAttributeIds = getSelected();
|
||||
popoverPopup(clicked, event_id + '/' + selectedAttributeIds, 'objects', 'proposeObjectsFromAttributes');
|
||||
}
|
||||
|
||||
function hideSelectedTags(taxonomy) {
|
||||
$.get("/taxonomies/taxonomyMassHide/"+taxonomy, function(data) {
|
||||
$("#confirmation_box").html(data);
|
||||
|
@ -1456,20 +1477,23 @@ function templateElementFileCategoryChange(category) {
|
|||
}
|
||||
}
|
||||
|
||||
function openPopup(id) {
|
||||
var window_height = $(window).height();
|
||||
var popup_height = $(id).height();
|
||||
if (window_height < popup_height) {
|
||||
$(id).css("top", 50);
|
||||
$(id).css("height", window_height);
|
||||
$(id).addClass('vertical-scroll');
|
||||
} else {
|
||||
if (window_height > (300 + popup_height)) {
|
||||
var top_offset = ((window_height - popup_height) / 2) - 150;
|
||||
function openPopup(id, adjust_layout) {
|
||||
adjust_layout = adjust_layout === undefined ? true : adjust_layout;
|
||||
if (adjust_layout) {
|
||||
var window_height = $(window).height();
|
||||
var popup_height = $(id).height();
|
||||
if (window_height < popup_height) {
|
||||
$(id).css("top", 50);
|
||||
$(id).css("height", window_height);
|
||||
$(id).addClass('vertical-scroll');
|
||||
} else {
|
||||
var top_offset = (window_height - popup_height) / 2;
|
||||
if (window_height > (300 + popup_height)) {
|
||||
var top_offset = ((window_height - popup_height) / 2) - 150;
|
||||
} else {
|
||||
var top_offset = (window_height - popup_height) / 2;
|
||||
}
|
||||
$(id).css("top", top_offset + 'px');
|
||||
}
|
||||
$(id).css("top", top_offset + 'px');
|
||||
}
|
||||
$("#gray_out").fadeIn();
|
||||
$(id).fadeIn();
|
||||
|
@ -1555,7 +1579,7 @@ function openPopover(clicked, data, hover, placement) {
|
|||
|
||||
function getMatrixPopup(scope, scope_id, galaxy_id) {
|
||||
cancelPopoverForm();
|
||||
getPopup(scope_id + '/' + galaxy_id + '/' + scope, 'events', 'viewGalaxyMatrix', '', '#popover_form_large');
|
||||
getPopup(scope_id + '/' + galaxy_id + '/' + scope, 'events', 'viewGalaxyMatrix', '', '#popover_matrix');
|
||||
}
|
||||
|
||||
function getPopup(id, context, target, admin, popupType) {
|
||||
|
@ -1578,7 +1602,7 @@ function getPopup(id, context, target, admin, popupType) {
|
|||
success:function (data, textStatus) {
|
||||
$(".loading").hide();
|
||||
$(popupType).html(data);
|
||||
openPopup(popupType);
|
||||
openPopup(popupType, false);
|
||||
},
|
||||
error:function() {
|
||||
$(".loading").hide();
|
||||
|
@ -3673,7 +3697,7 @@ function quickSubmitGalaxyForm(cluster_ids, additionalData) {
|
|||
var scope = additionalData['target_type'];
|
||||
fetchFormDataAjax("/galaxies/attachMultipleClusters/" + target_id + "/" + scope, function(formData) {
|
||||
$('body').append($('<div id="temp"/>').html(formData));
|
||||
$('#temp #GalaxyTargetIds').val(JSON.stringify(selected_tag_ids));
|
||||
$('#temp #GalaxyTargetIds').val(JSON.stringify(cluster_ids));
|
||||
if (target_id == 'selected') {
|
||||
$('#AttributeAttributeIds, #GalaxyAttributeIds').val(getSelected());
|
||||
}
|
||||
|
@ -3733,6 +3757,7 @@ $(document).keyup(function(e){
|
|||
$("#gray_out").fadeOut();
|
||||
$("#popover_form").fadeOut();
|
||||
$("#popover_form_large").fadeOut();
|
||||
$("#popover_matrix").fadeOut();
|
||||
$("#screenshot_box").fadeOut();
|
||||
$("#popover_box").fadeOut();
|
||||
$("#confirmation_box").fadeOut();
|
||||
|
|
|
@ -173,6 +173,9 @@ installCore () {
|
|||
# install lief
|
||||
$SUDO_WWW ${PATH_TO_MISP}/venv/bin/pip install https://github.com/lief-project/packages/raw/lief-master-latest/pylief-0.9.0.dev.zip
|
||||
|
||||
# install zmq needed by mispzmq
|
||||
$SUDO_WWW ${PATH_TO_MISP}/venv/bin/pip install zmq
|
||||
|
||||
# install python-magic
|
||||
$SUDO_WWW ${PATH_TO_MISP}/venv/bin/pip install python-magic
|
||||
|
||||
|
|
|
@ -72,13 +72,13 @@ echo " - Change DELETE FROM to > 0 in misp-wipe.sql to also remove default ones"
|
|||
echo " - Defaults are created on first login"
|
||||
MySQLRUser=${MySQLRUser:-$MySQLUUser}
|
||||
MySQLRPass=${MySQLRPass:-$MySQLUPass}
|
||||
mysql -u $MySQLRUser -p$MySQLRPass $MISPDB < $SQL
|
||||
mysql --host $MISPDBHost -u $MySQLRUser -p$MySQLRPass $MISPDB < $SQL
|
||||
|
||||
echo "Inserting default values to MySQL tables"
|
||||
TMP=/tmp/misp-wipe-$$.sql
|
||||
cd $MISPPath
|
||||
sed -n '/Default values for initial installation/ { s///; :a; n; p; ba; }' INSTALL/MYSQL.sql | egrep -v '(admin_settings|db_version)' > $TMP
|
||||
mysql -u $MySQLRUser -p$MySQLRPass $MISPDB < $TMP
|
||||
mysql --host $MISPDBHost -u $MySQLRUser -p$MySQLRPass $MISPDB < $TMP
|
||||
rm -f $TMP
|
||||
|
||||
echo "Wiping files"
|
||||
|
|
Loading…
Reference in New Issue