mirror of https://github.com/MISP/MISP
new: [feeds] index refactor and new features
- added the ability to select an orgc ID for CSV/freetext feeds - all events created from this feed will carry the selected orgc_id - Refactored the index fully - using the factories - better warnings against the dangerous new feed each pull setting - event index search added - several settings cleaned up / made more clear - auto reload of default feed configuration disabled, fixes #2542, fixes #5789 - added a button / endpoint to handle that instead to allow for the deleted default feeds to stay deletedpull/5560/head
parent
cdea7aab4a
commit
2d63f68fc1
|
@ -9,7 +9,18 @@ class FeedsController extends AppController
|
|||
public $paginate = array(
|
||||
'limit' => 60,
|
||||
'recursive' => -1,
|
||||
'contain' => array('Tag', 'SharingGroup'),
|
||||
'contain' => array(
|
||||
'Tag',
|
||||
'SharingGroup',
|
||||
'Orgc' => array(
|
||||
'fields' => array(
|
||||
'Orgc.id',
|
||||
'Orgc.uuid',
|
||||
'Orgc.name',
|
||||
'Orgc.local'
|
||||
)
|
||||
)
|
||||
),
|
||||
'maxLimit' => 9999, // LATER we will bump here on a problem once we have more than 9999 events
|
||||
'order' => array(
|
||||
'Feed.default' => 'DESC',
|
||||
|
@ -29,12 +40,25 @@ class FeedsController extends AppController
|
|||
}
|
||||
}
|
||||
|
||||
public function loadDefaultFeeds()
|
||||
{
|
||||
if ($this->request->is('post')) {
|
||||
$this->Feed->load_default_feeds();
|
||||
$message = __('Default feed metadata loaded.');
|
||||
if ($this->_isRest()) {
|
||||
return $this->RestResponse->saveSuccessResponse('Feed', 'loadDefaultFeeds', false, $this->response->type(), $message);
|
||||
} else {
|
||||
$this->Flash->success($message);
|
||||
$this->redirect(array('controller' => 'Feeds', 'action' => 'index'));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public function index()
|
||||
{
|
||||
if (!$this->_isSiteAdmin() && !$this->Auth->user('org_id') == Configure::read('MISP.host_org_id')) {
|
||||
throw NotAllowedException('You don\'t have access to this feature.');
|
||||
}
|
||||
$this->Feed->load_default_feeds();
|
||||
$scope = isset($this->passedArgs['scope']) ? $this->passedArgs['scope'] : 'all';
|
||||
if ($scope !== 'all') {
|
||||
if ($scope == 'enabled') {
|
||||
|
@ -50,6 +74,15 @@ class FeedsController extends AppController
|
|||
);
|
||||
}
|
||||
}
|
||||
$passedArgs = $this->passedArgs;
|
||||
if (!empty($passedArgs['value'])) {
|
||||
$lookup = strtolower($passedArgs['value']);
|
||||
$allSearchFields = array('name', 'url', 'provider', 'source_format');
|
||||
foreach ($allSearchFields as $field) {
|
||||
$this->paginate['conditions']['AND']['OR'][] = array('LOWER(Feed.' . $field . ') LIKE' => '%' . $lookup . '%');
|
||||
}
|
||||
}
|
||||
$this->set('passedArgs', json_encode($passedArgs));
|
||||
if ($this->_isRest()) {
|
||||
$keepFields = array('conditions', 'contain', 'recursive', 'sort');
|
||||
$searchParams = array();
|
||||
|
@ -172,6 +205,10 @@ class FeedsController extends AppController
|
|||
if (empty($this->request->data['Feed']['fixed_event'])) {
|
||||
$this->request->data['Feed']['fixed_event'] = 1;
|
||||
}
|
||||
$this->set('orgs', $this->Event->Orgc->find('list', array(
|
||||
'fields' => array('id', 'name'),
|
||||
'order' => 'LOWER(name)'
|
||||
)));
|
||||
if ($this->request->is('post')) {
|
||||
if ($this->_isRest()) {
|
||||
if (empty($this->request->data['Feed'])) {
|
||||
|
@ -198,6 +235,11 @@ class FeedsController extends AppController
|
|||
if (!isset($this->request->data['Feed']['source_format'])) {
|
||||
$this->request->data['Feed']['source_format'] = 'freetext';
|
||||
}
|
||||
if (!empty($this->request->data['Feed']['source_format']) && ($this->request->data['Feed']['source_format'] == 'misp')) {
|
||||
if (!empty($this->request->data['Feed']['orgc_id'])) {
|
||||
$this->request->data['Feed']['orgc_id'] = 0;
|
||||
}
|
||||
}
|
||||
if ($this->request->data['Feed']['source_format'] == 'freetext') {
|
||||
if ($this->request->data['Feed']['fixed_event'] == 1) {
|
||||
if (!empty($this->request->data['Feed']['target_event']) && is_numeric($this->request->data['Feed']['target_event'])) {
|
||||
|
@ -287,6 +329,10 @@ class FeedsController extends AppController
|
|||
$tags[0] = 'None';
|
||||
$this->set('feed_types', $this->Feed->getFeedTypesOptions());
|
||||
$this->set('tags', $tags);
|
||||
$this->set('orgs', $this->Event->Orgc->find('list', array(
|
||||
'fields' => array('id', 'name'),
|
||||
'order' => 'LOWER(name)'
|
||||
)));
|
||||
if (!empty($this->Feed->data['Feed']['settings'])) {
|
||||
$this->Feed->data['Feed']['settings'] = json_decode($this->Feed->data['Feed']['settings'], true);
|
||||
}
|
||||
|
@ -303,6 +349,11 @@ class FeedsController extends AppController
|
|||
$this->request->data['Feed']['sharing_group_id'] = 0;
|
||||
}
|
||||
$this->request->data['Feed']['id'] = $feedId;
|
||||
if (!empty($this->request->data['Feed']['source_format']) && ($this->request->data['Feed']['source_format'] == 'misp')) {
|
||||
if (!empty($this->request->data['Feed']['orgc_id'])) {
|
||||
$this->request->data['Feed']['orgc_id'] = 0;
|
||||
}
|
||||
}
|
||||
if (!empty($this->request->data['Feed']['source_format']) && ($this->request->data['Feed']['source_format'] == 'freetext' || $this->request->data['Feed']['source_format'] == 'csv')) {
|
||||
if ($this->request->data['Feed']['fixed_event'] == 1) {
|
||||
if (isset($this->request->data['Feed']['target_event']) && is_numeric($this->request->data['Feed']['target_event'])) {
|
||||
|
@ -324,7 +375,7 @@ class FeedsController extends AppController
|
|||
$this->request->data['Feed']['settings']['delimiter'] = ',';
|
||||
}
|
||||
$this->request->data['Feed']['settings'] = json_encode($this->request->data['Feed']['settings']);
|
||||
$fields = array('id', 'name', 'provider', 'enabled', 'caching_enabled','rules', 'url', 'distribution', 'sharing_group_id', 'tag_id', 'fixed_event', 'event_id', 'publish', 'delta_merge', 'source_format', 'override_ids', 'settings', 'input_source', 'delete_local_file', 'lookup_visible', 'headers');
|
||||
$fields = array('id', 'name', 'provider', 'enabled', 'caching_enabled','rules', 'url', 'distribution', 'sharing_group_id', 'tag_id', 'fixed_event', 'event_id', 'publish', 'delta_merge', 'source_format', 'override_ids', 'settings', 'input_source', 'delete_local_file', 'lookup_visible', 'headers', 'orgc_id');
|
||||
$feed = array();
|
||||
foreach ($fields as $field) {
|
||||
if (isset($this->request->data['Feed'][$field])) {
|
||||
|
|
|
@ -77,7 +77,8 @@ class AppModel extends Model
|
|||
27 => false, 28 => false, 29 => false, 30 => false, 31 => false, 32 => false,
|
||||
33 => false, 34 => false, 35 => false, 36 => false, 37 => false, 38 => false,
|
||||
39 => false, 40 => false, 41 => false, 42 => false, 43 => false, 44 => false,
|
||||
45 => false, 46 => false, 47 => false, 48 => false, 49 => false, 50 => false
|
||||
45 => false, 46 => false, 47 => false, 48 => false, 49 => false, 50 => false,
|
||||
51 => false
|
||||
);
|
||||
|
||||
public $advanced_updates_description = array(
|
||||
|
@ -1372,6 +1373,10 @@ class AppModel extends Model
|
|||
INDEX `timestamp` (`timestamp`)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;";
|
||||
break;
|
||||
case 51:
|
||||
$sqlArray[] = "ALTER TABLE `feeds` ADD `orgc_id` int(11) NOT NULL DEFAULT 0";
|
||||
$this->__addIndex('feeds', 'orgc_id');
|
||||
break;
|
||||
case 'fixNonEmptySharingGroupID':
|
||||
$sqlArray[] = 'UPDATE `events` SET `sharing_group_id` = 0 WHERE `distribution` != 4;';
|
||||
$sqlArray[] = 'UPDATE `attributes` SET `sharing_group_id` = 0 WHERE `distribution` != 4;';
|
||||
|
|
|
@ -19,6 +19,10 @@ class Feed extends AppModel
|
|||
'Tag' => array(
|
||||
'className' => 'Tag',
|
||||
'foreignKey' => 'tag_id',
|
||||
),
|
||||
'Orgc' => array(
|
||||
'className' => 'Organisation',
|
||||
'foreignKey' => 'orgc_id'
|
||||
)
|
||||
);
|
||||
|
||||
|
@ -51,6 +55,25 @@ class Feed extends AppModel
|
|||
)
|
||||
);
|
||||
|
||||
/*
|
||||
* Cleanup of empty belongsto relationships
|
||||
*/
|
||||
public function afterFind($results, $primary = false)
|
||||
{
|
||||
foreach ($results as $k => $result) {
|
||||
if (isset($result['SharingGroup']) && empty($result['SharingGroup']['id'])) {
|
||||
unset($results[$k]['SharingGroup']);
|
||||
}
|
||||
if (isset($result['Tag']) && empty($result['Tag']['id'])) {
|
||||
unset($results[$k]['Tag']);
|
||||
}
|
||||
if (isset($result['Orgc']) && empty($result['Orgc']['id'])) {
|
||||
unset($results[$k]['Orgc']);
|
||||
}
|
||||
}
|
||||
return $results;
|
||||
}
|
||||
|
||||
public function validateInputSource($fields)
|
||||
{
|
||||
if (!empty($this->data['Feed']['input_source'])) {
|
||||
|
@ -879,11 +902,15 @@ class Feed extends AppModel
|
|||
}
|
||||
} else {
|
||||
$this->Event->create();
|
||||
$orgc_id = $user['org_id'];
|
||||
if (!empty($feed['Feed']['orgc_id'])) {
|
||||
$orgc_id = $feed['Feed']['orgc_id'];
|
||||
}
|
||||
$event = array(
|
||||
'info' => $feed['Feed']['name'] . ' feed',
|
||||
'analysis' => 2,
|
||||
'threat_level_id' => 4,
|
||||
'orgc_id' => $user['org_id'],
|
||||
'orgc_id' => $orgc_id,
|
||||
'org_id' => $user['org_id'],
|
||||
'date' => date('Y-m-d'),
|
||||
'distribution' => $feed['Feed']['distribution'],
|
||||
|
|
|
@ -88,6 +88,16 @@
|
|||
</div>
|
||||
</div><br />
|
||||
</div>
|
||||
<div id="OrgcDiv" class="optionalField">
|
||||
<?php
|
||||
echo $this->Form->input('orgc_id', array(
|
||||
'label' => __('Creator organisation'),
|
||||
'div' => 'input clear',
|
||||
'options' => $orgs,
|
||||
'class' => 'form-control span6'
|
||||
));
|
||||
?>
|
||||
</div>
|
||||
<div id="TargetDiv" class="optionalField">
|
||||
<?php
|
||||
echo $this->Form->input('fixed_event', array(
|
||||
|
|
|
@ -92,6 +92,16 @@
|
|||
'class' => 'form-control span6'
|
||||
));
|
||||
?>
|
||||
<div id="OrgcDiv" class="optionalField">
|
||||
<?php
|
||||
echo $this->Form->input('orgc_id', array(
|
||||
'label' => __('Creator organisation'),
|
||||
'div' => 'input clear',
|
||||
'options' => $orgs,
|
||||
'class' => 'form-control span6'
|
||||
));
|
||||
?>
|
||||
</div>
|
||||
<div id="TargetDiv" class="optionalField">
|
||||
<?php
|
||||
echo $this->Form->input('fixed_event', array(
|
||||
|
|
|
@ -1,316 +1,325 @@
|
|||
<div class="feed index">
|
||||
<h2><?php echo __('Feeds');?></h2>
|
||||
<b><?php echo __('Generate feed lookup caches or fetch feed data (enabled feeds only)');?></b>
|
||||
<div class="toggleButtons">
|
||||
<a href="<?php echo $baseurl; ?>/feeds/cacheFeeds/all" class="toggle-left qet btn btn-inverse"><?php echo __('Cache all feeds');?></a>
|
||||
<a href="<?php echo $baseurl; ?>/feeds/cacheFeeds/freetext" class="toggle qet btn btn-inverse"><?php echo __('Cache freetext/CSV feeds');?></a>
|
||||
<a href="<?php echo $baseurl; ?>/feeds/cacheFeeds/misp" class="toggle-right qet btn btn-inverse"><?php echo __('Cache MISP feeds');?></a>
|
||||
<a href="<?php echo $baseurl; ?>/feeds/fetchFromAllFeeds" class="btn btn-primary qet" style="margin-left:20px;"><?php echo __('Fetch and store all feed data');?></a>
|
||||
</div><br />
|
||||
<div class="pagination">
|
||||
<ul>
|
||||
<?php
|
||||
$this->Paginator->options(array(
|
||||
'update' => '.span12',
|
||||
'evalScripts' => true,
|
||||
'before' => '$(".progress").show()',
|
||||
'complete' => '$(".progress").hide()',
|
||||
));
|
||||
|
||||
echo $this->Paginator->prev('« ' . __('previous'), array('tag' => 'li', 'escape' => false), null, array('tag' => 'li', 'class' => 'prev disabled', 'escape' => false, 'disabledTag' => 'span'));
|
||||
echo $this->Paginator->numbers(array('modulus' => 20, 'separator' => '', 'tag' => 'li', 'currentClass' => 'active', 'currentTag' => 'span'));
|
||||
echo $this->Paginator->next(__('next') . ' »', array('tag' => 'li', 'escape' => false), null, array('tag' => 'li', 'class' => 'next disabled', 'escape' => false, 'disabledTag' => 'span'));
|
||||
?>
|
||||
</ul>
|
||||
</div>
|
||||
<?php
|
||||
$canViewFeedData = $isSiteAdmin || intval(Configure::read('MISP.host_org_id')) === $me['org_id'];
|
||||
$data = array(
|
||||
'children' => array(
|
||||
<?php
|
||||
echo '<div class="index">';
|
||||
echo $this->element('/genericElements/IndexTable/index_table', array(
|
||||
'data' => array(
|
||||
'data' => $feeds,
|
||||
'primary_id_path' => 'Feed.id',
|
||||
'top_bar' => array(
|
||||
'children' => array(
|
||||
array(
|
||||
'children' => array(
|
||||
array(
|
||||
'class' => 'hidden mass-select',
|
||||
'text' => __('Enable selected'),
|
||||
'onClick' => "multiSelectToggleFeeds",
|
||||
'onClickParams' => array('1', '0')
|
||||
),
|
||||
array(
|
||||
'class' => 'hidden mass-select',
|
||||
'text' => __('Disable selected'),
|
||||
'onClick' => "multiSelectToggleFeeds",
|
||||
'onClickParams' => array('0', '0')
|
||||
),
|
||||
array(
|
||||
'class' => 'hidden mass-select',
|
||||
'text' => __('Enable caching for selected'),
|
||||
'onClick' => "multiSelectToggleFeeds",
|
||||
'onClickParams' => array('1', '1')
|
||||
),
|
||||
array(
|
||||
'class' => 'hidden mass-select',
|
||||
'text' => __('Disable caching for selected'),
|
||||
'onClick' => "multiSelectToggleFeeds",
|
||||
'onClickParams' => array('0', '1')
|
||||
)
|
||||
)
|
||||
),
|
||||
array(
|
||||
'children' => array(
|
||||
array(
|
||||
'url' => '/feeds/index/scope:default',
|
||||
'text' => __('Default feeds'),
|
||||
'active' => $scope === 'default',
|
||||
'style' => 'display:inline;'
|
||||
),
|
||||
array(
|
||||
'url' => '/feeds/index/scope:custom',
|
||||
'text' => __('Custom feeds'),
|
||||
'active' => $scope === 'custom',
|
||||
'style' => 'display:inline;'
|
||||
),
|
||||
array(
|
||||
'url' => '/feeds/index/scope:all',
|
||||
'text' => __('All feeds'),
|
||||
'active' => $scope === 'all',
|
||||
'style' => 'display:inline;'
|
||||
),
|
||||
array(
|
||||
'url' => '/feeds/index/scope:enabled',
|
||||
'text' => __('Enabled feeds'),
|
||||
'active' => $scope === 'enabled',
|
||||
'style' => 'display:inline;'
|
||||
)
|
||||
)
|
||||
),
|
||||
array(
|
||||
'type' => 'search',
|
||||
'button' => __('Filter'),
|
||||
'placeholder' => __('Enter value to search'),
|
||||
'data' => '',
|
||||
'searchKey' => 'value'
|
||||
)
|
||||
)
|
||||
),
|
||||
'fields' => array(
|
||||
array(
|
||||
'children' => array(
|
||||
array(
|
||||
'class' => 'hidden mass-select',
|
||||
'text' => __('Enable selected'),
|
||||
'onClick' => "multiSelectToggleFeeds",
|
||||
'onClickParams' => array('1', '0')
|
||||
),
|
||||
array(
|
||||
'class' => 'hidden mass-select',
|
||||
'text' => __('Disable selected'),
|
||||
'onClick' => "multiSelectToggleFeeds",
|
||||
'onClickParams' => array('0', '0')
|
||||
),
|
||||
array(
|
||||
'class' => 'hidden mass-select',
|
||||
'text' => __('Enable caching for selected'),
|
||||
'onClick' => "multiSelectToggleFeeds",
|
||||
'onClickParams' => array('1', '1')
|
||||
),
|
||||
array(
|
||||
'class' => 'hidden mass-select',
|
||||
'text' => __('Disable caching for selected'),
|
||||
'onClick' => "multiSelectToggleFeeds",
|
||||
'onClickParams' => array('0', '1')
|
||||
),
|
||||
'element' => 'selector',
|
||||
'class' => 'short',
|
||||
'data' => array(
|
||||
'id' => array(
|
||||
'value_path' => 'Feed.id'
|
||||
)
|
||||
)
|
||||
),
|
||||
array(
|
||||
'children' => array(
|
||||
array(
|
||||
'url' => '/feeds/index/scope:default',
|
||||
'text' => __('Default feeds'),
|
||||
'active' => $scope === 'default'
|
||||
),
|
||||
array(
|
||||
'url' => '/feeds/index/scope:custom',
|
||||
'text' => __('Custom feeds'),
|
||||
'active' => $scope === 'custom'
|
||||
),
|
||||
array(
|
||||
'url' => '/feeds/index/scope:all',
|
||||
'text' => __('All feeds'),
|
||||
'active' => $scope === 'all'
|
||||
),
|
||||
array(
|
||||
'url' => '/feeds/index/scope:enabled',
|
||||
'text' => __('Enabled feeds'),
|
||||
'active' => $scope === 'enabled'
|
||||
)
|
||||
)
|
||||
'name' => __('Id'),
|
||||
'sort' => 'Feed.id',
|
||||
'class' => 'short',
|
||||
'data_path' => 'Feed.id',
|
||||
),
|
||||
array(
|
||||
'name' => __('Enabled'),
|
||||
'sort' => 'Feed.enabled',
|
||||
'title' => __('Enable pulling the feed into your MISP as events/attributes.'),
|
||||
'class' => 'short',
|
||||
'element' => 'boolean',
|
||||
'data_path' => 'Feed.enabled',
|
||||
'rule_path' => 'Feed.rules'
|
||||
),
|
||||
array(
|
||||
'name' => __('Caching'),
|
||||
'sort' => 'Feed.caching_enabled',
|
||||
'title' => __('Enable caching the feed into Redis - allowing for correlations to the feed to be shown.'),
|
||||
'class' => 'short',
|
||||
'element' => 'boolean',
|
||||
'data_path' => 'Feed.caching_enabled',
|
||||
),
|
||||
array(
|
||||
'name' => __('Name'),
|
||||
'class' => 'shortish',
|
||||
'data_path' => 'Feed.name',
|
||||
),
|
||||
array(
|
||||
'name' => __('Format'),
|
||||
'class' => 'short',
|
||||
'sort' => 'Feed.source_format',
|
||||
'data_path' => 'Feed.source_format'
|
||||
),
|
||||
array(
|
||||
'name' => __('Provider'),
|
||||
'class' => 'short',
|
||||
'data_path' => 'Feed.provider',
|
||||
'sort' => 'Feed.provider'
|
||||
),
|
||||
array(
|
||||
'name' => __('Org'),
|
||||
'class' => 'short',
|
||||
'data_path' => 'Orgc',
|
||||
'sort' => 'Feed.Orgc',
|
||||
'element' => 'org'
|
||||
),
|
||||
array(
|
||||
'name' => __('Source'),
|
||||
'class' => 'short',
|
||||
'data_path' => 'Feed.input_source',
|
||||
'sort' => 'Feed.input_source'
|
||||
),
|
||||
array(
|
||||
'name' => __('URL'),
|
||||
'class' => 'shortish',
|
||||
'data_path' => 'Feed.url',
|
||||
'sort' => 'Feed.url'
|
||||
),
|
||||
array(
|
||||
'name' => __('Headers'),
|
||||
'class' => 'shortish',
|
||||
'data_path' => 'Feed.headers'
|
||||
),
|
||||
array(
|
||||
'name' => __('Target'),
|
||||
'class' => 'short',
|
||||
'data_path' => array(
|
||||
'Feed.fixed_event',
|
||||
'Feed.source_format',
|
||||
'Feed.event_error',
|
||||
'Feed.event_id',
|
||||
'Feed.enabled'
|
||||
),
|
||||
'element' => 'target_event'
|
||||
),
|
||||
array(
|
||||
'name' => __('Publish'),
|
||||
'class' => 'short',
|
||||
'element' => 'boolean',
|
||||
'sort' => 'Feed.publish',
|
||||
'data_path' => 'Feed.publish'
|
||||
),
|
||||
array(
|
||||
'name' => __('Delta'),
|
||||
'title' => __('Delta Merge strategy - align the local feed with the remote state'),
|
||||
'class' => 'short',
|
||||
'element' => 'boolean',
|
||||
'sort' => 'Feed.delta_merge',
|
||||
'data_path' => 'Feed.delta_merge'
|
||||
),
|
||||
array(
|
||||
'name' => __('Override'),
|
||||
'title' => __('Override the IDS flags and set all derived attribute to IDS off'),
|
||||
'class' => 'short',
|
||||
'element' => 'boolean',
|
||||
'sort' => 'Feed.ids',
|
||||
'data_path' => 'Feed.ids'
|
||||
),
|
||||
array(
|
||||
'name' => __('Distribution'),
|
||||
'class' => 'short',
|
||||
'data_path' => 'Feed.distribution',
|
||||
'element' => 'distribution_levels'
|
||||
),
|
||||
array(
|
||||
'name' => __('Tag'),
|
||||
'class' => 'short',
|
||||
'data_path' => 'Tag',
|
||||
'element' => 'tags'
|
||||
),
|
||||
array(
|
||||
'name' => __('Visible'),
|
||||
'class' => 'short',
|
||||
'data_path' => 'Feed.lookup_visible',
|
||||
'element' => 'boolean',
|
||||
'sort' => 'Feed.lookup_visible'
|
||||
),
|
||||
array(
|
||||
'name' => __('Caching'),
|
||||
'class' => 'short',
|
||||
'data_path' => 'Feed.cache_timestamp',
|
||||
'enabled_path' => 'Feed.caching_enabled',
|
||||
'element' => 'caching',
|
||||
'sort' => 'Feed.cache_timestamp'
|
||||
)
|
||||
)
|
||||
);
|
||||
echo $this->element('/genericElements/ListTopBar/scaffold', array('data' => $data));
|
||||
?>
|
||||
<table class="table table-striped table-hover table-condensed">
|
||||
<tr>
|
||||
<?php if ($isSiteAdmin): ?>
|
||||
<th>
|
||||
<input class="select_all select" type="checkbox" title="<?php echo __('Select all');?>" role="button" tabindex="0" aria-label="<?php echo __('Select all events on current page');?>" onClick="toggleAllCheckboxes();" />
|
||||
</th>
|
||||
<?php else: ?>
|
||||
<th style="padding-left:0px;padding-right:0px;"> </th>
|
||||
<?php endif;?>
|
||||
<th><?php echo $this->Paginator->sort('id');?></th>
|
||||
<th title="<?php echo __('Enable pulling the feed into your MISP as events/attributes.'); ?>"><?php echo $this->Paginator->sort('enabled');?></th>
|
||||
<th title="<?php echo __('Enable caching the feed into Redis - allowing for correlations to the feed to be shown.'); ?>"><?php echo $this->Paginator->sort('caching_enabled', __('Caching enabled'));?></th>
|
||||
<th><?php echo $this->Paginator->sort('name');?></th>
|
||||
<th><?php echo $this->Paginator->sort('source_format', __('Feed Format'));?></th>
|
||||
<th><?php echo $this->Paginator->sort('provider', __('Provider'));?></th>
|
||||
<th><?php echo $this->Paginator->sort('input_source', __('Input'));?></th>
|
||||
<th><?php echo $this->Paginator->sort('url', __('URL'));?></th>
|
||||
<th><?php echo $this->Paginator->sort('headers');?></th>
|
||||
<th><?php echo __('Target');?></th>
|
||||
<th><?php echo __('Publish');?></th>
|
||||
<th><?php echo __('Delta Merge');?></th>
|
||||
<th><?php echo __('Override IDS');?></th>
|
||||
<th><?php echo $this->Paginator->sort('distribution');?></th>
|
||||
<th><?php echo $this->Paginator->sort('tag');?></th>
|
||||
<th><?php echo $this->Paginator->sort('lookup_visible', __('Lookup visible'));?></th>
|
||||
<th class="actions"><?php echo __('Caching');?></th>
|
||||
<th class="actions"><?php echo __('Actions');?></th>
|
||||
</tr><?php
|
||||
foreach ($feeds as $item):
|
||||
$rules = array();
|
||||
$rules = json_decode($item['Feed']['rules'], true);
|
||||
$fieldOptions = array('tags', 'orgs');
|
||||
$typeOptions = array('OR' => array('colour' => 'green', 'text' => 'allowed'), 'NOT' => array('colour' => 'red', 'text' => 'blocked'));
|
||||
$ruleDescription = '';
|
||||
foreach ($fieldOptions as $fieldOption) {
|
||||
foreach ($typeOptions as $typeOption => $typeData) {
|
||||
if (isset($rules[$fieldOption][$typeOption]) && !empty($rules[$fieldOption][$typeOption])) {
|
||||
$ruleDescription .= '<span class=\'bold\'>' .
|
||||
ucfirst($fieldOption) . ' ' .
|
||||
$typeData['text'] . '</span>: <span class=\'' .
|
||||
$typeData['colour'] . '\'>';
|
||||
foreach ($rules[$fieldOption][$typeOption] as $k => $temp) {
|
||||
if ($k != 0) $ruleDescription .= ', ';
|
||||
$ruleDescription .= h($temp);
|
||||
}
|
||||
$ruleDescription .= '</span><br />';
|
||||
}
|
||||
}
|
||||
}
|
||||
?>
|
||||
<tr>
|
||||
<?php
|
||||
if ($isSiteAdmin):
|
||||
?>
|
||||
<td style="width:10px;" data-id="<?php echo h($item['Feed']['id']); ?>">
|
||||
<input class="select" type="checkbox" data-id="<?php echo $item['Feed']['id'];?>" aria-label="select <?php echo $item['Feed']['name'];?>" />
|
||||
</td>
|
||||
<?php
|
||||
else:
|
||||
?>
|
||||
<td style="padding-left:0px;padding-right:0px;"></td>
|
||||
<?php
|
||||
endif;
|
||||
?>
|
||||
<td class="short">
|
||||
<?php
|
||||
if ($canViewFeedData) {
|
||||
echo sprintf(
|
||||
'<a href="%s/feeds/view/%s" title="%s">%s</a>',
|
||||
$baseurl,
|
||||
h($item['Feed']['id']),
|
||||
sprintf(
|
||||
__('View feed #%s', h($item['Feed']['id']))
|
||||
),
|
||||
'title' => __('Feeds'),
|
||||
'description' => __('Generate feed lookup caches or fetch feed data (enabled feeds only)'),
|
||||
'html' => sprintf(
|
||||
'<div class="toggleButtons">%s%s%s%s%s</div><br />',
|
||||
$this->Form->postButton(
|
||||
__('Load default feed metadata'),
|
||||
array('controller' => 'feeds', 'action' => 'loadDefaultFeeds'),
|
||||
array(
|
||||
'class' => 'qet btn btn-inverse',
|
||||
'div' => false,
|
||||
'style' => 'margin-right:20px;'
|
||||
)
|
||||
),
|
||||
sprintf(
|
||||
'<a href="%s/feeds/cacheFeeds/all" class="%s">%s</a>',
|
||||
$baseurl,
|
||||
'toggle-left qet btn btn-inverse',
|
||||
__('Cache all feeds')
|
||||
),
|
||||
sprintf(
|
||||
'<a href="%s/feeds/cacheFeeds/freetext" class="%s">%s</a>',
|
||||
$baseurl,
|
||||
'toggle qet btn btn-inverse',
|
||||
__('Cache freetext/CSV feeds')
|
||||
),
|
||||
sprintf(
|
||||
'<a href="%s/feeds/cacheFeeds/misp" class="%s">%s</a>',
|
||||
$baseurl,
|
||||
'toggle-right qet btn btn-inverse',
|
||||
__('Cache MISP feeds')
|
||||
),
|
||||
sprintf(
|
||||
'<a href="%s/feeds/fetchFromAllFeeds" class="%s" style="%s">%s</a>',
|
||||
$baseurl,
|
||||
'btn btn-primary qet',
|
||||
'margin-left:20px;',
|
||||
__('Fetch and store all feed data')
|
||||
)
|
||||
),
|
||||
'actions' => array(
|
||||
array(
|
||||
'url' => $baseurl . '/feeds/previewIndex',
|
||||
'url_params_data_paths' => 'Feed.id',
|
||||
'icon' => 'search',
|
||||
'title' => __('Explore the events remotely')
|
||||
),
|
||||
array(
|
||||
'url' => $baseurl . '/feeds/fetchFromFeed',
|
||||
'url_params_data_paths' => 'Feed.id',
|
||||
'icon' => 'arrow-circle-down',
|
||||
'title' => __('Fetch all events'),
|
||||
'requirement' => $isSiteAdmin,
|
||||
'complex_requirement' => array(
|
||||
'options' => array(
|
||||
'datapath' => array(
|
||||
'event_error' => 'Feed.event_error',
|
||||
'enabled' => 'Feed.enabled'
|
||||
),
|
||||
),
|
||||
h($item['Feed']['id'])
|
||||
);
|
||||
} else {
|
||||
echo h($item['Feed']['id']);
|
||||
}
|
||||
|
||||
?>
|
||||
</td>
|
||||
<td class="short">
|
||||
<span role="img" <?php echo ($item['Feed']['enabled'] ? 'class="icon-ok" aria-label="Yes"' : 'class="icon-remove" aria-label="No"'); ?>"></span>
|
||||
<span
|
||||
class="short <?php if (!$item['Feed']['enabled'] || empty($ruleDescription)) echo "hidden"; ?>"
|
||||
data-toggle="popover"
|
||||
title="Filter rules"
|
||||
data-content="<?php echo $ruleDescription; ?>"
|
||||
>
|
||||
(<?php echo __('Rules');?>)
|
||||
</span>
|
||||
</td>
|
||||
<td class="short">
|
||||
<span role="img" <?php echo ($item['Feed']['caching_enabled'] ? 'class="icon-ok" aria-label="Yes"' : 'class="icon-remove" aria-label="No"'); ?>"></span>
|
||||
</td>
|
||||
<td>
|
||||
<?php
|
||||
echo h($item['Feed']['name']);
|
||||
if ($item['Feed']['default']):
|
||||
?>
|
||||
<img src="<?php echo $baseurl;?>/img/orgs/MISP.png" width="24" height="24" style="padding-bottom:3px;" />
|
||||
<?php
|
||||
endif;
|
||||
?>
|
||||
</td>
|
||||
<td><?php echo $feed_types[$item['Feed']['source_format']]['name']; ?> </td>
|
||||
<td><?php echo h($item['Feed']['provider']); ?> </td>
|
||||
<td><?php echo h($item['Feed']['input_source']); ?> </td>
|
||||
<td><?php echo h($item['Feed']['url']); ?> </td>
|
||||
<td class="short"><?php echo nl2br(h($item['Feed']['headers'])); ?> </td>
|
||||
<td class="shortish">
|
||||
<?php
|
||||
if (in_array($item['Feed']['source_format'], array('freetext', 'csv'))):
|
||||
if ($item['Feed']['fixed_event']):
|
||||
if (isset($item['Feed']['event_error'])):
|
||||
?>
|
||||
<span class="red bold"><?php echo __('Error: Invalid event!');?></span>
|
||||
<?php
|
||||
else:
|
||||
if ($item['Feed']['event_id']):
|
||||
?>
|
||||
<a href="<?php echo $baseurl;?>/events/view/<?php echo h($item['Feed']['event_id']); ?>"><?php echo __('Fixed event %s', h($item['Feed']['event_id']));?></a>
|
||||
<?php
|
||||
else:
|
||||
echo __('New fixed event');
|
||||
endif;
|
||||
endif;
|
||||
endif;
|
||||
else:
|
||||
echo ' ';
|
||||
endif;
|
||||
?>
|
||||
</td>
|
||||
<?php
|
||||
if ($item['Feed']['source_format'] != 'misp'):
|
||||
?>
|
||||
<td><span role="img" <?php echo ($item['Feed']['publish'] ? 'class="icon-ok" aria-label="Yes"' : 'class="icon-remove" aria-label="No"'); ?>"></span></td>
|
||||
<td><span role="img" <?php echo ($item['Feed']['delta_merge'] ? 'class="icon-ok" aria-label="Yes"' : 'class="icon-remove" aria-label="No"'); ?>"></span></td>
|
||||
<td><span role="img" <?php echo ($item['Feed']['override_ids'] ? 'class="icon-ok" aria-label="Yes"' : 'class="icon-remove" aria-label="No"'); ?>"></span></td>
|
||||
<?php
|
||||
else:
|
||||
?>
|
||||
<td> </td>
|
||||
<td> </td>
|
||||
<td> </td>
|
||||
<?php
|
||||
endif;
|
||||
?>
|
||||
<td <?php if ($item['Feed']['distribution'] == 0) echo 'class="red"'; ?>>
|
||||
<?php
|
||||
echo $item['Feed']['distribution'] == 4 ? '<a href="' . $baseurl . '/sharing_groups/view/' . h($item['SharingGroup']['id']) . '">' . h($item['SharingGroup']['name']) . '</a>' : $distributionLevels[$item['Feed']['distribution']] ;
|
||||
?>
|
||||
</td>
|
||||
<td>
|
||||
<?php if ($item['Feed']['tag_id']): ?>
|
||||
<a href="<?php echo $baseurl;?>/events/index/searchtag:<?php echo h($item['Tag']['id']); ?>" class=tag style="background-color:<?php echo h($item['Tag']['colour']);?>;color:<?php echo $this->TextColour->getTextColour($item['Tag']['colour']);?>"><?php echo h($item['Tag']['name']); ?></a>
|
||||
<?php else: ?>
|
||||
|
||||
<?php endif;?>
|
||||
</td>
|
||||
<td class="short"><span role="img" <?php echo ($item['Feed']['lookup_visible'] ? 'class="icon-ok" aria-label="Yes"' : 'class="icon-remove" aria-label="No"'); ?>"></span>
|
||||
<td class="short action-links <?php echo !empty($item['Feed']['cache_timestamp']) ? 'bold' : 'bold red';?>">
|
||||
<?php
|
||||
if (!empty($item['Feed']['cache_timestamp'])):
|
||||
$units = array('m', 'h', 'd');
|
||||
$intervals = array(60, 60, 24);
|
||||
$unit = 's';
|
||||
$last = time() - $item['Feed']['cache_timestamp'];
|
||||
foreach ($units as $k => $v) {
|
||||
if ($last > $intervals[$k]) {
|
||||
$unit = $v;
|
||||
$last = floor($last / $intervals[$k]);
|
||||
} else {
|
||||
break;
|
||||
'function' => function($row, $options) {
|
||||
if (!empty($options['datapath']['event_error'])) {
|
||||
return false;
|
||||
}
|
||||
if (empty($options['datapath']['enabled'])) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
||||
echo __('Age: ') . $last . $unit;
|
||||
else:
|
||||
echo __('Not cached');
|
||||
endif;
|
||||
if ($item['Feed']['caching_enabled'] && $isSiteAdmin):
|
||||
?>
|
||||
<a href="<?php echo $baseurl;?>/feeds/cacheFeeds/<?php echo h($item['Feed']['id']); ?>" title="<?php echo __('Cache feed');?>" aria-label="<?php echo __('Cache feed');?>"><span class="black fa fa-memory"></span></a>
|
||||
<?php
|
||||
endif;
|
||||
?>
|
||||
</td>
|
||||
<td class="short action-links">
|
||||
<?php
|
||||
echo $this->Html->link('', array('action' => 'previewIndex', $item['Feed']['id']), array('class' => 'fa fa-search', 'title' => __('Explore the events remotely'), 'aria-label' => __('Explore the events remotely')));
|
||||
if (!isset($item['Feed']['event_error']) && $isSiteAdmin) {
|
||||
if ($item['Feed']['enabled']) echo $this->Html->link('', array('action' => 'fetchFromFeed', $item['Feed']['id']), array('class' => 'fa fa-arrow-circle-down', 'title' => __('Fetch all events'), 'aria-label' => __('Fetch all events')));
|
||||
}
|
||||
if ($isSiteAdmin):
|
||||
?>
|
||||
<a href="<?php echo $baseurl;?>/feeds/edit/<?php echo h($item['Feed']['id']); ?>" aria-label="<?php echo __('Edit');?>"><span class="black fa fa-edit" title="<?php echo __('Edit');?>"> </span></a>
|
||||
<?php echo $this->Form->postLink('', array('action' => 'delete', h($item['Feed']['id'])), array('class' => 'fa fa-trash', 'title' => __('Delete'), 'aria-label' => __('Delete')), __('Are you sure you want to permanently remove the feed (%s)?', h($item['Feed']['name']))); ?>
|
||||
<?php endif; ?>
|
||||
<a href="<?php echo $baseurl;?>/feeds/view/<?php echo h($item['Feed']['id']); ?>.json" title="<?php echo __('Download feed metadata as JSON');?>" download><span class="fa fa-cloud-download-alt black"></span></a>
|
||||
</td>
|
||||
</tr><?php
|
||||
endforeach; ?>
|
||||
</table>
|
||||
<p>
|
||||
<?php
|
||||
echo $this->Paginator->counter(array(
|
||||
'format' => __('Page {:page} of {:pages}, showing {:current} records out of {:count} total, starting on record {:start}, ending on {:end}')
|
||||
)
|
||||
),
|
||||
array(
|
||||
'url' => $baseurl . '/feeds/edit',
|
||||
'url_params_data_paths' => 'Feed.id',
|
||||
'icon' => 'edit',
|
||||
'title' => __('Edit'),
|
||||
'requirement' => $isSiteAdmin
|
||||
),
|
||||
array(
|
||||
'url' => $baseurl . '/feeds/delete',
|
||||
'url_params_data_paths' => 'Feed.id',
|
||||
'icon' => 'trash',
|
||||
'title' => __('Delete'),
|
||||
'postLink' => 1,
|
||||
'postLinkConfirm' => __('Are you sure you want to permanently remove the feed?'),
|
||||
'requirement' => $isSiteAdmin
|
||||
),
|
||||
array(
|
||||
'url' => $baseurl . '/feeds/view',
|
||||
'url_params_data_paths' => 'Feed.id',
|
||||
'url_extension' => 'json',
|
||||
'icon' => 'cloud-download-alt',
|
||||
'title' => __('Download feed metadata as JSON')
|
||||
),
|
||||
)
|
||||
)
|
||||
));
|
||||
?>
|
||||
</p>
|
||||
<div class="pagination">
|
||||
<ul>
|
||||
<?php
|
||||
echo $this->Paginator->prev('« ' . __('previous'), array('tag' => 'li', 'escape' => false), null, array('tag' => 'li', 'class' => 'prev disabled', 'escape' => false, 'disabledTag' => 'span'));
|
||||
echo $this->Paginator->numbers(array('modulus' => 20, 'separator' => '', 'tag' => 'li', 'currentClass' => 'active', 'currentTag' => 'span'));
|
||||
echo $this->Paginator->next(__('next') . ' »', array('tag' => 'li', 'escape' => false), null, array('tag' => 'li', 'class' => 'next disabled', 'escape' => false, 'disabledTag' => 'span'));
|
||||
?>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
echo '</div>';
|
||||
echo $this->element('/genericElements/SideMenu/side_menu', array('menuList' => 'feeds', 'menuItem' => 'index'));
|
||||
?>
|
||||
<script type="text/javascript">
|
||||
$(document).ready(function(){
|
||||
popoverStartup();
|
||||
$('.select').on('change', function() {
|
||||
listCheckboxesChecked();
|
||||
});
|
||||
$('#quickFilterButton').click(function() {
|
||||
runIndexQuickFilter();
|
||||
});
|
||||
$('#quickFilterField').on('keypress', function (e) {
|
||||
if(e.which === 13) {
|
||||
runIndexQuickFilter();
|
||||
}
|
||||
});
|
||||
});
|
||||
</script>
|
||||
<?php
|
||||
echo $this->element('/genericElements/SideMenu/side_menu', array('menuList' => 'feeds', 'menuItem' => 'index'));
|
||||
|
|
|
@ -3939,6 +3939,7 @@ function feedFormUpdate() {
|
|||
switch($('#FeedSourceFormat').val()) {
|
||||
case 'freetext':
|
||||
$('#TargetDiv').show();
|
||||
$('#OrgcDiv').show();
|
||||
$('#OverrideIdsDiv').show();
|
||||
$('#PublishDiv').show();
|
||||
if ($('#FeedTarget').val() != 0) {
|
||||
|
@ -3949,6 +3950,7 @@ function feedFormUpdate() {
|
|||
break;
|
||||
case 'csv':
|
||||
$('#TargetDiv').show();
|
||||
$('#OrgcDiv').show();
|
||||
$('#OverrideIdsDiv').show();
|
||||
$('#PublishDiv').show();
|
||||
if ($('#FeedTarget').val() != 0) {
|
||||
|
|
Loading…
Reference in New Issue