mirror of https://github.com/MISP/MISP
Merge branch '2.4' of github.com:MISP/MISP into 2.4
commit
084b79e399
|
@ -178,6 +178,7 @@ class ACLComponent extends Component
|
|||
'index' => array('*'),
|
||||
'previewEvent' => array('*'),
|
||||
'previewIndex' => array('*'),
|
||||
'searchCaches' => array('*'),
|
||||
'toggleSelected' => array('perm_site_admin'),
|
||||
'view' => array('*'),
|
||||
),
|
||||
|
|
|
@ -960,4 +960,50 @@ class FeedsController extends AppController
|
|||
$this->render('ajax/feedToggleConfirmation');
|
||||
}
|
||||
}
|
||||
|
||||
public function searchCaches()
|
||||
{
|
||||
if (!$this->_isSiteAdmin() && !$this->Auth->user('org_id') == Configure::read('MISP.host_org_id')) {
|
||||
throw NotAllowedException('You don\'t have access to this feature.');
|
||||
}
|
||||
if (isset($this->passedArgs['pages'])) {
|
||||
$currentPage = $this->passedArgs['pages'];
|
||||
} else {
|
||||
$currentPage = 1;
|
||||
}
|
||||
$urlparams = '';
|
||||
App::uses('CustomPaginationTool', 'Tools');
|
||||
$customPagination = new CustomPaginationTool();
|
||||
$passedArgs = array();
|
||||
$hits = array();
|
||||
$value = false;
|
||||
if ($this->request->is('post')) {
|
||||
if (isset($this->request->data['Feed'])) {
|
||||
$this->request->data = $this->request->data['Feed'];
|
||||
}
|
||||
if (isset($this->request->data['value'])) {
|
||||
$this->request->data = $this->request->data['value'];
|
||||
}
|
||||
$value = $this->request->data;
|
||||
}
|
||||
if (!empty($this->params['named']['value'])) {
|
||||
$value = $this->params['named']['value'];
|
||||
}
|
||||
$hits = $this->Feed->searchCaches($value);
|
||||
if ($this->_isRest()) {
|
||||
return $this->RestResponse->viewData($hits, $this->response->type());
|
||||
} else {
|
||||
$this->set('hits', $hits);
|
||||
}
|
||||
$params = $customPagination->createPaginationRules($hits, $this->passedArgs, $this->alias);
|
||||
$this->params->params['paging'] = array('Feed' => $params);
|
||||
$hits = $customPagination->sortArray($hits, $params, true);
|
||||
if (is_array($hits)) {
|
||||
$customPagination->truncateByPagination($hits, $params);
|
||||
}
|
||||
$pageCount = count($hits);
|
||||
$this->set('urlparams', $urlparams);
|
||||
$this->set('passedArgs', json_encode($passedArgs));
|
||||
$this->set('passedArgsArray', $passedArgs);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1502,4 +1502,99 @@ class Feed extends AppModel
|
|||
}
|
||||
return $result;
|
||||
}
|
||||
|
||||
public function searchCaches($value)
|
||||
{
|
||||
$value = strtolower(trim($value));
|
||||
$hits = array();
|
||||
$this->Server = ClassRegistry::init('Server');
|
||||
$result['Server'] = $this->Server->find('all', array(
|
||||
'conditions' => array(
|
||||
'caching_enabled' => 1
|
||||
),
|
||||
'recursive' => -1,
|
||||
'fields' => array('Server.id', 'Server.name', 'Server.url')
|
||||
));
|
||||
$redis = $this->setupRedis();
|
||||
if (empty($value) || $redis->sismember('misp:feed_cache:combined', md5($value))) {
|
||||
$feeds = $this->find('all', array(
|
||||
'conditions' => array(
|
||||
'caching_enabled' => 1
|
||||
),
|
||||
'recursive' => -1,
|
||||
'fields' => array('Feed.id', 'Feed.name', 'Feed.url', 'Feed.source_format')
|
||||
));
|
||||
foreach ($feeds as $feed) {
|
||||
if (empty($value) || $redis->sismember('misp:feed_cache:' . $feed['Feed']['id'], md5($value))) {
|
||||
if ($feed['Feed']['source_format'] === 'misp') {
|
||||
$uuid = $redis->smembers('misp:feed_cache:event_uuid_lookup:' . md5($value));
|
||||
foreach ($uuid as $k => $url) {
|
||||
$uuid[$k] = explode('/', $url)[1];
|
||||
}
|
||||
$feed['Feed']['uuid'] = $uuid;
|
||||
if (!empty($feed['Feed']['uuid'])) {
|
||||
foreach ($feed['Feed']['uuid'] as $uuid) {
|
||||
$feed['Feed']['direct_urls'][] = array(
|
||||
'url' => sprintf(
|
||||
'%s/feeds/previewEvent/%s/%s',
|
||||
Configure::read('MISP.baseurl'),
|
||||
h($feed['Feed']['id']),
|
||||
h($uuid)
|
||||
),
|
||||
'name' => __('Event %s', $uuid)
|
||||
);
|
||||
}
|
||||
}
|
||||
$feed['Feed']['type'] = 'MISP Feed';
|
||||
} else {
|
||||
$feed['Feed']['type'] = 'Feed';
|
||||
if (!empty($value)) {
|
||||
$feed['Feed']['direct_urls'][] = array(
|
||||
'url' => sprintf(
|
||||
'%s/feeds/previewIndex/%s',
|
||||
Configure::read('MISP.baseurl'),
|
||||
h($feed['Feed']['id'])
|
||||
),
|
||||
'name' => __('Feed %s', $feed['Feed']['id'])
|
||||
);
|
||||
}
|
||||
}
|
||||
$hits[] = $feed;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (empty($value) || $redis->sismember('misp:server_cache:combined', md5($value))) {
|
||||
$this->Server = ClassRegistry::init('Server');
|
||||
$servers = $this->Server->find('all', array(
|
||||
'conditions' => array(
|
||||
'caching_enabled' => 1
|
||||
),
|
||||
'recursive' => -1,
|
||||
'fields' => array('Server.id', 'Server.name', 'Server.url')
|
||||
));
|
||||
foreach ($servers as $server) {
|
||||
if (empty($value) || $redis->sismember('misp:server_cache:' . $server['Server']['id'], md5($value))) {
|
||||
$uuid = $redis->smembers('misp:server_cache:event_uuid_lookup:' . md5($value));
|
||||
if (!empty($uuid)) {
|
||||
foreach ($uuid as $k => $url) {
|
||||
$uuid[$k] = explode('/', $url)[1];
|
||||
$server['Server']['direct_urls'][] = array(
|
||||
'url' => sprintf(
|
||||
'%s/servers/previewEvent/%s/%s',
|
||||
Configure::read('MISP.baseurl'),
|
||||
h($server['Server']['id']),
|
||||
h($uuid[$k])
|
||||
),
|
||||
'name' => __('Event %s', h($uuid[$k]))
|
||||
);
|
||||
}
|
||||
}
|
||||
$server['Server']['uuid'] = $uuid;
|
||||
$server['Server']['type'] = 'MISP Server';
|
||||
$hits[] = array('Feed' => $server['Server']);
|
||||
}
|
||||
}
|
||||
}
|
||||
return $hits;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,3 @@
|
|||
<?php
|
||||
echo h(Hash::extract($row, $field['data_path'])[0]);
|
||||
?>
|
|
@ -0,0 +1,13 @@
|
|||
<?php
|
||||
$url_data = Hash::extract($row, $field['data_path']);
|
||||
$links = array();
|
||||
foreach ($url_data as $url) {
|
||||
$links[] = sprintf(
|
||||
'<a href="%s" title="%s">%s</a>',
|
||||
h($url['url']),
|
||||
h($url['name']),
|
||||
h($url['name'])
|
||||
);
|
||||
}
|
||||
echo implode('<br />', $links);
|
||||
?>
|
|
@ -0,0 +1,20 @@
|
|||
<?php
|
||||
$headersHtml = '';
|
||||
foreach ($fields as $k => $header) {
|
||||
$header_data = '';
|
||||
if (!empty($header['sort'])) {
|
||||
if (!empty($header['name'])) {
|
||||
$header_data = $paginator->sort($header['sort'], $header['name']);
|
||||
} else {
|
||||
$header_data = $paginator->sort($header['sort']);
|
||||
}
|
||||
} else {
|
||||
$header_data = h($header['name']);
|
||||
}
|
||||
$headersHtml .= sprintf(
|
||||
'<th>%s</th>',
|
||||
$header_data
|
||||
);
|
||||
}
|
||||
echo $headersHtml;
|
||||
?>
|
|
@ -0,0 +1,46 @@
|
|||
<?php
|
||||
/*
|
||||
* echo $this->element('/genericElements/IndexTable/index_table', array(
|
||||
* 'top_bar' => (
|
||||
* // search/filter bar information compliant with ListTopBar
|
||||
* ),
|
||||
* 'data' => array(
|
||||
// the actual data to be used
|
||||
* ),
|
||||
* 'fields' => array(
|
||||
* // field list with information for the paginator, the elements used for the individual cells, etc
|
||||
* ),
|
||||
* 'title' => optional title,
|
||||
* 'description' => optional description
|
||||
* ));
|
||||
*
|
||||
*/
|
||||
if (!empty($data['title'])) {
|
||||
echo sprintf('<h2>%s</h2>', h($data['title']));
|
||||
}
|
||||
if (!empty($data['description'])) {
|
||||
echo sprintf('<p>%s</p>', h($data['description']));
|
||||
}
|
||||
echo $this->element('/genericElements/IndexTable/pagination', array('paginator' => $this->Paginator));
|
||||
if (!empty($data['top_bar'])) {
|
||||
echo $this->element('/genericElements/ListTopBar/scaffold', array('data' => $data['top_bar']));
|
||||
}
|
||||
$rows = '';
|
||||
foreach ($data['data'] as $k => $data_row) {
|
||||
$row_element = 'row';
|
||||
if (!empty($data['row_element'])) {
|
||||
$row_element = $data['row_element'];
|
||||
}
|
||||
$rows .= sprintf(
|
||||
'<tr>%s</tr>',
|
||||
$this->element('/genericElements/IndexTable/' . $row_element, array('k' => $k, 'row' => $data_row, 'fields' => $data['fields']))
|
||||
);
|
||||
}
|
||||
echo sprintf(
|
||||
'<table class="table table-striped table-hover table-condensed">%s%s</table>',
|
||||
$this->element('/genericElements/IndexTable/headers', array('fields' => $data['fields'], 'paginator' => $this->Paginator)),
|
||||
$rows
|
||||
);
|
||||
echo $this->element('/genericElements/IndexTable/pagination_counter', array('paginator' => $this->Paginator));
|
||||
echo $this->element('/genericElements/IndexTable/pagination', array('paginator' => $this->Paginator));
|
||||
?>
|
|
@ -0,0 +1,14 @@
|
|||
<?php
|
||||
$paginator->options(array(
|
||||
'update' => '.span12',
|
||||
'evalScripts' => true,
|
||||
'before' => '$(".progress").show()',
|
||||
'complete' => '$(".progress").hide()',
|
||||
));
|
||||
sprintf(
|
||||
'<div class="pagination"><ul>%s%s%s</ul></div>',
|
||||
$paginator->prev('« ' . __('previous'), array('tag' => 'li', 'escape' => false), null, array('tag' => 'li', 'class' => 'prev disabled', 'escape' => false, 'disabledTag' => 'span')),
|
||||
$paginator->numbers(array('modulus' => 20, 'separator' => '', 'tag' => 'li', 'currentClass' => 'active', 'currentTag' => 'span')),
|
||||
$paginator->next(__('next') . ' »', array('tag' => 'li', 'escape' => false), null, array('tag' => 'li', 'class' => 'next disabled', 'escape' => false, 'disabledTag' => 'span'))
|
||||
);
|
||||
?>
|
|
@ -0,0 +1,8 @@
|
|||
<?php
|
||||
echo sprintf(
|
||||
'<p>%s</p>',
|
||||
$paginator->counter(array(
|
||||
'format' => __('Page {:page} of {:pages}, showing {:current} records out of {:count} total, starting on record {:start}, ending on {:end}')
|
||||
))
|
||||
);
|
||||
?>
|
|
@ -0,0 +1,20 @@
|
|||
<?php
|
||||
$rowHtml = '';
|
||||
foreach ($fields as $k => $field) {
|
||||
if (empty($field['element'])) {
|
||||
$valueField = $this->element('/genericElements/IndexTable/Fields/generic_field', array('field' => $field, 'row' => $row, 'data_path' => empty($field['data_path']) ? '' : $field['data_path']));
|
||||
} else {
|
||||
$valueField = $this->element('/genericElements/IndexTable/Fields/' . $field['element'], array('field' => $field, 'row' => $row, 'data_path' => empty($field['data_path']) ? '' : $field['data_path']));
|
||||
}
|
||||
$rowHtml .= sprintf(
|
||||
'<td%s%s%s%s%s>%s</td>',
|
||||
(empty($field['id'])) ? '' : sprintf('id="%s"', $field['id']),
|
||||
(empty($field['class'])) ? '' : sprintf(' class="%s"', $field['class']),
|
||||
(empty($field['style'])) ? '' : sprintf(' style="%s"', $field['style']),
|
||||
(empty($field['title'])) ? '' : sprintf(' title="%s"', $field['title']),
|
||||
(empty($field['ondblclick'])) ? '' : sprintf(' ondblclick="%s"', $field['ondblclick']),
|
||||
$valueField
|
||||
);
|
||||
}
|
||||
echo ($rowHtml);
|
||||
?>
|
|
@ -1,4 +1,16 @@
|
|||
<?php
|
||||
/*
|
||||
* Run a quick filter against the current API endpoint
|
||||
* Result is passed via URL parameters, by default using the searchall key
|
||||
* Valid parameters:
|
||||
* - data: data-* fields
|
||||
* - searchKey: data-search-key, specifying the key to be used (defaults to searchall)
|
||||
* - fa-icon: an icon to use for the lookup $button
|
||||
* - buttong: Text to use for the lookup button
|
||||
* - cancel: Button for quickly removing the filters
|
||||
* - placeholder: optional placeholder for the text field
|
||||
* - id: element ID for the input field - defaults to quickFilterField
|
||||
*/
|
||||
if (!isset($data['requirement']) || $data['requirement']) {
|
||||
$button = empty($data['button']) && empty($data['fa-icon']) ? '' : sprintf(
|
||||
'<button class=" btn btn-small btn-inverse" %s id="quickFilterButton">%s%s</button>',
|
||||
|
@ -10,10 +22,11 @@
|
|||
$button .= $this->element('/genericElements/ListTopBar/element_simple', array('data' => $data['cancel']));
|
||||
}
|
||||
$input = sprintf(
|
||||
'<input type="text" class="span3 input-small" placeholder="%s" aria-label="%s" style="padding: 2px 6px;" id="%s">',
|
||||
'<input type="text" class="span3 input-small" placeholder="%s" aria-label="%s" style="padding: 2px 6px;" id="%s" data-searchkey="%s">',
|
||||
empty($data['placeholder']) ? '' : h($data['placeholder']),
|
||||
empty($data['placeholder']) ? '' : h($data['placeholder']),
|
||||
empty($data['id']) ? 'quickFilterField' : h($data['id'])
|
||||
empty($data['id']) ? 'quickFilterField' : h($data['id']),
|
||||
empty($data['searchKey']) ? 'searchall' : h($data['searchKey'])
|
||||
);
|
||||
echo sprintf(
|
||||
'<div class="btn-group pull-right"><div class="input-append" style="margin-bottom:0px;">%s%s</div></div>',
|
||||
|
|
|
@ -874,6 +874,10 @@
|
|||
'url' => '/feeds/index',
|
||||
'text' => __('List Feeds')
|
||||
));
|
||||
echo $this->element('/genericElements/SideMenu/side_menu_link', array(
|
||||
'url' => '/feeds/searchCaches',
|
||||
'text' => __('Search Feed Caches')
|
||||
));
|
||||
if ($isSiteAdmin) {
|
||||
echo $this->element('/genericElements/SideMenu/side_menu_link', array(
|
||||
'url' => '/feeds/add',
|
||||
|
|
|
@ -221,6 +221,11 @@
|
|||
'text' => __('List Feeds'),
|
||||
'url' => '/feeds/index',
|
||||
'requirement' => ($isSiteAdmin || $hostOrgUser)
|
||||
),
|
||||
array(
|
||||
'text' => __('Search Feed Caches'),
|
||||
'url' => '/feeds/searchCaches',
|
||||
'requirement' => ($isSiteAdmin || $hostOrgUser)
|
||||
)
|
||||
)
|
||||
),
|
||||
|
|
|
@ -36,12 +36,58 @@
|
|||
<?php
|
||||
foreach ($event['Object'] as $o => $object) {
|
||||
?>
|
||||
<table class="table table-condensed table-stripped">
|
||||
<table class="MISPObject" style="width:100%;">
|
||||
<tbody>
|
||||
<tr>
|
||||
<td class="bold"><?php echo __('Name');?></td>
|
||||
<td><?php echo h($object['name']); ?></td>
|
||||
<td class='ObjectName'><?php echo h($object['name']); ?></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="bold"><?php echo __('UUID');?></td>
|
||||
<td class='ObjectUUID'><?php echo h($object['uuid']); ?></td>
|
||||
</tr>
|
||||
<?php if (isset($object['ObjectReference']) && !empty($object['ObjectReference'])) { ?>
|
||||
<tr>
|
||||
<td class="bold"><?php echo __('References:'); ?></td>
|
||||
</tr>
|
||||
<table class="table table-condensed" style="margin-bottom:0px;">
|
||||
<thead>
|
||||
<th><?php echo __('Referenced name/type'); ?></th>
|
||||
<th><?php echo __('Referenced uuid'); ?></th>
|
||||
<th><?php echo __('Relationship'); ?></th>
|
||||
</thead>
|
||||
<tbody>
|
||||
<?php
|
||||
foreach ($object['ObjectReference'] as $reference) {
|
||||
echo '<tr class="ObjectReference">';
|
||||
$referenced_uuid = $reference['referenced_uuid'];
|
||||
foreach ($event['Object'] as $object_reference) {
|
||||
if ($referenced_uuid === $object_reference['uuid']) {
|
||||
$name = $object_reference['name'];
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!isset($name)) {
|
||||
foreach ($event['Attribute'] as $attribute_reference) {
|
||||
if ($referenced_uuid === $attribute_reference['uuid']) {
|
||||
$name = $attribute_reference['type'];
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!isset($name)) {
|
||||
$name = '';
|
||||
}
|
||||
}
|
||||
echo '<td class="ReferencedName">' . h($name) . '</td>';
|
||||
unset($name);
|
||||
echo '<td class="ReferencedUUID">' . h($referenced_uuid) . '</td>';
|
||||
echo '<td class="Relationship">' . h($reference['relationship_type']) . '</td>';
|
||||
echo '</tr>';
|
||||
}
|
||||
echo '</tbody>';
|
||||
echo '</table>';
|
||||
}
|
||||
?>
|
||||
<tr>
|
||||
<table class="table table-condensed table-striped">
|
||||
<thead>
|
||||
|
|
|
@ -266,7 +266,7 @@ foreach ($feeds as $item):
|
|||
endif;
|
||||
if ($item['Feed']['caching_enabled'] && $isSiteAdmin):
|
||||
?>
|
||||
<a href="<?php echo $baseurl;?>/feeds/cacheFeeds/<?php echo h($item['Feed']['id']); ?>" title="Cache feed"><span class="fa fa-memory"></span></a>
|
||||
<a href="<?php echo $baseurl;?>/feeds/cacheFeeds/<?php echo h($item['Feed']['id']); ?>" title="Cache feed"><span class="black fa fa-memory"></span></a>
|
||||
<?php
|
||||
endif;
|
||||
?>
|
||||
|
|
|
@ -0,0 +1,83 @@
|
|||
<?php
|
||||
/*
|
||||
* echo $this->element('/genericElements/IndexTable/index_table', array(
|
||||
* 'top_bar' => (
|
||||
* // search/filter bar information compliant with ListTopBar
|
||||
* ),
|
||||
* 'data' => array(
|
||||
// the actual data to be used
|
||||
* ),
|
||||
* 'fields' => array(
|
||||
* // field list with information for the paginator
|
||||
* ),
|
||||
* 'title' => optional title,
|
||||
* 'description' => optional description
|
||||
* ));
|
||||
*
|
||||
*/
|
||||
echo '<div class="index">';
|
||||
echo $this->element('/genericElements/IndexTable/index_table', array(
|
||||
'data' => array(
|
||||
'data' => $hits,
|
||||
'top_bar' => array(
|
||||
'children' => array(
|
||||
array(
|
||||
'type' => 'search',
|
||||
'button' => __('Filter'),
|
||||
'placeholder' => __('Enter value to search'),
|
||||
'data' => '',
|
||||
'searchKey' => 'value'
|
||||
)
|
||||
)
|
||||
),
|
||||
'fields' => array(
|
||||
array(
|
||||
'name' => __('Id'),
|
||||
'sort' => 'id',
|
||||
'class' => 'short',
|
||||
'data_path' => 'Feed.id'
|
||||
),
|
||||
array(
|
||||
'name' => __('Type'),
|
||||
'class' => 'short',
|
||||
'sort' => 'type',
|
||||
'data_path' => 'Feed.type'
|
||||
),
|
||||
array(
|
||||
'name' => __('Name'),
|
||||
'class' => 'short',
|
||||
'sort' => 'name',
|
||||
'data_path' => 'Feed.name'
|
||||
),
|
||||
array(
|
||||
'name' => __('Feed URL'),
|
||||
'sort' => 'url',
|
||||
'data_path' => 'Feed.url'
|
||||
),
|
||||
array(
|
||||
'name' => __('Link to correlation'),
|
||||
'element' => 'links',
|
||||
'data_path' => 'Feed.direct_urls',
|
||||
'class' => 'action'
|
||||
)
|
||||
),
|
||||
'title' => __('Feed Cache Search'),
|
||||
'description' => __('Search for values potentially contained in the cached feeds and servers.')
|
||||
)
|
||||
));
|
||||
echo '</div>';
|
||||
echo $this->element('/genericElements/SideMenu/side_menu', array('menuList' => 'feeds', 'menuItem' => 'searchCaches'));
|
||||
?>
|
||||
<script type="text/javascript">
|
||||
var passedArgsArray = <?php echo $passedArgs; ?>;
|
||||
$(document).ready(function() {
|
||||
$('#quickFilterButton').click(function() {
|
||||
runIndexQuickFilter();
|
||||
});
|
||||
$('#quickFilterField').on('keypress', function (e) {
|
||||
if(e.which === 13) {
|
||||
runIndexQuickFilter();
|
||||
}
|
||||
});
|
||||
});
|
||||
</script>
|
|
@ -1874,8 +1874,12 @@ function runIndexQuickFilter(preserveParams) {
|
|||
if (!passedArgsArray) {
|
||||
var passedArgsArray = [];
|
||||
}
|
||||
var searchKey = 'searchall';
|
||||
if ($('#quickFilterField').data('searchkey')) {
|
||||
searchKey = $('#quickFilterField').data('searchkey');
|
||||
}
|
||||
if ( $('#quickFilterField').val().trim().length > 0){
|
||||
passedArgsArray["searchall"] = $('#quickFilterField').val().trim();
|
||||
passedArgsArray[searchKey] = $('#quickFilterField').val().trim();
|
||||
}
|
||||
url = here;
|
||||
if (typeof preserveParams !== "undefined") {
|
||||
|
|
Loading…
Reference in New Issue