mirror of https://github.com/MISP/MISP
new: [analystdata] wip
parent
e73d1001a0
commit
e04c810ae3
|
@ -0,0 +1,130 @@
|
|||
<?php
|
||||
App::uses('AppController', 'Controller');
|
||||
|
||||
class AnalystDataController extends AppController
|
||||
{
|
||||
|
||||
public $components = ['Session', 'RequestHandler'];
|
||||
|
||||
public $paginate = [
|
||||
'limit' => 60,
|
||||
'order' => []
|
||||
];
|
||||
|
||||
public $uses = [
|
||||
'Opinion',
|
||||
'Note',
|
||||
'Relationship'
|
||||
];
|
||||
|
||||
private $__valid_types = [
|
||||
'Opinion',
|
||||
'Note',
|
||||
'Relationship'
|
||||
];
|
||||
|
||||
public $modelSelection = 'Note';
|
||||
|
||||
private function _setViewElements()
|
||||
{
|
||||
$dropdownData = [];
|
||||
$this->loadModel('Event');
|
||||
$dropdownData['distributionLevels'] = $this->Event->distributionLevels;
|
||||
$this->set('initialDistribution', Configure::read('MISP.default_event_distribution'));
|
||||
$dropdownData['sgs'] = $this->Event->SharingGroup->fetchAllAuthorised($this->Auth->user(), 'name', 1);
|
||||
$dropdownData['valid_targets'] = array_combine($this->AnalystData->valid_targets, $this->AnalystData->valid_targets);
|
||||
$this->set(compact('dropdownData'));
|
||||
$this->set('modelSelection', $this->modelSelection);
|
||||
}
|
||||
|
||||
public function add($type = 'Note', $object_uuid = null, $object_type = null)
|
||||
{
|
||||
$this->__typeSelector($type);
|
||||
if (!empty($object_uuid)) {
|
||||
$this->request->data[$this->modelSelection]['object_uuid'] = $object_uuid;
|
||||
}
|
||||
if (!empty($object_type)) {
|
||||
$this->request->data[$this->modelSelection]['object_type'] = $object_type;
|
||||
}
|
||||
|
||||
if (empty($this->request->data[$this->modelSelection]['object_type']) && !empty($this->request->data[$this->modelSelection]['object_uuid'])) {
|
||||
// Target uuid set, but no type provided, time to figure it out...
|
||||
$this->request->data[$this->modelSelection]['object_type'] = $this->AnalystData->deduceType($object_uuid);
|
||||
}
|
||||
$params = [];
|
||||
$this->CRUD->add($params);
|
||||
if ($this->restResponsePayload) {
|
||||
return $this->restResponsePayload;
|
||||
}
|
||||
$this->_setViewElements();
|
||||
$this->set('menuData', array('menuList' => 'analyst_data', 'menuItem' => 'add'));
|
||||
$this->render('add');
|
||||
}
|
||||
|
||||
public function edit($type = 'Note', $id)
|
||||
{
|
||||
$this->__typeSelector($type);
|
||||
$this->set('id', $id);
|
||||
$params = [];
|
||||
$this->CRUD->edit($id, $params);
|
||||
if ($this->IndexFilter->isRest()) {
|
||||
return $this->restResponsePayload;
|
||||
}
|
||||
$this->_setViewElements();
|
||||
$this->set('menuData', array('menuList' => 'analyst_data', 'menuItem' => 'edit'));
|
||||
$this->render('add');
|
||||
}
|
||||
|
||||
public function delete($type = 'Note', $id)
|
||||
{
|
||||
$this->__typeSelector($type);
|
||||
$this->CRUD->delete($id);
|
||||
if ($this->IndexFilter->isRest()) {
|
||||
return $this->restResponsePayload;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public function view($type = 'Note', $id)
|
||||
{
|
||||
$this->__typeSelector($type);
|
||||
$this->set('menuData', array('menuList' => 'analyst_data', 'menuItem' => 'edit'));
|
||||
$this->CRUD->view($id);
|
||||
if ($this->IndexFilter->isRest()) {
|
||||
return $this->restResponsePayload;
|
||||
}
|
||||
$this->set('id', $id);
|
||||
$this->loadModel('Event');
|
||||
$this->_setViewElements();
|
||||
$this->set('distributionLevels', $this->Event->distributionLevels);
|
||||
$this->render('view');
|
||||
}
|
||||
|
||||
public function index($type = 'Note')
|
||||
{
|
||||
$this->__typeSelector($type);
|
||||
$this->set('menuData', array('menuList' => 'analyst_data', 'menuItem' => 'index'));
|
||||
$params = [
|
||||
'filters' => ['uuid', 'target_object', 'uuid'],
|
||||
'quickFilters' => ['name']
|
||||
];
|
||||
$this->CRUD->index($params);
|
||||
if ($this->IndexFilter->isRest()) {
|
||||
return $this->restResponsePayload;
|
||||
}
|
||||
$this->_setViewElements();
|
||||
}
|
||||
|
||||
private function __typeSelector($type) {
|
||||
foreach ($this->__valid_types as $vt) {
|
||||
if ($type === $vt) {
|
||||
$this->modelSelection = $vt;
|
||||
$this->AnalystData = $this->{$vt};
|
||||
$this->modelClass = $vt;
|
||||
$this->{$vt}->current_user = $this->Auth->user();
|
||||
return $vt;
|
||||
}
|
||||
}
|
||||
throw new MethodNotAllowedException(__('Invalid type.'));
|
||||
}
|
||||
}
|
|
@ -0,0 +1,60 @@
|
|||
<?php
|
||||
App::uses('AppModel', 'Model');
|
||||
|
||||
class AnalystData extends AppModel
|
||||
{
|
||||
|
||||
public $recursive = -1;
|
||||
|
||||
public $actsAs = array(
|
||||
'Containable'
|
||||
);
|
||||
|
||||
public $valid_targets = [
|
||||
'Attribute',
|
||||
'Event',
|
||||
'GalaxyCluster',
|
||||
'Galaxy',
|
||||
'Object',
|
||||
'Note',
|
||||
'Opinion',
|
||||
'Relationship',
|
||||
'Organisation',
|
||||
'SharingGroup'
|
||||
];
|
||||
|
||||
public $current_user = null;
|
||||
|
||||
|
||||
public function beforeValidate($options = array())
|
||||
{
|
||||
parent::beforeValidate();
|
||||
if (empty($this->id) && empty($this->data[$this->current_type]['uuid'])) {
|
||||
$this->data[$this->current_type]['uuid'] = CakeText::uuid();
|
||||
}
|
||||
if (empty($this->id)) {
|
||||
if (empty($this->data[$this->current_type]['orgc_uuid']) || empty($this->current_user['Role']['perm_sync'])) {
|
||||
$this->data[$this->current_type]['orgc_uuid'] = $this->current_user['Organisation']['uuid'];
|
||||
}
|
||||
$this->data[$this->current_type]['org_uuid'] = $this->current_user['Organisation']['uuid'];
|
||||
$this->data[$this->current_type]['authors'] = $this->current_user['email'];
|
||||
}
|
||||
debug($this->data);
|
||||
return true;
|
||||
}
|
||||
|
||||
public function deduceType(string $uuid)
|
||||
{
|
||||
foreach ($this->valid_targets as $valid_target) {
|
||||
$this->{$valid_target} = ClassRegistry::init($valid_target);
|
||||
$result = $this->$valid_target->find('first', [
|
||||
'conditions' => [$valid_target.'.uuid' => $uuid],
|
||||
'recursive' => -1
|
||||
]);
|
||||
if (!empty($result)) {
|
||||
return $valid_target;
|
||||
}
|
||||
}
|
||||
throw new NotFoundException(__('Invalid UUID'));
|
||||
}
|
||||
}
|
|
@ -2017,7 +2017,7 @@ class AppModel extends Model
|
|||
`distribution` tinyint(4) NOT NULL,
|
||||
`sharing_group_id` int(10) unsigned,
|
||||
`note` mediumtext,
|
||||
`language` varchar(16) DEFAULT 'en'
|
||||
`language` varchar(16) DEFAULT 'en',
|
||||
PRIMARY KEY (`id`),
|
||||
UNIQUE KEY `uuid` (`uuid`),
|
||||
KEY `object_uuid` (`object_uuid`),
|
||||
|
@ -2041,7 +2041,7 @@ class AppModel extends Model
|
|||
`distribution` tinyint(4) NOT NULL,
|
||||
`sharing_group_id` int(10) unsigned,
|
||||
`opinion` int(10) unsigned,
|
||||
`comment` text
|
||||
`comment` text,
|
||||
PRIMARY KEY (`id`),
|
||||
UNIQUE KEY `uuid` (`uuid`),
|
||||
KEY `object_uuid` (`object_uuid`),
|
||||
|
@ -2050,7 +2050,7 @@ class AppModel extends Model
|
|||
KEY `orgc_uuid` (`orgc_uuid`),
|
||||
KEY `distribution` (`distribution`),
|
||||
KEY `sharing_group_id` (`sharing_group_id`),
|
||||
KEY `opinion`
|
||||
KEY `opinion` (`opinion`)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;";
|
||||
|
||||
$sqlArray[] = "CREATE TABLE `relationships` (
|
||||
|
|
|
@ -0,0 +1,17 @@
|
|||
<?php
|
||||
|
||||
/**
|
||||
* Common functions for the 3 analyst objects
|
||||
*/
|
||||
class AnalystDataBehavior extends ModelBehavior
|
||||
{
|
||||
public function fetchForUuid()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
public function checkACL()
|
||||
{
|
||||
|
||||
}
|
||||
}
|
|
@ -0,0 +1,24 @@
|
|||
<?php
|
||||
App::uses('AppModel', 'Model');
|
||||
App::uses('AnalystData', 'Model');
|
||||
class Note extends AnalystData
|
||||
{
|
||||
|
||||
public $recursive = -1;
|
||||
|
||||
public $actsAs = array(
|
||||
'Containable',
|
||||
'AnalystData'
|
||||
);
|
||||
|
||||
public $current_type = 'Note';
|
||||
|
||||
public $validate = array(
|
||||
);
|
||||
|
||||
public function beforeValidate($options = array())
|
||||
{
|
||||
parent::beforeValidate();
|
||||
return true;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,23 @@
|
|||
<?php
|
||||
App::uses('AppModel', 'Model');
|
||||
class Opinion extends AppModel
|
||||
{
|
||||
|
||||
public $recursive = -1;
|
||||
|
||||
public $actsAs = array(
|
||||
'Containable',
|
||||
'AnalystData'
|
||||
);
|
||||
|
||||
public $current_type = 'Opinion';
|
||||
|
||||
public $validate = array(
|
||||
);
|
||||
|
||||
public function beforeValidate($options = array())
|
||||
{
|
||||
parent::beforeValidate();
|
||||
return true;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,17 @@
|
|||
<?php
|
||||
App::uses('AppModel', 'Model');
|
||||
class Relationship extends AnalystData
|
||||
{
|
||||
|
||||
public $recursive = -1;
|
||||
|
||||
public $actsAs = array(
|
||||
'Containable',
|
||||
'AnalystData'
|
||||
);
|
||||
|
||||
public $current_type = 'Relationship';
|
||||
|
||||
public $validate = array(
|
||||
);
|
||||
}
|
|
@ -0,0 +1,70 @@
|
|||
<?php
|
||||
$edit = $this->request->params['action'] === 'edit' ? true : false;
|
||||
$fields = [
|
||||
[
|
||||
'field' => 'object_type',
|
||||
'class' => 'span2',
|
||||
'disabled' => !empty($this->data[$modelSelection]['object_type']),
|
||||
'default' => empty($this->data[$modelSelection]['object_type']) ? null : $this->data[$modelSelection]['object_type'],
|
||||
'options' => $dropdownData['valid_targets'],
|
||||
'type' => 'dropdown',
|
||||
'stayInLine' => 1
|
||||
],
|
||||
[
|
||||
'field' => 'object_uuid',
|
||||
'class' => 'span4',
|
||||
'disabled' => !empty($this->data[$modelSelection]['object_uuid']),
|
||||
'default' => empty($this->data[$modelSelection]['object_uuid']) ? null : $this->data[$modelSelection]['object_uuid']
|
||||
],
|
||||
[
|
||||
'field' => 'distribution',
|
||||
'class' => 'input',
|
||||
'options' => $dropdownData['distributionLevels'],
|
||||
'default' => isset($attribute['Attribute']['distribution']) ? $attribute['Attribute']['distribution'] : $initialDistribution,
|
||||
'stayInLine' => 1,
|
||||
'type' => 'dropdown'
|
||||
],
|
||||
[
|
||||
'field' => 'sharing_group_id',
|
||||
'class' => 'input',
|
||||
'options' => $dropdownData['sgs'],
|
||||
'label' => __("Sharing Group"),
|
||||
'type' => 'dropdown'
|
||||
]
|
||||
];
|
||||
|
||||
if ($modelSelection === 'Note') {
|
||||
$fields = array_merge($fields,
|
||||
[
|
||||
[
|
||||
'field' => 'language',
|
||||
'class' => 'span3'
|
||||
],
|
||||
[
|
||||
'field' => 'note',
|
||||
'type' => 'textarea',
|
||||
'class' => 'input span6'
|
||||
]
|
||||
]
|
||||
);
|
||||
} else if ($modelSelection === 'Opinion') {
|
||||
|
||||
} else if ($modelSelection === 'Relationship') {
|
||||
|
||||
}
|
||||
echo $this->element('genericElements/Form/genericForm', [
|
||||
'data' => [
|
||||
'description' => false,
|
||||
'model' => $modelSelection,
|
||||
'title' => $edit ? __('Edit %s', $modelSelection) : __('Add new %s', $modelSelection),
|
||||
'fields' => $fields,
|
||||
'submit' => [
|
||||
'action' => $this->request->params['action'],
|
||||
'ajaxSubmit' => 'submitGenericFormInPlace();'
|
||||
]
|
||||
]
|
||||
]);
|
||||
|
||||
if (!$ajax) {
|
||||
echo $this->element('/genericElements/SideMenu/side_menu', $menuData);
|
||||
}
|
|
@ -0,0 +1,105 @@
|
|||
<?php
|
||||
$fields = [
|
||||
[
|
||||
'name' => __('Id'),
|
||||
'sort' => $modelSelection . '.id',
|
||||
'data_path' => $modelSelection . '.id'
|
||||
],
|
||||
[
|
||||
'name' => __('UUID'),
|
||||
'data_path' => $modelSelection . '.uuid'
|
||||
],
|
||||
[
|
||||
'name' => __('Target Object'),
|
||||
'sort' => $modelSelection . '.object_type',
|
||||
'data_path' => $modelSelection . '.object_uuid'
|
||||
],
|
||||
[
|
||||
'name' => __('Creator org'),
|
||||
'data_path' => $modelSelection . '.orgc_id'
|
||||
],
|
||||
[
|
||||
'name' => __('Created'),
|
||||
'sort' => $modelSelection . '.created',
|
||||
'data_path' => $modelSelection . '.created'
|
||||
],
|
||||
[
|
||||
'name' => __('Modified'),
|
||||
'sort' => $modelSelection . '.modified',
|
||||
'data_path' => $modelSelection . '.modified'
|
||||
],
|
||||
[
|
||||
'name' => __('Distribution'),
|
||||
'sort' => $modelSelection . '.distribution',
|
||||
'data_path' => $modelSelection . '.distribution'
|
||||
]
|
||||
];
|
||||
|
||||
if ($modelSelection === 'Note') {
|
||||
$fields = array_merge($fields,
|
||||
[
|
||||
[
|
||||
'name' => __('Language'),
|
||||
'sort' => $modelSelection . '.language',
|
||||
'data_path' => $modelSelection . '.language'
|
||||
],
|
||||
[
|
||||
'name' => __('Note'),
|
||||
'sort' => $modelSelection . '.note',
|
||||
'data_path' => $modelSelection . '.note'
|
||||
]
|
||||
]
|
||||
);
|
||||
} else if ($modelSelection === 'Opinion') {
|
||||
|
||||
} else if ($modelSelection === 'Relationship') {
|
||||
|
||||
}
|
||||
|
||||
echo $this->element('genericElements/IndexTable/scaffold', [
|
||||
'scaffold_data' => [
|
||||
'data' => [
|
||||
'data' => $data,
|
||||
'top_bar' => [
|
||||
'pull' => 'right',
|
||||
'children' => [
|
||||
[
|
||||
'type' => 'search',
|
||||
'button' => __('Filter'),
|
||||
'placeholder' => __('Enter value to search'),
|
||||
'data' => '',
|
||||
'searchKey' => 'quickFilter'
|
||||
]
|
||||
]
|
||||
],
|
||||
'fields' => $fields,
|
||||
'title' => empty($ajax) ? __('%s index', Inflector::pluralize($modelSelection)) : false,
|
||||
'actions' => [
|
||||
[
|
||||
'url' => $baseurl . '/analystData/view/' . $modelSelection . '/',
|
||||
'url_params_data_paths' => [$modelSelection . '.id'],
|
||||
'icon' => 'eye'
|
||||
],
|
||||
[
|
||||
'onclick' => sprintf(
|
||||
'openGenericModal(\'%s/analystData/edit/' . $modelSelection . '/[onclick_params_data_path]\');',
|
||||
$baseurl
|
||||
),
|
||||
'onclick_params_data_path' => $modelSelection . '.id',
|
||||
'title' => __('Edit %s', $modelSelection),
|
||||
'icon' => 'edit'
|
||||
],
|
||||
[
|
||||
'onclick' => sprintf(
|
||||
'openGenericModal(\'%s/analystData/edit/' . $modelSelection . '/[onclick_params_data_path]\');',
|
||||
$baseurl
|
||||
),
|
||||
'onclick_params_data_path' => $modelSelection . '.id',
|
||||
'icon' => 'trash'
|
||||
]
|
||||
]
|
||||
]
|
||||
]
|
||||
]);
|
||||
|
||||
?>
|
|
@ -0,0 +1,72 @@
|
|||
<?php
|
||||
echo $this->element(
|
||||
'genericElements/SingleViews/single_view',
|
||||
[
|
||||
'title' => __('Note view'),
|
||||
'data' => $data,
|
||||
'fields' => [
|
||||
[
|
||||
'key' => __('ID'),
|
||||
'path' => $modelSelection . '.id'
|
||||
],
|
||||
[
|
||||
'key' => __('UUID'),
|
||||
'path' => $modelSelection . '.uuid'
|
||||
],
|
||||
[
|
||||
'key' => __('Target Object'),
|
||||
'type' => 'custom',
|
||||
'function' => function (array $row) use ($baseurl) {
|
||||
$path = Inflector::pluralize(strtolower($row['Note']['object_type']));
|
||||
return sprintf(
|
||||
'<span class="bold">%s</span>: <a href="%s/%s/view/%s">%s</a>',
|
||||
h($row['Note']['object_type']),
|
||||
h($baseurl),
|
||||
h($path),
|
||||
h($row['Note']['object_uuid']),
|
||||
h($row['Note']['object_uuid'])
|
||||
);
|
||||
|
||||
}
|
||||
],
|
||||
[
|
||||
'key' => __('Creator org'),
|
||||
'path' => $modelSelection . '.orgc_uuid',
|
||||
'pathName' => $modelSelection . '.orgc_uuid',
|
||||
'type' => 'model',
|
||||
'model' => 'organisations'
|
||||
],
|
||||
[
|
||||
'key' => __('Owner org'),
|
||||
'path' => $modelSelection . '.org_uuid',
|
||||
'pathName' => $modelSelection . '.org_uuid',
|
||||
'type' => 'model',
|
||||
'model' => 'organisations'
|
||||
],
|
||||
[
|
||||
'key' => __('Created'),
|
||||
'path' => $modelSelection . '.created'
|
||||
],
|
||||
[
|
||||
'key' => __('Modified'),
|
||||
'path' => $modelSelection . '.modified'
|
||||
],
|
||||
[
|
||||
'key' => __('Distribution'),
|
||||
'path' => $modelSelection . '.distribution',
|
||||
'event_id_path' => $modelSelection . '.id',
|
||||
'disable_distribution_graph' => true,
|
||||
'sg_path' => $modelSelection . '.sharing_group_id',
|
||||
'type' => 'distribution'
|
||||
],
|
||||
[
|
||||
'key' => __('Language'),
|
||||
'path' => $modelSelection . '.language'
|
||||
],
|
||||
[
|
||||
'key' => __('Note'),
|
||||
'path' => $modelSelection . '.note'
|
||||
]
|
||||
]
|
||||
]
|
||||
);
|
|
@ -24,25 +24,27 @@ if ($distribution == 4) {
|
|||
}
|
||||
|
||||
$eventDistributionGraph = '';
|
||||
if (!($distribution == 4 && empty($sg))) {
|
||||
$eventDistributionGraph = sprintf(
|
||||
'%s %s %s',
|
||||
sprintf(
|
||||
'<span id="distribution_graph_bar" style="margin-left: 5px;" data-object-id="%s" data-object-context="event"></span>',
|
||||
h($event_id_path)
|
||||
),
|
||||
sprintf(
|
||||
'<it class="%s" data-object-id="%s" data-object-context="event" data-shown="false"></it><div style="display: none">%s</div>',
|
||||
'useCursorPointer fa fa-info-circle distribution_graph',
|
||||
h($event_id_path),
|
||||
$this->element('view_event_distribution_graph')
|
||||
),
|
||||
sprintf(
|
||||
'<it type="button" id="showAdvancedSharingButton" title="%s" class="%s" aria-hidden="true" style="margin-left: 5px;"></it>',
|
||||
__('Toggle advanced sharing network viewer'),
|
||||
'fa fa-share-alt useCursorPointer'
|
||||
)
|
||||
);
|
||||
if (empty($field['disable_distribution_graph'])) {
|
||||
if (!($distribution == 4 && empty($sg))) {
|
||||
$eventDistributionGraph = sprintf(
|
||||
'%s %s %s',
|
||||
sprintf(
|
||||
'<span id="distribution_graph_bar" style="margin-left: 5px;" data-object-id="%s" data-object-context="event"></span>',
|
||||
h($event_id_path)
|
||||
),
|
||||
sprintf(
|
||||
'<it class="%s" data-object-id="%s" data-object-context="event" data-shown="false"></it><div style="display: none">%s</div>',
|
||||
'useCursorPointer fa fa-info-circle distribution_graph',
|
||||
h($event_id_path),
|
||||
$this->element('view_event_distribution_graph')
|
||||
),
|
||||
sprintf(
|
||||
'<it type="button" id="showAdvancedSharingButton" title="%s" class="%s" aria-hidden="true" style="margin-left: 5px;"></it>',
|
||||
__('Toggle advanced sharing network viewer'),
|
||||
'fa fa-share-alt useCursorPointer'
|
||||
)
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
echo sprintf(
|
||||
|
|
Loading…
Reference in New Issue