mirror of https://github.com/MISP/MISP
chg: [internal] Optimise fetching trending tags widget
parent
8ae1a1e1d4
commit
a368e3196f
|
@ -1,6 +1,9 @@
|
|||
<?php
|
||||
App::uses('AppController', 'Controller');
|
||||
|
||||
/**
|
||||
* @property Dashboard $Dashboard
|
||||
*/
|
||||
class DashboardsController extends AppController
|
||||
{
|
||||
public $components = array('Session', 'RequestHandler');
|
||||
|
@ -147,47 +150,50 @@ class DashboardsController extends AppController
|
|||
|
||||
public function renderWidget($widget_id, $force = false)
|
||||
{
|
||||
if ($this->request->is('post')) {
|
||||
if (empty($this->request->data['data'])) {
|
||||
$this->request->data = array('data' => $this->request->data);
|
||||
|
||||
}
|
||||
if (empty($this->request->data['data'])) {
|
||||
throw new MethodNotAllowedException(__('You need to specify the widget to use along with the configuration.'));
|
||||
}
|
||||
$value = $this->request->data['data'];
|
||||
$dashboardWidget = $this->Dashboard->loadWidget($this->Auth->user(), $value['widget']);
|
||||
$this->layout = false;
|
||||
$this->set('title', $dashboardWidget->title);
|
||||
$redis = $this->Dashboard->setupRedis();
|
||||
$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 (!isset($dashboardWidget->cacheLifetime)) {
|
||||
$dashboardWidget->cacheLifetime = false;
|
||||
}
|
||||
if (empty($dashboardWidget->cacheLifetime) || empty($data)) {
|
||||
$data = $dashboardWidget->handler($this->Auth->user(), json_decode($value['config'], true));
|
||||
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'];
|
||||
}
|
||||
$valueConfig = json_decode($value['config'], true);
|
||||
$config = array(
|
||||
'render' => $dashboardWidget->render,
|
||||
'autoRefreshDelay' => empty($dashboardWidget->autoRefreshDelay) ? false : $dashboardWidget->autoRefreshDelay,
|
||||
'widget_config' => empty($valueConfig['widget_config']) ? array() : $valueConfig['widget_config']
|
||||
);
|
||||
$this->set('widget_id', $widget_id);
|
||||
$this->set('data', $data);
|
||||
$this->set('config', $config);
|
||||
$this->render('widget_loader');
|
||||
} else {
|
||||
if (!$this->request->is('post')) {
|
||||
throw new MethodNotAllowedException(__('This endpoint can only be reached via POST requests.'));
|
||||
}
|
||||
|
||||
@session_write_close(); // allow concurrent AJAX requests (session hold lock by default)
|
||||
|
||||
if (empty($this->request->data['data'])) {
|
||||
$this->request->data = array('data' => $this->request->data);
|
||||
}
|
||||
if (empty($this->request->data['data'])) {
|
||||
throw new MethodNotAllowedException(__('You need to specify the widget to use along with the configuration.'));
|
||||
}
|
||||
$value = $this->request->data['data'];
|
||||
$valueConfig = json_decode($value['config'], true);
|
||||
$dashboardWidget = $this->Dashboard->loadWidget($this->Auth->user(), $value['widget']);
|
||||
|
||||
$redis = $this->Dashboard->setupRedis();
|
||||
$org_scope = $this->_isSiteAdmin() ? 0 : $this->Auth->user('org_id');
|
||||
$lookup_hash = hash('sha256', $value['widget'] . $value['config']);
|
||||
$cacheKey = 'misp:dashboard:' . $org_scope . ':' . $lookup_hash;
|
||||
$data = $redis->get($cacheKey);
|
||||
if (!isset($dashboardWidget->cacheLifetime)) {
|
||||
$dashboardWidget->cacheLifetime = false;
|
||||
}
|
||||
if (empty($dashboardWidget->cacheLifetime) || empty($data)) {
|
||||
$data = $dashboardWidget->handler($this->Auth->user(), $valueConfig);
|
||||
if (!empty($dashboardWidget->cacheLifetime)) {
|
||||
$redis->setex($cacheKey, $dashboardWidget->cacheLifetime, json_encode(array('data' => $data)));
|
||||
}
|
||||
} else {
|
||||
$data = json_decode($data, true)['data'];
|
||||
}
|
||||
$config = array(
|
||||
'render' => $dashboardWidget->render,
|
||||
'autoRefreshDelay' => empty($dashboardWidget->autoRefreshDelay) ? false : $dashboardWidget->autoRefreshDelay,
|
||||
'widget_config' => empty($valueConfig['widget_config']) ? array() : $valueConfig['widget_config']
|
||||
);
|
||||
|
||||
$this->layout = false;
|
||||
$this->set('title', $dashboardWidget->title);
|
||||
$this->set('widget_id', $widget_id);
|
||||
$this->set('data', $data);
|
||||
$this->set('config', $config);
|
||||
$this->render('widget_loader');
|
||||
}
|
||||
|
||||
public function import()
|
||||
|
|
|
@ -20,36 +20,41 @@ class TrendingTagsWidget
|
|||
"include": ["misp-galaxy:", "my-internal-taxonomy"]
|
||||
}';
|
||||
public $description = 'Widget showing the trending tags over the past x seconds, along with the possibility to include/exclude tags.';
|
||||
public $cacheLifetime = 600;
|
||||
|
||||
public function handler($user, $options = array())
|
||||
{
|
||||
$this->Event = ClassRegistry::init('Event');
|
||||
$params = array(
|
||||
'metadata' => 1,
|
||||
'timestamp' => time() - (empty($options['time_window']) ? 8640000 : $options['time_window'])
|
||||
);
|
||||
/** @var Event $eventModel */
|
||||
$eventModel = ClassRegistry::init('Event');
|
||||
$threshold = empty($options['threshold']) ? 10 : $options['threshold'];
|
||||
$eventIds = $this->Event->filterEventIds($user, $params);
|
||||
$params['eventid'] = $eventIds;
|
||||
$events = array();
|
||||
$params = [
|
||||
'timestamp' => time() - (empty($options['time_window']) ? 8640000 : $options['time_window']),
|
||||
];
|
||||
$eventIds = $eventModel->filterEventIds($user, $params);
|
||||
|
||||
$tags = [];
|
||||
$tagColours = [];
|
||||
if (!empty($eventIds)) {
|
||||
$events = $this->Event->fetchEvent($user, $params);
|
||||
}
|
||||
$tags = array();
|
||||
$tagColours = array();
|
||||
foreach ($events as $event) {
|
||||
foreach ($event['EventTag'] as $et) {
|
||||
if ($this->checkTag($options, $et['Tag']['name'])) {
|
||||
if (empty($tags[$et['Tag']['name']])) {
|
||||
$tags[$et['Tag']['name']] = 1;
|
||||
$tagColours[$et['Tag']['name']] = $et['Tag']['colour'];
|
||||
} else {
|
||||
$tags[$et['Tag']['name']] += 1;
|
||||
}
|
||||
$eventTags = $eventModel->EventTag->find('all', [
|
||||
'conditions' => ['EventTag.event_id' => $eventIds],
|
||||
'contain' => ['Tag' => ['fields' => ['name', 'colour']]],
|
||||
'recursive' => -1,
|
||||
'fields' => ['id'],
|
||||
]);
|
||||
|
||||
foreach ($eventTags as $eventTag) {
|
||||
$tagName = $eventTag['Tag']['name'];
|
||||
if (isset($tags[$tagName])) {
|
||||
$tags[$tagName]++;
|
||||
} else if ($this->checkTag($options, $tagName)) {
|
||||
$tags[$tagName] = 1;
|
||||
$tagColours[$tagName] = $eventTag['Tag']['colour'];
|
||||
}
|
||||
}
|
||||
|
||||
arsort($tags);
|
||||
}
|
||||
arsort($tags);
|
||||
|
||||
$data['data'] = array_slice($tags, 0, $threshold);
|
||||
$data['colours'] = $tagColours;
|
||||
return $data;
|
||||
|
|
|
@ -8,7 +8,7 @@
|
|||
?>
|
||||
</div>
|
||||
<script type="text/javascript">
|
||||
$(document).ready(function() {
|
||||
$(function() {
|
||||
if (<?= $config['autoRefreshDelay'] ? 'true' : 'false' ?>) {
|
||||
setTimeout( function(){
|
||||
updateDashboardWidget("#widget_<?= h($widget_id) ?>")},
|
||||
|
|
|
@ -5391,12 +5391,12 @@ function saveDashboardState() {
|
|||
}
|
||||
|
||||
function updateDashboardWidget(element) {
|
||||
element = $(element);
|
||||
var $element = $(element);
|
||||
if (element.length) {
|
||||
var container_id = $(element).attr('id').substring(7);
|
||||
var container = $(element).find('.widgetContent');
|
||||
var titleText = $(element).find('.widgetTitleText');
|
||||
var temp = JSON.parse($(element).attr('config'));
|
||||
var container_id = $element.attr('id').substring(7);
|
||||
var container = $element.find('.widgetContent');
|
||||
var titleText = $element.find('.widgetTitleText');
|
||||
var temp = JSON.parse($element.attr('config'));
|
||||
if (temp['alias'] !== undefined) {
|
||||
titleText.text(temp['alias']);
|
||||
}
|
||||
|
@ -5404,8 +5404,8 @@ function updateDashboardWidget(element) {
|
|||
type: 'POST',
|
||||
url: baseurl + '/dashboards/renderWidget/' + container_id,
|
||||
data: {
|
||||
config: $(element).attr('config'),
|
||||
widget: $(element).attr('widget')
|
||||
config: $element.attr('config'),
|
||||
widget: $element.attr('widget')
|
||||
},
|
||||
success:function (data, textStatus) {
|
||||
container.html(data);
|
||||
|
|
Loading…
Reference in New Issue