Merge branch '2.4' of https://github.com/MISP/MISP into rework_modules

pull/4584/head
chrisr3d 2019-04-04 16:35:14 +02:00
commit e238e5e3ec
8 changed files with 142 additions and 43 deletions

View File

@ -1238,9 +1238,15 @@ class EventsController extends AppController
$this->set('emptyEvent', $emptyEvent);
$attributeCount = isset($event['Attribute']) ? count($event['Attribute']) : 0;
$objectCount = isset($event['Object']) ? count($event['Object']) : 0;
$oldest_timestamp = false;
if (!empty($event['Object'])) {
foreach ($event['Object'] as $k => $object) {
if (!empty($object['Attribute'])) {
foreach ($object['Attribute'] as $attribute) {
if ($oldest_timestamp == false || $oldest_timestamp < $attribute['timestamp']) {
$oldest_timestamp = $attribute['timestamp'];
}
}
$attributeCount += count($object['Attribute']);
}
}
@ -1320,6 +1326,9 @@ class EventsController extends AppController
$startDate = null;
$modificationMap = array();
foreach ($event['Attribute'] as $k => $attribute) {
if ($oldest_timestamp == false || $oldest_timestamp < $attribute['timestamp']) {
$oldest_timestamp = $attribute['timestamp'];
}
if ($startDate === null || $attribute['timestamp'] < $startDate) {
$startDate = $attribute['timestamp'];
}
@ -1458,6 +1467,7 @@ class EventsController extends AppController
$orgTable = $this->Event->Orgc->find('list', array(
'fields' => array('Orgc.id', 'Orgc.name')
));
$this->set('oldest_timestamp', $oldest_timestamp);
$this->set('required_taxonomies', $this->Event->getRequiredTaxonomies());
$this->set('orgTable', $orgTable);
$this->set('currentUri', $attributeUri);
@ -5105,12 +5115,17 @@ class EventsController extends AppController
}
if (isset($result['results']['Object']) && !empty($result['results']['Object'])) {
foreach ($result['results']['Object'] as $tmp_object) {
<<<<<<< HEAD
$tmp_object['distribution'] = (isset($tmp_object['distribution']) ? (int)$tmp_object['distribution'] : $defaultDistribution);
$tmp_object['sharing_group_id'] = (isset($tmp_object['sharing_group_id']) ? (int)$tmp_object['sharing_group_id'] : 0);
if (isset($tmp_object['Attribute']) && $tmp_object['Attribute']) {
foreach ($tmp_object['Attribute'] as &$tmp_attribute) {
$tmp_attribute = $this->__fillAttribute($tmp_attribute, $defaultDistribution);
}
=======
foreach ($tmp_object['Attribute'] as &$tmp_attribute) {
$tmp_attribute = $this->__fillAttribute($tmp_attribute, $defaultDistribution);
>>>>>>> df59c69134c5ce3731891927bebb9eec50e500d9
}
array_push($objects, $tmp_object);
}
@ -5216,8 +5231,17 @@ class EventsController extends AppController
public function handleModuleResults($eventId)
{
debug($eventId);
debug($this->request->event);
if (!$this->userRole['perm_add']) {
throw new MethodNotAllowedException(__('Event not found or you don\'t have permissions to create attributes'));
}
if ($this->request->is('post')) {
if (!$this->Event->checkIfAuthorised($this->Auth->user(), $id)) {
throw new MethodNotAllowedException(__('Invalid event.'));
}
$this->redirect(array('controller' => 'events', 'action' => 'view', $id));
} else {
throw new MethodNotAllowedException('This endpoint requires a POST request.');
}
}
public function importModule($module, $eventId)

View File

@ -388,7 +388,7 @@ class ServersController extends AppController
$this->set('host_org_id', Configure::read('MISP.host_org_id'));
}
}
public function edit($id = null)
{
$this->Server->id = $id;
@ -1542,6 +1542,21 @@ class ServersController extends AppController
}
}
public function updateSubmodule()
{
if (!$this->_isSiteAdmin()) {
throw new MethodNotAllowedException();
}
if ($this->request->is('post')) {
$request = $this->request->data;
$submodule = $request['Server']['submodule'];
$res = $this->Server->updateSubmodule($submodule);
return new CakeResponse(array('body'=> json_encode($res), 'type' => 'json'));
} else {
throw new MethodNotAllowedException();
}
}
public function getInstanceUUID()
{
return $this->RestResponse->viewData(array('uuid' => Configure::read('MISP.uuid')), $this->response->type());

View File

@ -4570,45 +4570,56 @@ class Server extends AppModel
public function getSubmodulesGitStatus()
{
exec('cd ' . APP . '../; git submodule |cut -f3 -d\ ', $submodulesNames);
exec('cd ' . APP . '../; git submodule status --cached | cut -b 2- | cut -d " " -f 1,2 ', $submodules_names);
$status = array();
foreach ($submodulesNames as $submoduleName) {
$temp = $this->getSubmoduleGitStatus($submoduleName);
if ( ! empty($temp) ) {
$status[$submoduleName] = $this->getSubmoduleGitStatus($submoduleName);
}
foreach ($submodules_names as $submodule_name_info) {
$submodule_name_info = explode(' ', $submodule_name_info);
$superproject_submodule_commit_id = $submodule_name_info[0];
$submodule_name = $submodule_name_info[1];
$temp = $this->getSubmoduleGitStatus($submodule_name, $superproject_submodule_commit_id);
if ( !empty($temp) ) {
$status[$submodule_name] = $temp;
}
}
return $status;
}
public function getSubmoduleGitStatus($submoduleName) {
$acceptedSubmodulesNames = array('PyMISP',
'app/files/misp-galaxy',
'app/files/taxonomies',
'app/files/misp-objects',
'app/files/noticelists',
'app/files/warninglists',
'cti-python-stix2'
);
private function _isAcceptedSubmodule($submodule) {
$accepted_submodules_names = array('PyMISP',
'app/files/misp-galaxy',
'app/files/taxonomies',
'app/files/misp-objects',
'app/files/noticelists',
'app/files/warninglists',
'cti-python-stix2'
);
return in_array($submodule, $accepted_submodules_names);
}
public function getSubmoduleGitStatus($submodule_name, $superproject_submodule_commit_id) {
$status = array();
if (in_array($submoduleName, $acceptedSubmodulesNames)) {
$path = APP . '../' . $submoduleName;
$submoduleName=(strpos($submoduleName, '/') >= 0 ? explode('/', $submoduleName) : $submoduleName);
$submoduleName=end($submoduleName);
if ($this->_isAcceptedSubmodule($submodule_name)) {
$path = APP . '../' . $submodule_name;
$submodule_name=(strpos($submodule_name, '/') >= 0 ? explode('/', $submodule_name) : $submodule_name);
$submodule_name=end($submodule_name);
$submoduleRemote=exec('cd ' . $path . '; git config --get remote.origin.url');
exec(sprintf('cd %s; git rev-parse HEAD', $path), $submodule_current_commit_id);
$submodule_current_commit_id = $submodule_current_commit_id[0];
$status = array(
'moduleName' => $submoduleName,
'current' => exec(sprintf('cd %s; git rev-parse HEAD', $path)),
'moduleName' => $submodule_name,
'current' => $submodule_current_commit_id,
'currentTimestamp' => exec(sprintf('cd %s; git log -1 --pretty=format:%%ct', $path)),
'remoteTimestamp' => exec('timeout 3 git log origin/2.4 -1 --pretty=format:%ct'),
'remote' => exec(sprintf('timeout 3 git ls-remote %s | head -1 | sed "s/HEAD//"', $submoduleRemote)),
'remoteTimestamp' => exec(sprintf('cd %s; git show -s --pretty=format:%%ct %s', $path, $superproject_submodule_commit_id)),
'remote' => $superproject_submodule_commit_id,
'upToDate' => ''
);
if (!empty($status['remote'])) {
if ($status['remote'] == $status['current']) {
$status['upToDate'] = 'same';
} else {
} else if ($status['currentTimestamp'] < $status['remoteTimestamp']) {
$status['upToDate'] = 'older';
} else {
$status['upToDate'] = 'younger';
}
} else {
$status['upToDate'] = 'error';
@ -4618,19 +4629,22 @@ class Server extends AppModel
return $status;
}
// Potentially obsolete. Ideally it is more uniform to get the path of the submodules.
private function __getSubmodulePath($submoduleName) {
$base = APP . 'files' . DS;
switch ($submoduleName) {
case 'misp-taxonomies':
return $base . 'taxonomies';
case 'misp-noticelist':
return $base . 'noticelists';
case 'misp-warninglists':
return $base . 'warninglists';
default:
return $base . $submoduleName;
public function updateSubmodule($submodule_name=false) {
$path = APP . '../';
if ($submodule_name == false) {
$command = sprintf('cd %s; git submodule update', $path);
exec($command, $output);
$output = implode("\n", $output);
$res = array('status' => true, 'output' => $output);
} else if ($this->_isAcceptedSubmodule($submodule_name)) {
$command = sprintf('cd %s; git submodule update -- %s', $path, $submodule_name);
exec($command, $output);
$output = implode("\n", $output);
$res = array('status' => true, 'output' => $output);
} else {
$res = array('status' => false);
}
return $res;
}
public function update($status)

View File

@ -61,7 +61,7 @@
<pre class="hidden green bold" id="gitResult"></pre>
<button title="<?php echo __('Pull the latest MISP version from github');?>" class="btn btn-inverse" style="padding-top:1px;padding-bottom:1px;" onClick = "updateMISP();"><?php echo __('Update MISP');?></button>
</div>
<h3><?php echo __('Submodules version');?><it id="refreshSubmoduleStatus" class="fa fa-refresh useCursorPointer" style="font-size: small; margin-left: 5px;"></it></h3>
<h3><?php echo __('Submodules version');?><it id="refreshSubmoduleStatus" class="fas fa-sync useCursorPointer" style="font-size: small; margin-left: 5px;"></it></h3>
<div id="divSubmoduleVersions" style="background-color:#f7f7f9;">
</div>

View File

@ -188,7 +188,7 @@
);
$table_data[] = array(
'key' => __('First recorded change'),
'value' => date('Y-m-d H:i:s', $event['Event']['timestamp'])
'value' => date('Y-m-d H:i:s', $oldest_timestamp)
);
$table_data[] = array(
'key' => __('Last change'),

View File

@ -4,6 +4,14 @@
<th><?php echo __('Submodule'); ?></th>
<th><?php echo __('Current Version'); ?></th>
<th><?php echo __('Status'); ?></th>
<th><?php echo __('Action'); ?>
<?php
echo $this->Form->create('Server', array('url' => array('action' => 'updateSubmodule'), 'div' => false, 'style' => 'margin: 0px; display: inline-block;'));
echo $this->Form->hidden('submodule', array('value' => false));
echo $this->Form->end();
echo '<it class="fas fa-sync useCursorPointer" title="' . __('Update all submodules') . '" aria-label="Update all" onclick="submitSubmoduleUpdate(this);"></it>';
?>
</th>
</tr>
</thead>
<tbody>
@ -21,7 +29,11 @@
$class = 'warning';
}
$versionText = __('Outdated version');
$versionText .= sprintf(' (%s days, %s hours)', $status['timeDiff']->format('%d'), $status['timeDiff']->format('%h'));
$versionText .= sprintf(_(' (%s days, %s hours older than super project)'), $status['timeDiff']->format('%a'), $status['timeDiff']->format('%h'));
break;
case 'younger':
$class = 'warning';
$versionText = __('Newer version. Make sure to update MISP');
break;
case 'error':
$class = 'error bold';
@ -37,6 +49,16 @@
<td><?php echo h($submodule) ?></td>
<td><?php echo h($status['current']) ?></td>
<td><?php echo h($versionText) ?></td>
<td>
<?php
if ($status['upToDate'] != 'same') {
echo $this->Form->create('Server', array('url' => array('action' => 'updateSubmodule'), 'div' => false, 'style' => 'margin: 0px; display: inline-block;'));
echo $this->Form->hidden('submodule', array('value' => h($submodule)));
echo $this->Form->end();
echo '<it class="fas fa-sync useCursorPointer" title="' . __('Update submodule') . '" aria-label="Update" onclick="submitSubmoduleUpdate(this);"></it>';
}
?>
</td>
</tr>
<?php endforeach; ?>
</tbody>

View File

@ -420,7 +420,7 @@ function drawBarChart(data) {
}
$(document).ready(function() {
var rightBtn = '<div style="float:right;"><span type="button" id="reloadDistributionGraph" title="Reload Distribution Graph" class="fa fa-refresh useCursorPointer" aria-hidden="true" style="margin-left: 5px;" onclick="fetchDistributionData(function(data) { construct_piechart(data); });"></span></div>';
var rightBtn = '<div style="float:right;"><span type="button" id="reloadDistributionGraph" title="Reload Distribution Graph" class="fas fa-sync useCursorPointer" aria-hidden="true" style="margin-left: 5px;" onclick="fetchDistributionData(function(data) { construct_piechart(data); });"></span></div>';
var pop = $('.distribution_graph').popover({
title: "<b>Distribution graph</b> [atomic event]" + rightBtn,
html: true,

View File

@ -3817,6 +3817,30 @@ function submitMISPUpdate() {
});
}
function submitSubmoduleUpdate(clicked) {
var $clicked = $(clicked);
var $form = $clicked.parent().find('form');
var formData = $form.serialize();
$.ajax({
beforeSend: function (XMLHttpRequest) {
$clicked.addClass('fa-spin');
},
data: formData,
success:function (data, textStatus) {
if (data.output !== '') {
showMessage('success', data.output);
}
updateSubModulesStatus();
},
complete:function() {
$clicked.removeClass('fa-spin');
},
type:"post",
cache: false,
url:$form.attr('action'),
});
}
$(".cortex-json").click(function() {
var cortex_data = $(this).data('cortex-json');
cortex_data = htmlEncode(JSON.stringify(cortex_data, null, 2));