mirror of https://github.com/MISP/MISP
Merge branch '2.4' of github.com:MISP/MISP into 2.4
commit
5e15ab1ef1
|
@ -401,6 +401,7 @@ class ACLComponent extends Component
|
|||
'releaseUpdateLock' => array(),
|
||||
'resetRemoteAuthKey' => array(),
|
||||
'rest' => array('perm_auth'),
|
||||
'restartDeadWorkers' => array(),
|
||||
'restartWorkers' => array(),
|
||||
'serverSettings' => array(),
|
||||
'serverSettingsEdit' => array(),
|
||||
|
|
|
@ -139,16 +139,25 @@ class DashboardsController extends AppController
|
|||
$org_scope = $this->_isSiteAdmin() ? 0 : $this->Auth->user('org_id');
|
||||
$lookup_hash = hash('sha256', $value['widget'] . $value['config']);
|
||||
$data = $redis->get('misp:dashboard:' . $org_scope . ':' . $lookup_hash);
|
||||
if (empty($data)) {
|
||||
$cacheLifetime = isset($dashboardWidget->cacheLifetime) ? $dashboardWidget->cacheLifetime : 300;
|
||||
if (!isset($dashboardWidget->cacheLifetime)) {
|
||||
$dashboardWidget->cacheLifetime = false;
|
||||
}
|
||||
if (empty($dashboardWidget->cacheLifetime) || empty($data)) {
|
||||
$data = $dashboardWidget->handler($this->Auth->user(), json_decode($value['config'], true));
|
||||
$redis->set('misp:dashboard:' . $org_scope . ':' . $lookup_hash, json_encode(array('data' => $data)));
|
||||
$redis->expire('misp:dashboard:' . $org_scope . ':' . $lookup_hash, $cacheLifetime);
|
||||
if (!empty($dashboardWidget->cacheLifetime)) {
|
||||
$redis->set('misp:dashboard:' . $org_scope . ':' . $lookup_hash, json_encode(array('data' => $data)));
|
||||
$redis->expire('misp:dashboard:' . $org_scope . ':' . $lookup_hash, $dashboardWidget->cacheLifetime);
|
||||
}
|
||||
} else {
|
||||
$data = json_decode($data, true)['data'];
|
||||
}
|
||||
$config = array(
|
||||
'render' => $dashboardWidget->render,
|
||||
'autoRefreshDelay' => empty($dashboardWidget->autoRefreshDelay) ? false : $dashboardWidget->autoRefreshDelay
|
||||
);
|
||||
$this->set('data', $data);
|
||||
$this->render('/Dashboards/Widgets/' . $dashboardWidget->render);
|
||||
$this->set('config', $config);
|
||||
$this->render('widget_loader');
|
||||
} else {
|
||||
throw new MethodNotAllowedException(__('This endpoint can only be reached via POST requests.'));
|
||||
}
|
||||
|
|
|
@ -1367,6 +1367,18 @@ class ServersController extends AppController
|
|||
$this->redirect(array('controller' => 'servers', 'action' => 'serverSettings', 'workers'));
|
||||
}
|
||||
|
||||
public function restartDeadWorkers()
|
||||
{
|
||||
if (!$this->_isSiteAdmin() || !$this->request->is('post')) {
|
||||
throw new MethodNotAllowedException();
|
||||
}
|
||||
$this->Server->restartDeadWorkers($this->Auth->user());
|
||||
if ($this->_isRest()) {
|
||||
return $this->RestResponse->saveSuccessResponse('Server', 'restartDeadWorkers', false, $this->response->type(), __('Restarting workers.'));
|
||||
}
|
||||
$this->redirect(array('controller' => 'servers', 'action' => 'serverSettings', 'workers'));
|
||||
}
|
||||
|
||||
private function __manageFiles()
|
||||
{
|
||||
if (!$this->_isSiteAdmin()) {
|
||||
|
|
|
@ -8,7 +8,8 @@ class MispAdminResourceWidget
|
|||
public $height = 2;
|
||||
public $params = array();
|
||||
public $description = 'Basic widget showing some server statistics in regards to MISP.';
|
||||
public $cacheLifetime = 5;
|
||||
public $cacheLifetime = false;
|
||||
public $autoRefreshDelay = 3;
|
||||
|
||||
|
||||
public function handler($user, $options = array())
|
||||
|
|
|
@ -8,7 +8,7 @@ class MispAdminSyncTestWidget
|
|||
public $height = 2;
|
||||
public $params = array();
|
||||
public $description = 'Basic widget showing some server statistics in regards to MISP.';
|
||||
public $cacheLifetime = 5;
|
||||
public $cacheLifetime = 1;
|
||||
|
||||
|
||||
public function handler($user, $options = array())
|
||||
|
@ -19,6 +19,10 @@ class MispAdminSyncTestWidget
|
|||
'conditions' => array('OR' => array('pull' => 1, 'push' => 1, 'caching_enabled' => 1)),
|
||||
'recursive' => -1
|
||||
));
|
||||
$data = array();
|
||||
if (empty($servers)) {
|
||||
return array();
|
||||
}
|
||||
$syncTestErrorCodes = $this->Server->syncTestErrorCodes;
|
||||
foreach ($servers as $server) {
|
||||
$result = $this->Server->runConnectionTest($server['Server']['id']);
|
||||
|
|
|
@ -8,7 +8,8 @@ class MispAdminWorkerWidget
|
|||
public $height = 2;
|
||||
public $params = array();
|
||||
public $description = 'Basic widget showing some server statistics in regards to MISP.';
|
||||
public $cacheLifetime = 5;
|
||||
public $cacheLifetime = false;
|
||||
public $autoRefreshDelay = 5;
|
||||
|
||||
|
||||
public function handler($user, $options = array())
|
||||
|
@ -23,11 +24,13 @@ class MispAdminWorkerWidget
|
|||
}
|
||||
$total = 0;
|
||||
$alive = 0;
|
||||
foreach ($queue['workers'] as $worker) {
|
||||
if ($worker['alive']) {
|
||||
$alive += 1;
|
||||
if (!empty($queue['workers'])) {
|
||||
foreach ($queue['workers'] as $worker) {
|
||||
if ($worker['alive']) {
|
||||
$alive += 1;
|
||||
}
|
||||
$total += 1;
|
||||
}
|
||||
$total += 1;
|
||||
}
|
||||
$colour = 'green';
|
||||
if ($alive == 0) {
|
||||
|
|
|
@ -6,12 +6,26 @@ class Dashboard extends AppModel
|
|||
|
||||
public function loadWidget($user, $name)
|
||||
{
|
||||
$name = str_replace('/', '', $name);
|
||||
if (file_exists(APP . 'Lib/Dashboard/' . $name . '.php')) {
|
||||
App::uses($name, 'Dashboard');
|
||||
} else if (file_exists(APP . 'Lib/Dashboard/Custom/' . $name . '.php')) {
|
||||
App::uses($name, 'Dashboard/Custom');
|
||||
} else {
|
||||
throw new NotFoundException(__('Invalid widget or widget not found.'));
|
||||
$customdir = new Folder(APP . 'Lib/Dashboard/Custom');
|
||||
$subDirectories = $customdir->read();
|
||||
$found = false;
|
||||
foreach ($subDirectories[0] as $subDir) {
|
||||
$currentDir = new Folder(APP . 'Lib/Dashboard/' . $subDir);
|
||||
if (file_exists(APP . 'Lib/Dashboard/Custom/' . $subDir . '/' . $name . '.php')) {
|
||||
App::uses($name, 'Dashboard/Custom/' . $subDir);
|
||||
$found = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!$found) {
|
||||
throw new NotFoundException(__('Invalid widget or widget not found.'));
|
||||
}
|
||||
}
|
||||
$widget = new $name();
|
||||
if (method_exists($widget, 'checkPermissions')) {
|
||||
|
@ -24,31 +38,34 @@ class Dashboard extends AppModel
|
|||
|
||||
public function loadAllWidgets($user)
|
||||
{
|
||||
$dir = new Folder(APP . 'Lib/Dashboard');
|
||||
$paths = array(
|
||||
'/',
|
||||
'/Custom'
|
||||
);
|
||||
$customdir = new Folder(APP . 'Lib/Dashboard/Custom');
|
||||
$widgetFiles = $dir->find('.*Widget\.php');
|
||||
$customWidgetFiles = $customdir->find('.*Widget\.php');
|
||||
$widgets = array();
|
||||
foreach ($widgetFiles as $widgetFile) {
|
||||
$className = substr($widgetFile, 0, strlen($widgetFile) -4);
|
||||
$temp = $this->__extractMeta($user, $className, false);
|
||||
if ($temp !== false) {
|
||||
$widgets[$className] = $temp;
|
||||
}
|
||||
$subDirectories = $customdir->read();
|
||||
foreach ($subDirectories[0] as $subDir) {
|
||||
$paths[] = '/Custom/' . $subDir;
|
||||
}
|
||||
foreach ($customWidgetFiles as $widgetFile) {
|
||||
$className = substr($widgetFile, 0, strlen($widgetFile) -4);
|
||||
$temp = $this->__extractMeta($user, $className, true);
|
||||
if ($temp !== false) {
|
||||
$widgets[$className] = $temp;
|
||||
$widgetMeta = array();
|
||||
$widgets = array();
|
||||
foreach ($paths as $path) {
|
||||
$currentDir = new Folder(APP . 'Lib/Dashboard' . $path);
|
||||
$widgetFiles = $currentDir->find('.*Widget\.php');
|
||||
foreach ($widgetFiles as $widgetFile) {
|
||||
$className = substr($widgetFile, 0, strlen($widgetFile) -4);
|
||||
$temp = $this->__extractMeta($user, $className, $path);
|
||||
if ($temp !== false) {
|
||||
$widgets[$className] = $temp;
|
||||
}
|
||||
}
|
||||
}
|
||||
return $widgets;
|
||||
}
|
||||
|
||||
private function __extractMeta($user, $className, $custom)
|
||||
private function __extractMeta($user, $className, $path)
|
||||
{
|
||||
App::uses($className, 'Dashboard' . ($custom ? '/Custom' : ''));
|
||||
App::uses($className, 'Dashboard' . ($path === '/' ? '' : $path));
|
||||
$widgetClass = new $className();
|
||||
if (method_exists($widgetClass, 'checkPermissions')) {
|
||||
if (!$widgetClass->checkPermissions($user)) {
|
||||
|
@ -63,7 +80,8 @@ class Dashboard extends AppModel
|
|||
'description' => empty($widgetClass->description) ? $widgetClass->title : $widgetClass->description,
|
||||
'height' => empty($widgetClass->height) ? 1 : $widgetClass->height,
|
||||
'width' => empty($widgetClass->width) ? 1 : $widgetClass->width,
|
||||
'placeholder' => empty($widgetClass->placeholder) ? '' : $widgetClass->placeholder
|
||||
'placeholder' => empty($widgetClass->placeholder) ? '' : $widgetClass->placeholder,
|
||||
'autoRefreshDelay' => empty($widgetClass->autoRefreshDelay) ? false : $widgetClass->autoRefreshDelay,
|
||||
);
|
||||
return $widget;
|
||||
}
|
||||
|
|
|
@ -5119,6 +5119,7 @@ class Server extends AppModel
|
|||
} else {
|
||||
$currentUser = trim(shell_exec('whoami'));
|
||||
}
|
||||
$killed = array();
|
||||
foreach ($workers as $pid => $worker) {
|
||||
if (!is_numeric($pid)) {
|
||||
throw new MethodNotAllowedException('Non numeric PID found!');
|
||||
|
@ -5127,8 +5128,14 @@ class Server extends AppModel
|
|||
if ($worker['user'] == $currentUser && !$pidTest) {
|
||||
$this->ResqueStatus->removeWorker($pid);
|
||||
$this->__logRemoveWorker($user, $pid, $worker['queue'], true);
|
||||
if (empty($killed[$worker['queue']])) {
|
||||
$killed[$worker['queue']] = 1;
|
||||
} else {
|
||||
$killed[$worker['queue']] += 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
return $killed;
|
||||
}
|
||||
|
||||
private function __logRemoveWorker($user, $pid, $queue, $dead = false)
|
||||
|
@ -5593,6 +5600,19 @@ class Server extends AppModel
|
|||
return true;
|
||||
}
|
||||
|
||||
public function restartDeadWorkers($user=false)
|
||||
{
|
||||
if (Configure::read('MISP.background_jobs')) {
|
||||
$killed = $this->workerRemoveDead($user);
|
||||
foreach ($killed as $queue => $count) {
|
||||
for ($i = 0; $i < $count; $i++) {
|
||||
$this->startWorker($queue);
|
||||
}
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
public function restartWorker($pid)
|
||||
{
|
||||
if (Configure::read('MISP.background_jobs')) {
|
||||
|
|
|
@ -1,14 +0,0 @@
|
|||
<?php
|
||||
foreach ($data as $element) {
|
||||
if (!empty($element['type']) && $element['type'] === 'gap') {
|
||||
echo '<br />';
|
||||
} else {
|
||||
echo sprintf(
|
||||
'<div><span class="bold">%s</span>: <span class="%s">%s</span>%s</div>',
|
||||
h($element['title']),
|
||||
empty($element['class']) ? 'blue' : h($element['class']),
|
||||
!isset($element['value']) ? '' : h($element['value']),
|
||||
empty($element['html']) ? '' : $element['html']
|
||||
);
|
||||
}
|
||||
}
|
|
@ -38,7 +38,7 @@ function resetDashboardGrid(grid) {
|
|||
}
|
||||
|
||||
$(document).ready(function () {
|
||||
var grid = GridStack.init();
|
||||
var grid = GridStack.init({verticalMargin: 2});
|
||||
resetDashboardGrid(grid);
|
||||
grid.on('change', function(event, items) {
|
||||
saveDashboardState();
|
||||
|
|
|
@ -0,0 +1,18 @@
|
|||
<?php
|
||||
$randomId = rand();
|
||||
?>
|
||||
<div id="widgetContentInner<?= $randomId ?>">
|
||||
<?php
|
||||
echo $this->element('/dashboard/Widgets/' . $config['render']);
|
||||
?>
|
||||
</div>
|
||||
<script type="text/javascript">
|
||||
$(document).ready(function() {
|
||||
if (<?= $config['autoRefreshDelay'] ? 'true' : 'false' ?>) {
|
||||
setTimeout( function(){
|
||||
updateDashboardWidget($("#widgetContentInner<?= $randomId ?>").closest('.grid-stack-item'))},
|
||||
<?= $config['autoRefreshDelay'] ? $config['autoRefreshDelay'] : 1 ?> * 1000
|
||||
);
|
||||
}
|
||||
});
|
||||
</script>
|
|
@ -0,0 +1,32 @@
|
|||
<table style="border-spacing:0px;">
|
||||
<?php
|
||||
if (!empty($data['logarithmic'])) {
|
||||
$max = max($data['logarithmic']);
|
||||
} else {
|
||||
$max = max($data['data']);
|
||||
}
|
||||
foreach ($data['data'] as $entry => $count) {
|
||||
$value = $count;
|
||||
if (!empty($data['logarithmic'])) {
|
||||
$value = $data['logarithmic'][$entry];
|
||||
}
|
||||
echo sprintf(
|
||||
'<tr><td style="%s">%s</td><td style="%s">%s</td></tr>',
|
||||
'text-align:right;width:33%;',
|
||||
h($entry),
|
||||
'width:100%',
|
||||
sprintf(
|
||||
'<div title="%s" style="%s">%s</div>',
|
||||
h($entry) . ': ' . h($count),
|
||||
sprintf(
|
||||
'background-color:%s; width:%s; color:white; text-align:center;',
|
||||
(empty($data['colours'][$entry]) ? '#0088cc' : h($data['colours'][$entry])),
|
||||
100 * h($value) / $max . '%;'
|
||||
),
|
||||
h($count)
|
||||
),
|
||||
' '
|
||||
);
|
||||
}
|
||||
?>
|
||||
</table>
|
|
@ -0,0 +1,28 @@
|
|||
<?php
|
||||
foreach ($data as $element) {
|
||||
if (!empty($element['type']) && $element['type'] === 'gap') {
|
||||
echo '<br />';
|
||||
} else {
|
||||
if (!empty($element['value'])) {
|
||||
if (is_array($element['value'])) {
|
||||
foreach ($element['value'] as &$value) {
|
||||
if (is_array($value)) {
|
||||
$value = 'Array';
|
||||
} else {
|
||||
$value = h($value);
|
||||
}
|
||||
}
|
||||
$element['value'] = '<br />' . implode('<br />', $element['value']);
|
||||
} else {
|
||||
$element['value'] = h($element['value']);
|
||||
}
|
||||
}
|
||||
echo sprintf(
|
||||
'<div><span class="bold">%s</span>: <span class="%s">%s</span>%s</div>',
|
||||
h($element['title']),
|
||||
empty($element['class']) ? 'blue' : h($element['class']),
|
||||
!isset($element['value']) ? '' : $element['value'],
|
||||
empty($element['html']) ? '' : $element['html']
|
||||
);
|
||||
}
|
||||
}
|
|
@ -126,8 +126,8 @@
|
|||
|
||||
<?php
|
||||
if ($worker_array['controls']) {
|
||||
echo $this->Form->create('Server', array('url' => '/servers/restartWorkers'));
|
||||
echo $this->Form->button(__('Restart all workers'), array('class' => 'btn btn-primary'));
|
||||
echo $this->Form->create('Server', array('url' => '/servers/restartDeadWorkers'));
|
||||
echo $this->Form->button(__('Restart dead workers'), array('class' => 'btn btn-primary'));
|
||||
echo $this->Form->end();
|
||||
}
|
||||
?>
|
||||
|
|
|
@ -1 +1 @@
|
|||
Subproject commit 346503f433c23c8dca482ca713d5071bad4dd315
|
||||
Subproject commit 3d57ee4fd2a78d3de6f210b16fd24ddf81c75d9a
|
Loading…
Reference in New Issue