mirror of https://github.com/MISP/MISP
chg: migrate FeedsController to use CRUD component.
parent
91c2c95e6c
commit
94d4ba8274
|
@ -6,28 +6,32 @@ App::uses('AppController', 'Controller');
|
|||
*/
|
||||
class FeedsController extends AppController
|
||||
{
|
||||
public $components = array('Security', 'RequestHandler'); // XXX ACL component
|
||||
public $components = array(
|
||||
'Security',
|
||||
'CRUD',
|
||||
'RequestHandler'
|
||||
); // XXX ACL component
|
||||
|
||||
public $paginate = array(
|
||||
'limit' => 60,
|
||||
'recursive' => -1,
|
||||
'contain' => array(
|
||||
'Tag',
|
||||
'SharingGroup',
|
||||
'Orgc' => array(
|
||||
'fields' => array(
|
||||
'Orgc.id',
|
||||
'Orgc.uuid',
|
||||
'Orgc.name',
|
||||
'Orgc.local'
|
||||
)
|
||||
'limit' => 60,
|
||||
'recursive' => -1,
|
||||
'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',
|
||||
'Feed.id' => 'ASC'
|
||||
),
|
||||
)
|
||||
),
|
||||
'maxLimit' => 9999, // LATER we will bump here on a problem once we have more than 9999 events
|
||||
'order' => array(
|
||||
'Feed.default' => 'DESC',
|
||||
'Feed.id' => 'ASC'
|
||||
),
|
||||
);
|
||||
|
||||
public $uses = array('Feed');
|
||||
|
@ -58,97 +62,99 @@ class FeedsController extends AppController
|
|||
|
||||
public function index()
|
||||
{
|
||||
$conditions = [];
|
||||
$scope = isset($this->passedArgs['scope']) ? $this->passedArgs['scope'] : 'all';
|
||||
if ($scope !== 'all') {
|
||||
if ($scope == 'enabled') {
|
||||
$this->paginate['conditions'][] = array(
|
||||
$conditions[] = array(
|
||||
'OR' => array(
|
||||
'Feed.enabled' => 1,
|
||||
'Feed.caching_enabled' => 1
|
||||
)
|
||||
);
|
||||
} else {
|
||||
$this->paginate['conditions'][] = array(
|
||||
$conditions[] = array(
|
||||
'Feed.default' => $scope == 'custom' ? 0 : 1
|
||||
);
|
||||
}
|
||||
}
|
||||
$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();
|
||||
foreach ($keepFields as $field) {
|
||||
if (!empty($this->paginate[$field])) {
|
||||
$searchParams[$field] = $this->paginate[$field];
|
||||
}
|
||||
}
|
||||
|
||||
$data = $this->Feed->find('all', $searchParams);
|
||||
} else {
|
||||
$data = $this->paginate();
|
||||
}
|
||||
foreach ($data as $i => $entry) {
|
||||
if (!$this->_isSiteAdmin()) {
|
||||
unset($data[$i]['Feed']['headers']);
|
||||
}
|
||||
}
|
||||
$this->loadModel('Event');
|
||||
foreach ($data as $key => $value) {
|
||||
if ($value['Feed']['event_id'] != 0 && $value['Feed']['fixed_event']) {
|
||||
$event = $this->Event->find('first', array('conditions' => array('Event.id' => $value['Feed']['event_id']), 'recursive' => -1, 'fields' => array('Event.id')));
|
||||
if (empty($event)) {
|
||||
$data[$key]['Feed']['event_error'] = true;
|
||||
$this->CRUD->index([
|
||||
'filters' => [
|
||||
'Feed.name',
|
||||
'url',
|
||||
'provider',
|
||||
'source_format',
|
||||
'enabled',
|
||||
'caching_enabled',
|
||||
'default'
|
||||
],
|
||||
'quickFilters' => [
|
||||
'Feed.name',
|
||||
'url',
|
||||
'provider',
|
||||
'source_format'
|
||||
],
|
||||
'conditions' => $conditions,
|
||||
'afterFind' => function (array $feeds) {
|
||||
if ($this->_isSiteAdmin()) {
|
||||
$feeds = $this->Feed->attachFeedCacheTimestamps($feeds);
|
||||
}
|
||||
}
|
||||
}
|
||||
if ($this->_isSiteAdmin()) {
|
||||
$data = $this->Feed->attachFeedCacheTimestamps($data);
|
||||
}
|
||||
if ($this->_isRest()) {
|
||||
foreach ($data as $k => $v) {
|
||||
unset($data[$k]['SharingGroup']);
|
||||
if (empty($data[$k]['Tag']['id'])) {
|
||||
unset($data[$k]['Tag']);
|
||||
|
||||
if ($this->IndexFilter->isRest()) {
|
||||
foreach ($feeds as &$feed) {
|
||||
unset($feed['SharingGroup']);
|
||||
if (empty($feed['Tag']['id'])) {
|
||||
unset($feed['Tag']);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return $feeds;
|
||||
}
|
||||
return $this->RestResponse->viewData($data, $this->response->type());
|
||||
]);
|
||||
|
||||
if ($this->IndexFilter->isRest()) {
|
||||
return $this->restResponsePayload;
|
||||
}
|
||||
$this->set('scope', $scope);
|
||||
$this->set('feeds', $data);
|
||||
|
||||
$this->set('title_for_layout', __('Feeds'));
|
||||
$this->set('menuData', [
|
||||
'menuList' => 'feeds',
|
||||
'menuItem' => 'index'
|
||||
]);
|
||||
$this->loadModel('Event');
|
||||
$this->set('feed_types', $this->Feed->feed_types);
|
||||
$this->set('distributionLevels', $this->Event->distributionLevels);
|
||||
$this->set('scope', $scope);
|
||||
}
|
||||
|
||||
public function view($feedId)
|
||||
{
|
||||
$feed = $this->Feed->find('first', array(
|
||||
'conditions' => array('Feed.id' => $feedId),
|
||||
'recursive' => -1,
|
||||
'contain' => array('Tag')
|
||||
));
|
||||
if (!$this->_isSiteAdmin()) {
|
||||
unset($feed['Feed']['headers']);
|
||||
}
|
||||
$feed['Feed']['cached_elements'] = $this->Feed->getCachedElements($feed['Feed']['id']);
|
||||
$feed['Feed']['coverage_by_other_feeds'] = $this->Feed->getFeedCoverage($feed['Feed']['id'], 'feed', 'all') . '%';
|
||||
if ($this->_isRest()) {
|
||||
if (empty($feed['Tag']['id'])) {
|
||||
unset($feed['Tag']);
|
||||
$this->CRUD->view($feedId, [
|
||||
'contain' => ['Tag'],
|
||||
'afterFind' => function (array $feed) {
|
||||
if (!$this->_isSiteAdmin()) {
|
||||
unset($feed['Feed']['headers']);
|
||||
}
|
||||
|
||||
$feed['Feed']['cached_elements'] = $this->Feed->getCachedElements($feed['Feed']['id']);
|
||||
$feed['Feed']['coverage_by_other_feeds'] = $this->Feed->getFeedCoverage($feed['Feed']['id'], 'feed', 'all') . '%';
|
||||
|
||||
if ($this->_isRest()) {
|
||||
if (empty($feed['Tag']['id'])) {
|
||||
unset($feed['Tag']);
|
||||
}
|
||||
}
|
||||
|
||||
return $feed;
|
||||
}
|
||||
return $this->RestResponse->viewData($feed, $this->response->type());
|
||||
]);
|
||||
if ($this->IndexFilter->isRest()) {
|
||||
return $this->restResponsePayload;
|
||||
}
|
||||
$feeds = $this->Feed->getAllCachingEnabledFeeds($feed['Feed']['id'], true);
|
||||
$this->set('other_feeds', $feeds);
|
||||
$this->set('feed', $feed);
|
||||
|
||||
$otherFeeds = $this->Feed->getAllCachingEnabledFeeds($feedId, true);
|
||||
$this->set('other_feeds', $otherFeeds);
|
||||
}
|
||||
|
||||
public function feedCoverage($feedId)
|
||||
|
@ -190,120 +196,123 @@ class FeedsController extends AppController
|
|||
|
||||
public function add()
|
||||
{
|
||||
$params = [
|
||||
'beforeSave' => function (array $feed) {
|
||||
if ($this->_isRest()) {
|
||||
if (empty($feed['Feed']['source_format'])) {
|
||||
$feed['Feed']['source_format'] = 'freetext';
|
||||
}
|
||||
if (empty($feed['Feed']['fixed_event'])) {
|
||||
$feed['Feed']['source_format'] = 1;
|
||||
}
|
||||
}
|
||||
|
||||
if (isset($feed['Feed']['pull_rules'])) {
|
||||
$feed['Feed']['rules'] = $feed['Feed']['pull_rules'];
|
||||
}
|
||||
if (!isset($feed['Feed']['distribution'])) {
|
||||
$feed['Feed']['distribution'] = 0;
|
||||
}
|
||||
if ($feed['Feed']['distribution'] != 4) {
|
||||
$feed['Feed']['sharing_group_id'] = 0;
|
||||
}
|
||||
$feed['Feed']['default'] = 0;
|
||||
if (!isset($feed['Feed']['source_format'])) {
|
||||
$feed['Feed']['source_format'] = 'freetext';
|
||||
}
|
||||
if (!empty($feed['Feed']['source_format']) && ($feed['Feed']['source_format'] == 'misp')) {
|
||||
if (!empty($feed['Feed']['orgc_id'])) {
|
||||
$feed['Feed']['orgc_id'] = 0;
|
||||
}
|
||||
}
|
||||
if ($feed['Feed']['source_format'] == 'freetext') {
|
||||
if ($feed['Feed']['fixed_event'] == 1) {
|
||||
if (!empty($feed['Feed']['target_event']) && is_numeric($feed['Feed']['target_event'])) {
|
||||
$feed['Feed']['event_id'] = $feed['Feed']['target_event'];
|
||||
}
|
||||
}
|
||||
}
|
||||
if (!isset($feed['Feed']['settings'])) {
|
||||
$feed['Feed']['settings'] = array();
|
||||
} else {
|
||||
if (!empty($feed['Feed']['settings']['common']['excluderegex']) && !$this->__checkRegex($feed['Feed']['settings']['common']['excluderegex'])) {
|
||||
$regexErrorMessage = __('Invalid exclude regex. Make sure it\'s a delimited PCRE regex pattern.');
|
||||
if (!$this->_isRest()) {
|
||||
$this->Flash->error($regexErrorMessage);
|
||||
return true;
|
||||
} else {
|
||||
return new CakeResponse(array(
|
||||
'body' => json_encode(array('saved' => false, 'errors' => $regexErrorMessage)),
|
||||
'status' => 200,
|
||||
'type' => 'json'
|
||||
));
|
||||
}
|
||||
}
|
||||
}
|
||||
if (isset($feed['Feed']['settings']['delimiter']) && empty($feed['Feed']['settings']['delimiter'])) {
|
||||
$feed['Feed']['settings']['delimiter'] = ',';
|
||||
}
|
||||
if (empty($feed['Feed']['target_event'])) {
|
||||
$feed['Feed']['target_event'] = 0;
|
||||
}
|
||||
if (empty($feed['Feed']['lookup_visible'])) {
|
||||
$feed['Feed']['lookup_visible'] = 0;
|
||||
}
|
||||
if (empty($feed['Feed']['input_source'])) {
|
||||
$feed['Feed']['input_source'] = 'network';
|
||||
} else {
|
||||
$feed['Feed']['input_source'] = strtolower($feed['Feed']['input_source']);
|
||||
}
|
||||
if (!in_array($feed['Feed']['input_source'], array('network', 'local'))) {
|
||||
$feed['Feed']['input_source'] = 'network';
|
||||
}
|
||||
if (!isset($feed['Feed']['delete_local_file'])) {
|
||||
$feed['Feed']['delete_local_file'] = 0;
|
||||
}
|
||||
$feed['Feed']['settings'] = json_encode($feed['Feed']['settings']);
|
||||
$feed['Feed']['event_id'] = !empty($feed['Feed']['fixed_event']) ? $feed['Feed']['target_event'] : 0;
|
||||
|
||||
return $feed;
|
||||
}
|
||||
];
|
||||
|
||||
$this->CRUD->add($params);
|
||||
if ($this->IndexFilter->isRest()) {
|
||||
return $this->restResponsePayload;
|
||||
}
|
||||
|
||||
$this->loadModel('Event');
|
||||
$sgs = $this->Event->SharingGroup->fetchAllAuthorised($this->Auth->user(), 'name', 1);
|
||||
$sharingGroups = $this->Event->SharingGroup->fetchAllAuthorised($this->Auth->user(), 'name', 1);
|
||||
$distributionLevels = $this->Event->distributionLevels;
|
||||
if (empty($sgs)) {
|
||||
if (empty($sharingGroups)) {
|
||||
unset($distributionLevels[4]);
|
||||
}
|
||||
$this->set('distributionLevels', $distributionLevels);
|
||||
$this->set('sharingGroups', $sgs);
|
||||
$this->set('feed_types', $this->Feed->getFeedTypesOptions());
|
||||
$inputSources = array('network' => 'Network');
|
||||
if (empty(Configure::read('Security.disable_local_feed_access'))) {
|
||||
$inputSources['local'] = 'Local';
|
||||
}
|
||||
$tags = $this->Event->EventTag->Tag->find('list', array('fields' => array('Tag.name'), 'order' => array('lower(Tag.name) asc')));
|
||||
$tags[0] = 'None';
|
||||
$this->set('tags', $tags);
|
||||
$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'])) {
|
||||
$this->request->data['Feed'] = $this->request->data;
|
||||
if (empty($this->request->data['Feed']['source_format'])) {
|
||||
$this->request->data['Feed']['source_format'] = 'freetext';
|
||||
}
|
||||
if (empty($this->request->data['Feed']['fixed_event'])) {
|
||||
$this->request->data['Feed']['source_format'] = 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (!isset($this->request->data['Feed']['fixed_event'])) {
|
||||
$this->request->data['Feed']['fixed_event'] = 1;
|
||||
}
|
||||
$error = false;
|
||||
if (isset($this->request->data['Feed']['pull_rules'])) {
|
||||
$this->request->data['Feed']['rules'] = $this->request->data['Feed']['pull_rules'];
|
||||
}
|
||||
if (!isset($this->request->data['Feed']['distribution'])) {
|
||||
$this->request->data['Feed']['distribution'] = 0;
|
||||
}
|
||||
if ($this->request->data['Feed']['distribution'] != 4) {
|
||||
$this->request->data['Feed']['sharing_group_id'] = 0;
|
||||
}
|
||||
$this->request->data['Feed']['default'] = 0;
|
||||
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'])) {
|
||||
$this->request->data['Feed']['event_id'] = $this->request->data['Feed']['target_event'];
|
||||
}
|
||||
}
|
||||
}
|
||||
if (!isset($this->request->data['Feed']['settings'])) {
|
||||
$this->request->data['Feed']['settings'] = array();
|
||||
} else {
|
||||
if (!empty($this->request->data['Feed']['settings']['common']['excluderegex']) && !$this->__checkRegex($this->request->data['Feed']['settings']['common']['excluderegex'])) {
|
||||
$this->Flash->error('Invalid exclude regex. Make sure it\'s a delimited PCRE regex pattern.');
|
||||
return true;
|
||||
}
|
||||
}
|
||||
if (isset($this->request->data['Feed']['settings']['delimiter']) && empty($this->request->data['Feed']['settings']['delimiter'])) {
|
||||
$this->request->data['Feed']['settings']['delimiter'] = ',';
|
||||
}
|
||||
if (empty($this->request->data['Feed']['target_event'])) {
|
||||
$this->request->data['Feed']['target_event'] = 0;
|
||||
}
|
||||
if (empty($this->request->data['Feed']['lookup_visible'])) {
|
||||
$this->request->data['Feed']['lookup_visible'] = 0;
|
||||
}
|
||||
if (empty($this->request->data['Feed']['input_source'])) {
|
||||
$this->request->data['Feed']['input_source'] = 'network';
|
||||
} else {
|
||||
$this->request->data['Feed']['input_source'] = strtolower($this->request->data['Feed']['input_source']);
|
||||
}
|
||||
if (!in_array($this->request->data['Feed']['input_source'], array('network', 'local'))) {
|
||||
$this->request->data['Feed']['input_source'] = 'network';
|
||||
}
|
||||
if (!isset($this->request->data['Feed']['delete_local_file'])) {
|
||||
$this->request->data['Feed']['delete_local_file'] = 0;
|
||||
}
|
||||
$this->request->data['Feed']['settings'] = json_encode($this->request->data['Feed']['settings']);
|
||||
$this->request->data['Feed']['event_id'] = !empty($this->request->data['Feed']['fixed_event']) ? $this->request->data['Feed']['target_event'] : 0;
|
||||
if (!$error) {
|
||||
$result = $this->Feed->save($this->request->data);
|
||||
if ($result) {
|
||||
$message = __('Feed added.');
|
||||
if ($this->_isRest()) {
|
||||
$feed = $this->Feed->find('first', array('conditions' => array('Feed.id' => $this->Feed->id), 'recursive' => -1));
|
||||
return $this->RestResponse->viewData($feed, $this->response->type());
|
||||
}
|
||||
$this->Flash->success($message);
|
||||
$this->redirect(array('controller' => 'feeds', 'action' => 'index'));
|
||||
} else {
|
||||
$message = __('Feed could not be added. Reason: %s', json_encode($this->Feed->validationErrors));
|
||||
if ($this->_isRest()) {
|
||||
return $this->RestResponse->saveFailResponse('Feeds', 'add', false, $message, $this->response->type());
|
||||
}
|
||||
$this->Flash->error($message);
|
||||
$this->request->data['Feed']['settings'] = json_decode($this->request->data['Feed']['settings'], true);
|
||||
}
|
||||
}
|
||||
} elseif ($this->_isRest()) {
|
||||
return $this->RestResponse->describe('Feeds', 'add', false, $this->response->type());
|
||||
}
|
||||
|
||||
$dropdownData = [
|
||||
'orgs' => $this->Event->Orgc->find('list', array(
|
||||
'fields' => array('id', 'name'),
|
||||
'order' => 'LOWER(name)'
|
||||
)),
|
||||
'tags' => $tags,
|
||||
'feedTypes' => $this->Feed->getFeedTypesOptions(),
|
||||
'sharingGroups' => $sharingGroups,
|
||||
'distributionLevels' => $distributionLevels,
|
||||
'inputSources' => $inputSources
|
||||
];
|
||||
$this->set(compact('dropdownData'));
|
||||
|
||||
$this->set('menuData', array('menuList' => 'feeds', 'menuItem' => 'add'));
|
||||
}
|
||||
|
||||
private function __checkRegex($pattern)
|
||||
{
|
||||
if (@preg_match($pattern, null) === false) {
|
||||
if (@preg_match($pattern, '') === false) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
|
@ -311,141 +320,138 @@ class FeedsController extends AppController
|
|||
|
||||
public function edit($feedId)
|
||||
{
|
||||
$feed = $this->Feed->find('first', [
|
||||
'recursive' => -1,
|
||||
'conditions' => ['id' => $feedId]
|
||||
]);
|
||||
if (empty($feed)) {
|
||||
throw new NotFoundException(__('Invalid feed.'));
|
||||
}
|
||||
$this->set('feed', $feed);
|
||||
$this->loadModel('Event');
|
||||
$sgs = $this->Event->SharingGroup->fetchAllAuthorised($this->Auth->user(), 'name', 1);
|
||||
$distributionLevels = $this->Event->distributionLevels;
|
||||
if (empty($sgs)) {
|
||||
unset($distributionLevels[4]);
|
||||
}
|
||||
$this->set('distributionLevels', $distributionLevels);
|
||||
$this->set('sharingGroups', $sgs);
|
||||
$tags = $this->Event->EventTag->Tag->find('list', array('fields' => array('Tag.name'), 'order' => array('lower(Tag.name) asc')));
|
||||
$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($feed['Feed']['settings'])) {
|
||||
$feed['Feed']['settings'] = json_decode($feed['Feed']['settings'], true);
|
||||
}
|
||||
if ($this->request->is('post') || $this->request->is('put')) {
|
||||
if ($this->_isRest()) {
|
||||
if (empty($this->request->data['Feed'])) {
|
||||
$this->request->data['Feed'] = $this->request->data;
|
||||
$this->CRUD->edit($feedId, [
|
||||
'fields' => [
|
||||
'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'
|
||||
],
|
||||
'beforeSave' => function (array $feed) use ($feedId) {
|
||||
if (!empty($feed['Feed']['settings'])) {
|
||||
$feed['Feed']['settings'] = json_decode($feed['Feed']['settings'], true);
|
||||
}
|
||||
}
|
||||
if (isset($this->request->data['Feed']['pull_rules'])) {
|
||||
$this->request->data['Feed']['rules'] = $this->request->data['Feed']['pull_rules'];
|
||||
}
|
||||
if (isset($this->request->data['Feed']['distribution']) && $this->request->data['Feed']['distribution'] != 4) {
|
||||
$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 (isset($feed['Feed']['pull_rules'])) {
|
||||
$feed['Feed']['rules'] = $feed['Feed']['pull_rules'];
|
||||
}
|
||||
}
|
||||
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'])) {
|
||||
$this->request->data['Feed']['event_id'] = $this->request->data['Feed']['target_event'];
|
||||
} else if (!empty($feed['Feed']['event_id'])) {
|
||||
$this->request->data['Feed']['event_id'] = $feed['Feed']['event_id'];
|
||||
} else {
|
||||
$this->request->data['Feed']['event_id'] = 0;
|
||||
if (isset($feed['Feed']['distribution']) && $feed['Feed']['distribution'] != 4) {
|
||||
$feed['Feed']['sharing_group_id'] = 0;
|
||||
}
|
||||
$feed['Feed']['id'] = $feedId;
|
||||
if (!empty($feed['Feed']['source_format']) && ($feed['Feed']['source_format'] == 'misp')) {
|
||||
if (!empty($feed['Feed']['orgc_id'])) {
|
||||
$feed['Feed']['orgc_id'] = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (!isset($this->request->data['Feed']['settings'])) {
|
||||
if (!empty($feed['Feed']['settings'])) {
|
||||
$this->request->data['Feed']['settings'] = $feed['Feed']['settings'];
|
||||
if (!empty($feed['Feed']['source_format']) && ($feed['Feed']['source_format'] == 'freetext' || $feed['Feed']['source_format'] == 'csv')) {
|
||||
if ($feed['Feed']['fixed_event'] == 1) {
|
||||
if (isset($feed['Feed']['target_event']) && is_numeric($feed['Feed']['target_event'])) {
|
||||
$feed['Feed']['event_id'] = $feed['Feed']['target_event'];
|
||||
} else if (!empty($feed['Feed']['event_id'])) {
|
||||
$feed['Feed']['event_id'] = $feed['Feed']['event_id'];
|
||||
} else {
|
||||
$feed['Feed']['event_id'] = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (!isset($feed['Feed']['settings'])) {
|
||||
if (!empty($feed['Feed']['settings'])) {
|
||||
$feed['Feed']['settings'] = $feed['Feed']['settings'];
|
||||
} else {
|
||||
$feed['Feed']['settings'] = array();
|
||||
}
|
||||
} else {
|
||||
$this->request->data['Feed']['settings'] = array();
|
||||
if (!empty($feed['Feed']['settings']['common']['excluderegex']) && !$this->__checkRegex($feed['Feed']['settings']['common']['excluderegex'])) {
|
||||
$regexErrorMessage = __('Invalid exclude regex. Make sure it\'s a delimited PCRE regex pattern.');
|
||||
if (!$this->_isRest()) {
|
||||
$this->Flash->error($regexErrorMessage);
|
||||
return true;
|
||||
} else {
|
||||
return new CakeResponse(array(
|
||||
'body' => json_encode(array('saved' => false, 'errors' => $regexErrorMessage)),
|
||||
'status' => 200,
|
||||
'type' => 'json'
|
||||
));
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if (!empty($this->request->data['Feed']['settings']['common']['excluderegex']) && !$this->__checkRegex($this->request->data['Feed']['settings']['common']['excluderegex'])) {
|
||||
$this->Flash->error('Invalid exclude regex. Make sure it\'s a delimited PCRE regex pattern.');
|
||||
return true;
|
||||
if (isset($feed['Feed']['settings']['delimiter']) && empty($feed['Feed']['settings']['delimiter'])) {
|
||||
$feed['Feed']['settings']['delimiter'] = ',';
|
||||
}
|
||||
}
|
||||
if (isset($this->request->data['Feed']['settings']['delimiter']) && empty($this->request->data['Feed']['settings']['delimiter'])) {
|
||||
$this->request->data['Feed']['settings']['delimiter'] = ',';
|
||||
}
|
||||
$this->request->data['Feed']['settings'] = json_encode($this->request->data['Feed']['settings']);
|
||||
$fields = array('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');
|
||||
foreach ($fields as $field) {
|
||||
if (isset($this->request->data['Feed'][$field])) {
|
||||
$feed['Feed'][$field] = $this->request->data['Feed'][$field];
|
||||
}
|
||||
}
|
||||
$result = $this->Feed->save($feed);
|
||||
if ($result) {
|
||||
$feedCache = APP . 'tmp' . DS . 'cache' . DS . 'misp_feed_' . intval($feedId) . '.cache';
|
||||
$feed['Feed']['settings'] = json_encode($feed['Feed']['settings']);
|
||||
|
||||
return $feed;
|
||||
},
|
||||
'afterSave' => function (array $feed) {
|
||||
$feedCache = APP . 'tmp' . DS . 'cache' . DS . 'misp_feed_' . intval($feed['Feed']['id']) . '.cache';
|
||||
if (file_exists($feedCache)) {
|
||||
unlink($feedCache);
|
||||
}
|
||||
$message = __('Feed updated.');
|
||||
if ($this->_isRest()) {
|
||||
$feed = $this->Feed->find('first', array('conditions' => array('Feed.id' => $this->Feed->id), 'recursive' => -1));
|
||||
return $this->RestResponse->viewData($feed, $this->response->type());
|
||||
}
|
||||
$this->Flash->success($message);
|
||||
$this->redirect(array('controller' => 'feeds', 'action' => 'index'));
|
||||
} else {
|
||||
$message = __('Feed could not be updated. Reason: %s', json_encode($this->Feed->validationErrors));
|
||||
if ($this->_isRest()) {
|
||||
return $this->RestResponse->saveFailResponse('Feeds', 'edit', false, $message, $this->response->type());
|
||||
}
|
||||
$this->Flash->error($message);
|
||||
return $feed;
|
||||
}
|
||||
} else {
|
||||
if ($this->_isRest()) {
|
||||
return $this->RestResponse->describe('Feeds', 'edit', false, $this->response->type());
|
||||
}
|
||||
if (!isset($this->request->data['Feed'])) {
|
||||
$this->request->data = $feed;
|
||||
if ($feed['Feed']['event_id']) {
|
||||
$this->request->data['Feed']['target_event'] = $feed['Feed']['event_id'];
|
||||
}
|
||||
}
|
||||
$this->request->data['Feed']['pull_rules'] = $this->request->data['Feed']['rules'];
|
||||
]);
|
||||
if ($this->IndexFilter->isRest()) {
|
||||
return $this->restResponsePayload;
|
||||
}
|
||||
|
||||
$this->loadModel('Event');
|
||||
$sharingGroups = $this->Event->SharingGroup->fetchAllAuthorised($this->Auth->user(), 'name', 1);
|
||||
$distributionLevels = $this->Event->distributionLevels;
|
||||
if (empty($sharingGroups)) {
|
||||
unset($distributionLevels[4]);
|
||||
}
|
||||
$inputSources = array('network' => 'Network');
|
||||
if (empty(Configure::read('Security.disable_local_feed_access'))) {
|
||||
$inputSources['local'] = 'Local';
|
||||
}
|
||||
$tags = $this->Event->EventTag->Tag->find('list', array('fields' => array('Tag.name'), 'order' => array('lower(Tag.name) asc')));
|
||||
$tags[0] = 'None';
|
||||
|
||||
$dropdownData = [
|
||||
'orgs' => $this->Event->Orgc->find('list', array(
|
||||
'fields' => array('id', 'name'),
|
||||
'order' => 'LOWER(name)'
|
||||
)),
|
||||
'tags' => $tags,
|
||||
'feedTypes' => $this->Feed->getFeedTypesOptions(),
|
||||
'sharingGroups' => $sharingGroups,
|
||||
'distributionLevels' => $distributionLevels,
|
||||
'inputSources' => $inputSources
|
||||
];
|
||||
$this->set(compact('dropdownData'));
|
||||
$this->set('menuData', [
|
||||
'menuList' => 'feeds',
|
||||
'menuItem' => 'edit',
|
||||
]);
|
||||
|
||||
$this->set('edit', true);
|
||||
$this->render('add');
|
||||
}
|
||||
|
||||
public function delete($feedId)
|
||||
{
|
||||
if (!$this->request->is('post') && !$this->request->is('delete')) {
|
||||
throw new MethodNotAllowedException(__('Action not allowed, post or delete request expected.'));
|
||||
$this->CRUD->delete($feedId);
|
||||
if ($this->IndexFilter->isRest()) {
|
||||
return $this->restResponsePayload;
|
||||
}
|
||||
$this->Feed->id = $feedId;
|
||||
if (!$this->Feed->exists()) {
|
||||
throw new NotFoundException(__('Invalid feed.'));
|
||||
}
|
||||
if ($this->Feed->delete($feedId)) {
|
||||
$message = 'Feed deleted.';
|
||||
if ($this->_isRest()) {
|
||||
return $this->RestResponse->saveSuccessResponse('Feeds', 'delete', $feedId, false, $message);
|
||||
}
|
||||
$this->Flash->success($message);
|
||||
} else {
|
||||
$message = 'Feed could not be deleted.';
|
||||
if ($this->_isRest()) {
|
||||
return $this->RestResponse->saveFailResponse('Feeds', 'delete', false, $message, $this->response->type());
|
||||
}
|
||||
$this->Flash->error($message);
|
||||
}
|
||||
$this->redirect(array('controller' => 'feeds', 'action' => 'index'));
|
||||
}
|
||||
|
||||
public function fetchFromFeed($feedId)
|
||||
|
@ -473,21 +479,21 @@ class FeedsController extends AppController
|
|||
$this->loadModel('Job');
|
||||
$this->Job->create();
|
||||
$data = array(
|
||||
'worker' => 'default',
|
||||
'job_type' => 'fetch_feeds',
|
||||
'job_input' => 'Feed: ' . $feedId,
|
||||
'status' => 0,
|
||||
'retries' => 0,
|
||||
'org' => $this->Auth->user('Organisation')['name'],
|
||||
'message' => __('Starting fetch from Feed.'),
|
||||
'worker' => 'default',
|
||||
'job_type' => 'fetch_feeds',
|
||||
'job_input' => 'Feed: ' . $feedId,
|
||||
'status' => 0,
|
||||
'retries' => 0,
|
||||
'org' => $this->Auth->user('Organisation')['name'],
|
||||
'message' => __('Starting fetch from Feed.'),
|
||||
);
|
||||
$this->Job->save($data);
|
||||
$jobId = $this->Job->id;
|
||||
$process_id = CakeResque::enqueue(
|
||||
'default',
|
||||
'ServerShell',
|
||||
array('fetchFeed', $this->Auth->user('id'), $feedId, $jobId),
|
||||
true
|
||||
'default',
|
||||
'ServerShell',
|
||||
array('fetchFeed', $this->Auth->user('id'), $feedId, $jobId),
|
||||
true
|
||||
);
|
||||
$this->Job->saveField('process_id', $process_id);
|
||||
$message = __('Pull queued for background execution.');
|
||||
|
@ -869,8 +875,8 @@ class FeedsController extends AppController
|
|||
throw new MethodNotAllowedException(__('Invalid Feed.'));
|
||||
}
|
||||
$feed = $this->Feed->find('first', array(
|
||||
'conditions' => array('Feed.id' => $id),
|
||||
'recursive' => -1
|
||||
'conditions' => array('Feed.id' => $id),
|
||||
'recursive' => -1
|
||||
));
|
||||
$feed['Feed']['enabled'] = $enable;
|
||||
$result = array('result' => $this->Feed->save($feed));
|
||||
|
@ -913,21 +919,21 @@ class FeedsController extends AppController
|
|||
$this->loadModel('Job');
|
||||
$this->Job->create();
|
||||
$data = array(
|
||||
'worker' => 'default',
|
||||
'job_type' => 'cache_feeds',
|
||||
'job_input' => $scope,
|
||||
'status' => 0,
|
||||
'retries' => 0,
|
||||
'org' => $this->Auth->user('Organisation')['name'],
|
||||
'message' => __('Starting feed caching.'),
|
||||
'worker' => 'default',
|
||||
'job_type' => 'cache_feeds',
|
||||
'job_input' => $scope,
|
||||
'status' => 0,
|
||||
'retries' => 0,
|
||||
'org' => $this->Auth->user('Organisation')['name'],
|
||||
'message' => __('Starting feed caching.'),
|
||||
);
|
||||
$this->Job->save($data);
|
||||
$jobId = $this->Job->id;
|
||||
$process_id = CakeResque::enqueue(
|
||||
'default',
|
||||
'ServerShell',
|
||||
array('cacheFeed', $this->Auth->user('id'), $scope, $jobId),
|
||||
true
|
||||
'default',
|
||||
'ServerShell',
|
||||
array('cacheFeed', $this->Auth->user('id'), $scope, $jobId),
|
||||
true
|
||||
);
|
||||
$this->Job->saveField('process_id', $process_id);
|
||||
$message = 'Feed caching job initiated.';
|
||||
|
|
|
@ -1,296 +1,83 @@
|
|||
<div class="feed form">
|
||||
<?php echo $this->Form->create('Feed');?>
|
||||
<fieldset>
|
||||
<legend><?php echo __('Add MISP Feed');?></legend>
|
||||
<?php
|
||||
if (!empty(Configure::read('Security.disable_local_feed_access'))) {
|
||||
echo sprintf(
|
||||
'<p class="red bold">%s</p>',
|
||||
__('Warning: local feeds are currently disabled by policy, to re-enable the feature, set the Security.allow_local_feed_access flag in the server settings. This setting can only be set via the CLI.')
|
||||
);
|
||||
}
|
||||
echo '<p>' . __('Add a new MISP feed source.') . '</p>';
|
||||
echo $this->Form->input('enabled', array());
|
||||
echo $this->Form->input('caching_enabled', array('label' => __('Caching enabled')));
|
||||
?>
|
||||
<div class="input clear"></div>
|
||||
<?php
|
||||
echo $this->Form->input('lookup_visible', array('label' => __('Lookup visible')));
|
||||
echo $this->Form->input('name', array(
|
||||
'div' => 'input clear',
|
||||
'placeholder' => __('Feed name'),
|
||||
'class' => 'form-control span6',
|
||||
));
|
||||
echo $this->Form->input('provider', array(
|
||||
'div' => 'input clear',
|
||||
'label' => __('Provider'),
|
||||
'placeholder' => __('Name of the content provider'),
|
||||
'class' => 'form-control span6'
|
||||
));
|
||||
$options = array('network' => 'Network');
|
||||
if (empty(Configure::read('Security.disable_local_feed_access'))) {
|
||||
$options['local'] = 'Local';
|
||||
}
|
||||
echo $this->Form->input('input_source', array(
|
||||
'label' => __('Input Source'),
|
||||
'div' => 'input clear',
|
||||
'options' => $options,
|
||||
'class' => 'form-control span6'
|
||||
));
|
||||
?>
|
||||
<div class="input clear"></div>
|
||||
<div id="DeleteLocalFileDiv" class="optionalField">
|
||||
<?php
|
||||
echo $this->Form->input('delete_local_file', array(
|
||||
'label' => __('Remove input after ingestion')
|
||||
));
|
||||
?>
|
||||
</div>
|
||||
<div class="input clear"></div>
|
||||
<?php
|
||||
echo $this->Form->input('url', array(
|
||||
'div' => 'input clear',
|
||||
'label' => __('URL'),
|
||||
'placeholder' => __('URL of the feed'),
|
||||
'class' => 'form-control span6'
|
||||
));
|
||||
echo $this->Form->input('source_format', array(
|
||||
'label' => __('Source Format'),
|
||||
'div' => 'input clear',
|
||||
'options' => $feed_types,
|
||||
'class' => 'form-control span6'
|
||||
));
|
||||
?>
|
||||
<div id="HeadersDiv">
|
||||
<?php
|
||||
echo $this->Form->input('headers', array(
|
||||
'label' => __('Any headers to be passed with requests (for example: Authorization)'),
|
||||
'div' => 'clear',
|
||||
'class' => 'input-xxlarge',
|
||||
'type' => 'textarea',
|
||||
'placeholder' => __('Line break separated list of headers in the "headername: value" format')
|
||||
));
|
||||
?>
|
||||
<div>
|
||||
<span id="basicAuthFormEnable" class="btn btn-inverse quick-popover" style="line-height:10px; padding: 4px 4px;"><?php echo __('Add Basic Auth');?></span>
|
||||
<div id="basicAuthForm" class="quick-form" style="display:none;">
|
||||
<fieldset>
|
||||
<div class="input">
|
||||
<label for="BasicAuthUsername"><?php echo __('Username');?></label>
|
||||
<input class="form-control" type="text" id="BasicAuthUsername"><br />
|
||||
</div>
|
||||
<div class="input">
|
||||
<label for ="BasicAuthPassword"><?php echo __('Password');?></label>
|
||||
<input class="form-control" type="text" id="BasicAuthPassword"><br />
|
||||
</div>
|
||||
</fieldset>
|
||||
<span class="btn-inverse btn" onClick="add_basic_auth();" style="line-height:10px; padding: 4px 4px;"><?php echo __('Add basic auth header'); ?></span>
|
||||
</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(
|
||||
'label' => __('Target Event'),
|
||||
'div' => 'input clear',
|
||||
'options' => array('New Event Each Pull', 'Fixed Event'),
|
||||
'class' => 'form-control span6'
|
||||
));
|
||||
?>
|
||||
</div>
|
||||
<div id="TargetEventDiv" class="optionalField">
|
||||
<?php
|
||||
echo $this->Form->input('target_event', array(
|
||||
'label' => __('Target Event ID'),
|
||||
'div' => 'input clear',
|
||||
'placeholder' => __('Leave blank unless you want to reuse an existing event.'),
|
||||
'class' => 'form-control span6'
|
||||
));
|
||||
?>
|
||||
</div>
|
||||
<div id="settingsCsvValueDiv" class="optionalField">
|
||||
<?php
|
||||
echo $this->Form->input('Feed.settings.csv.value', array(
|
||||
'label' => __('Value field(s) in the CSV'),
|
||||
'title' => __('Select one or several fields that should be parsed by the CSV parser and converted into MISP attributes'),
|
||||
'div' => 'input clear',
|
||||
'placeholder' => __('2,3,4 (column position separated by commas)'),
|
||||
'class' => 'form-control span6'
|
||||
));
|
||||
?>
|
||||
</div>
|
||||
<div id="settingsCsvDelimiterDiv" class="optionalField">
|
||||
<?php
|
||||
echo $this->Form->input('Feed.settings.csv.delimiter', array(
|
||||
'label' => __('Delimiter'),
|
||||
'title' => __('Set the default CSV delimiter (default = ",")'),
|
||||
'div' => 'input clear',
|
||||
'placeholder' => ',',
|
||||
'class' => 'form-control span6',
|
||||
'value' => isset($this->request->data['Feed']['settings']['csv']['delimiter']) ? $this->request->data['Feed']['settings']['csv']['delimiter'] : ','
|
||||
));
|
||||
?>
|
||||
</div>
|
||||
<div id="settingsCommonExcluderegexDiv" class="optionalField">
|
||||
<?php
|
||||
echo $this->Form->input('Feed.settings.common.excluderegex', array(
|
||||
'label' => __('Exclusion Regex'),
|
||||
'title' => __('Add a regex pattern for detecting iocs that should be skipped (this can be useful to exclude any references to the actual report / feed for example)'),
|
||||
'div' => 'input clear',
|
||||
'placeholder' => __('Regex pattern, for example: "/^https://myfeedurl/i'),
|
||||
'class' => 'form-control span6'
|
||||
));
|
||||
?>
|
||||
</div>
|
||||
<div id="PublishDiv" class="input clear optionalField">
|
||||
<?php
|
||||
echo $this->Form->input('publish', array(
|
||||
'label' => __('Auto Publish'),
|
||||
'title' => __('Publish events directly after pulling the feed - if you would like to review the event before publishing uncheck this'),
|
||||
'type' => 'checkbox',
|
||||
'class' => 'form-control'
|
||||
));
|
||||
?>
|
||||
</div>
|
||||
<div id="OverrideIdsDiv" class="input clear optionalField">
|
||||
<?php
|
||||
echo $this->Form->input('override_ids', array(
|
||||
'label' => __('Override IDS Flag'),
|
||||
'title' => __('If checked, the IDS flags will always be set to off when pulling from this feed'),
|
||||
'type' => 'checkbox',
|
||||
'class' => 'form-control'
|
||||
));
|
||||
?>
|
||||
</div>
|
||||
<div id="DeltaMergeDiv" class="input clear optionalField">
|
||||
<?php
|
||||
echo $this->Form->input('delta_merge', array(
|
||||
'label' => __('Delta Merge'),
|
||||
'title' => __('Merge attributes (only add new attributes, remove revoked attributes)'),
|
||||
'type' => 'checkbox',
|
||||
'class' => 'form-control'
|
||||
));
|
||||
?>
|
||||
</div>
|
||||
<?php
|
||||
echo $this->Form->input('distribution', array(
|
||||
'options' => array($distributionLevels),
|
||||
'div' => 'input clear',
|
||||
'label' => __('Distribution'),
|
||||
'selected' => isset($this->request->data['Feed']['distribution']) ? $this->request->data['Feed']['distribution'] : 3,
|
||||
));
|
||||
?>
|
||||
<div id="SGContainer" style="display:none;">
|
||||
<?php
|
||||
if (!empty($sharingGroups)) {
|
||||
echo $this->Form->input('sharing_group_id', array(
|
||||
'options' => array($sharingGroups),
|
||||
'label' => __('Sharing Group'),
|
||||
));
|
||||
}
|
||||
?>
|
||||
</div>
|
||||
<div class="input clear"></div>
|
||||
<?php
|
||||
echo $this->Form->input('tag_id', array(
|
||||
'options' => $tags,
|
||||
'label' => __('Default Tag'),
|
||||
'selected' => isset($this->request->data['Feed']['tag_id']) ? $this->request->data['Feed']['tag_id'] : 0,
|
||||
));
|
||||
echo $this->Form->input('pull_rules', array('style' => 'display:none;', 'label' => false, 'div' => false));
|
||||
?>
|
||||
</fieldset>
|
||||
<b><?php echo __('Filter rules');?>:</b><br />
|
||||
<span id="pull_tags_OR" style="display:none;"><?php echo __('Events with the following tags allowed');?>: <span id="pull_tags_OR_text" style="color:green;"></span><br /></span>
|
||||
<span id="pull_tags_NOT" style="display:none;"><?php echo __('Events with the following tags blocked');?>: <span id="pull_tags_NOT_text" style="color:red;"></span><br /></span>
|
||||
<span id="pull_orgs_OR" style="display:none;"><?php echo __('Events with the following organisations allowed');?>: <span id="pull_orgs_OR_text" style="color:green;"></span><br /></span>
|
||||
<span id="pull_orgs_NOT" style="display:none;"><?php echo __('Events with the following organisations blocked');?>: <span id="pull_orgs_NOT_text" style="color:red;"></span><br /></span>
|
||||
<span id="pull_modify" class="btn btn-inverse" style="line-height:10px; padding: 4px 4px;"><?php echo __('Modify');?></span><br /><br />
|
||||
<?php
|
||||
echo $this->Form->button(__('Add'), array('class' => 'btn btn-primary'));
|
||||
echo $this->Form->end();
|
||||
?>
|
||||
<div id="hiddenRuleForms">
|
||||
<?php
|
||||
$modalData = [
|
||||
'data' => [
|
||||
'title' => __('Set PULL rules'),
|
||||
'content' => [
|
||||
[
|
||||
'html' => sprintf('<h5 style="font-weight: normal;"><i>%s</i></h5>', __('Configure the rules to be applied when PULLing data to the server'))
|
||||
],
|
||||
[
|
||||
'html' => $this->element('serverRuleElements/pull', [
|
||||
'context' => 'feeds',
|
||||
'allTags' => $tags,
|
||||
'allOrganisations' => $orgs,
|
||||
])
|
||||
]
|
||||
],
|
||||
],
|
||||
'type' => 'xl',
|
||||
'class' => 'pull-rule-modal',
|
||||
'confirm' => [
|
||||
'title' => __('Update'),
|
||||
'onclick' => "serverRulesUpdateState('pull');"
|
||||
]
|
||||
];
|
||||
echo $this->element('genericElements/infoModal', $modalData);
|
||||
?>
|
||||
</div>
|
||||
</div>
|
||||
<?php
|
||||
echo $this->element('/genericElements/SideMenu/side_menu', array('menuList' => 'feeds', 'menuItem' => 'add'));
|
||||
?>
|
||||
<script type="text/javascript">
|
||||
|
||||
var rules = {"pull": {"tags": {"OR":[], "NOT":[]}, "orgs": {"OR":[], "NOT":[]}}};
|
||||
var validOptions = ['pull'];
|
||||
var validFields = ['tags', 'orgs'];
|
||||
var modelContext = 'Feed';
|
||||
|
||||
$(document).ready(function() {
|
||||
feedDistributionChange();
|
||||
$("#pull_modify").click(function() {
|
||||
$('#genericModal.pull-rule-modal').modal()
|
||||
.on('shown', function () {
|
||||
var $containers = $(this).find('.rules-widget-container')
|
||||
$containers.each(function() {
|
||||
var initFun = $(this).data('funname');
|
||||
if (typeof window[initFun] === 'function') {
|
||||
window[initFun]()
|
||||
}
|
||||
})
|
||||
})
|
||||
.on('hidden', function () {
|
||||
var $containers = $(this).find('.rules-widget-container')
|
||||
$containers.each(function() {
|
||||
if ($(this).data('resetrulesfun') !== undefined) {
|
||||
$(this).data('resetrulesfun')()
|
||||
}
|
||||
})
|
||||
});
|
||||
});
|
||||
$("#FeedDistribution").change(function() {
|
||||
feedDistributionChange();
|
||||
});
|
||||
feedFormUpdate();
|
||||
$('#basicAuthFormEnable').click(function() {
|
||||
$('#basicAuthFormEnable').hide();
|
||||
$('#basicAuthForm').show();
|
||||
})
|
||||
});
|
||||
$("#FeedSourceFormat, #FeedFixedEvent, #FeedInputSource").change(function() {
|
||||
feedFormUpdate();
|
||||
});
|
||||
</script>
|
||||
echo $this->element('genericElements/Form/genericForm', [
|
||||
'data' => [
|
||||
'title' => isset($edit) ? __('Edit MISP feed') : __('Add MISP feed'),
|
||||
'description' => __('Add a new MISP feed source.'),
|
||||
'fields' => [
|
||||
[
|
||||
'field' => 'enabled',
|
||||
'label' => __('Enabled'),
|
||||
'type' => 'checkbox'
|
||||
],
|
||||
[
|
||||
'field' => 'caching_enabled',
|
||||
'label' => __('Caching enabled'),
|
||||
'type' => 'checkbox'
|
||||
],
|
||||
[
|
||||
'field' => 'lookup_visible',
|
||||
'label' => __('Lookup visible'),
|
||||
'type' => 'checkbox'
|
||||
],
|
||||
[
|
||||
'field' => 'name',
|
||||
'label' => __('Name'),
|
||||
'placeholder' => 'Feed name',
|
||||
'required' => 1
|
||||
],
|
||||
[
|
||||
'field' => 'provider',
|
||||
'label' => __('Provider'),
|
||||
'placeholder' => 'Name of the content provider',
|
||||
'required' => 1
|
||||
],
|
||||
[
|
||||
'field' => 'input_source',
|
||||
'label' => __('Input Source'),
|
||||
'options' => $dropdownData['inputSources'],
|
||||
'type' => 'dropdown'
|
||||
],
|
||||
[
|
||||
'field' => 'url',
|
||||
'label' => __('URL'),
|
||||
'placeholder' => 'URL of the feed',
|
||||
'required' => 1
|
||||
],
|
||||
[
|
||||
'field' => 'source_format',
|
||||
'label' => __('Source Format'),
|
||||
'options' => $dropdownData['feedTypes'],
|
||||
'type' => 'dropdown'
|
||||
],
|
||||
[
|
||||
'field' => 'headers',
|
||||
'label' => __('Any headers to be passed with requests (for example: Authorization)'),
|
||||
'class' => 'span6',
|
||||
'placeholder' => 'Line break separated list of headers in the "headername: value" format',
|
||||
'rows' => 4,
|
||||
],
|
||||
[
|
||||
'field' => 'distribution',
|
||||
'label' => __('Distribution'),
|
||||
'options' => $dropdownData['distributionLevels'],
|
||||
'selected' => isset($feed['Feed']['distribution']) ? $feed['Feed']['distribution'] : 3,
|
||||
'type' => 'dropdown'
|
||||
],
|
||||
[
|
||||
'field' => 'tag_id',
|
||||
'label' => __('Default Tag'),
|
||||
'options' => $dropdownData['tags'],
|
||||
'selected' => isset($feed['Feed']['tag_id']) ? $feed['Feed']['tag_id'] : 0,
|
||||
'type' => 'dropdown',
|
||||
'searchable' => 1
|
||||
],
|
||||
],
|
||||
'submit' => [
|
||||
'action' => $this->request->params['action'],
|
||||
'ajaxSubmit' => 'submitGenericFormInPlace();'
|
||||
]
|
||||
]
|
||||
]);
|
||||
if (!$ajax) {
|
||||
echo $this->element('/genericElements/SideMenu/side_menu', $menuData);
|
||||
}
|
||||
|
|
|
@ -1,321 +0,0 @@
|
|||
<div class="feed form">
|
||||
<?php echo $this->Form->create('Feed');?>
|
||||
<fieldset>
|
||||
<legend><?php echo __('Edit MISP Feed');?></legend>
|
||||
<?php
|
||||
if (!empty(Configure::read('Security.disable_local_feed_access'))) {
|
||||
echo sprintf(
|
||||
'<p class="red bold">%s</p>',
|
||||
__('Warning: local feeds are currently disabled by policy, to re-enable the feature, set the Security.allow_local_feed_access flag in the server settings. This setting can only be set via the CLI.')
|
||||
);
|
||||
}
|
||||
echo '<p>' . __('Edit a new MISP feed source.') . '</p>';
|
||||
echo $this->Form->input('enabled', array(
|
||||
'type' => 'checkbox'
|
||||
));
|
||||
echo $this->Form->input('caching_enabled', array(
|
||||
'type' => 'checkbox'
|
||||
));
|
||||
?>
|
||||
<div class="input clear"></div>
|
||||
<?php
|
||||
echo $this->Form->input('lookup_visible', array(
|
||||
'type' => 'checkbox'
|
||||
));
|
||||
echo $this->Form->input('name', array(
|
||||
'div' => 'input clear',
|
||||
'placeholder' => __('Feed name'),
|
||||
'class' => 'form-control span6',
|
||||
));
|
||||
echo $this->Form->input('provider', array(
|
||||
'div' => 'input clear',
|
||||
'placeholder' => __('Name of the content provider'),
|
||||
'class' => 'form-control span6'
|
||||
));
|
||||
$options = array('network' => 'Network');
|
||||
if (empty(Configure::read('Security.disable_local_feed_access'))) {
|
||||
$options['local'] = 'Local';
|
||||
}
|
||||
echo $this->Form->input('input_source', array(
|
||||
'div' => 'input clear',
|
||||
'options' => $options,
|
||||
'class' => 'form-control span6'
|
||||
));
|
||||
?>
|
||||
<div id="HeadersDiv"<?php echo $this->request->data['Feed']['input_source'] == 'file' ? 'style="display:none;"' : '';?>>
|
||||
<?php
|
||||
echo $this->Form->input('headers', array(
|
||||
'label' => __('Any headers to be passed with requests (for example: Authorization)'),
|
||||
'div' => 'clear',
|
||||
'class' => 'input-xxlarge',
|
||||
'type' => 'textarea',
|
||||
'placeholder' => __('Line break separated list of headers in the "headername: value" format')
|
||||
));
|
||||
?>
|
||||
<div>
|
||||
<span id="basicAuthFormEnable" class="btn btn-inverse quick-popover" style="line-height:10px; padding: 4px 4px;"><?php echo __('Add Basic Auth');?></span>
|
||||
<div id="basicAuthForm" class="quick-form" style="display:none;">
|
||||
<fieldset>
|
||||
<div class="input">
|
||||
<label for="BasicAuthUsername"><?php echo __('Username');?></label>
|
||||
<input class="form-control" type="text" id="BasicAuthUsername"><br />
|
||||
</div>
|
||||
<div class="input">
|
||||
<label for ="BasicAuthPassword"><?php echo __('Password');?></label>
|
||||
<input class="form-control" type="text" id="BasicAuthPassword"><br />
|
||||
</div>
|
||||
</fieldset>
|
||||
<span class="btn-inverse btn" onClick="add_basic_auth();" style="line-height:10px; padding: 4px 4px;"><?php echo __('Add basic auth header'); ?></span>
|
||||
</div>
|
||||
</div><br />
|
||||
</div>
|
||||
<div class="input clear"></div>
|
||||
<div id="DeleteLocalFileDiv" class="optionalField">
|
||||
<?php
|
||||
echo $this->Form->input('delete_local_file', array(
|
||||
'label' => __('Remove input after ingestion')
|
||||
));
|
||||
?>
|
||||
</div>
|
||||
<div class="input clear"></div>
|
||||
<?php
|
||||
echo $this->Form->input('url', array(
|
||||
'div' => 'input clear',
|
||||
'label' => __('URL'),
|
||||
'placeholder' => __('URL of the feed'),
|
||||
'class' => 'form-control span6'
|
||||
));
|
||||
echo $this->Form->input('source_format', array(
|
||||
'label' => __('Source Format'),
|
||||
'div' => 'input clear',
|
||||
'options' => $feed_types,
|
||||
'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(
|
||||
'label' => __('Target Event'),
|
||||
'div' => 'input clear',
|
||||
'options' => array('New Event Each Pull', 'Fixed Event'),
|
||||
'class' => 'form-control span6'
|
||||
));
|
||||
?>
|
||||
</div>
|
||||
<div id="TargetEventDiv" class="optionalField">
|
||||
<?php
|
||||
echo $this->Form->input('target_event', array(
|
||||
'label' => __('Target Event ID'),
|
||||
'div' => 'input clear',
|
||||
'placeholder' => __('Leave blank unless you want to reuse an existing event.'),
|
||||
'class' => 'form-control span6'
|
||||
));
|
||||
?>
|
||||
</div>
|
||||
<div id="settingsCsvValueDiv" class="optionalField">
|
||||
<?php
|
||||
echo $this->Form->input('Feed.settings.csv.value', array(
|
||||
'label' => __('Value field(s) in the CSV'),
|
||||
'title' => __('Select one or several fields that should be parsed by the CSV parser and converted into MISP attributes'),
|
||||
'div' => 'input clear',
|
||||
'placeholder' => __('2,3,4 (column position separated by commas)'),
|
||||
'class' => 'form-control span6'
|
||||
));
|
||||
?>
|
||||
</div>
|
||||
<div id="settingsCsvDelimiterDiv" class="optionalField">
|
||||
<?php
|
||||
echo $this->Form->input('Feed.settings.csv.delimiter', array(
|
||||
'label' => __('Delimiter'),
|
||||
'title' => __('Set the default CSV delimiter (default = ",")'),
|
||||
'div' => 'input clear',
|
||||
'placeholder' => ',',
|
||||
'class' => 'form-control span6'
|
||||
));
|
||||
?>
|
||||
</div>
|
||||
<div id="settingsCommonExcluderegexDiv" class="optionalField">
|
||||
<?php
|
||||
echo $this->Form->input('Feed.settings.common.excluderegex', array(
|
||||
'label' => __('Exclusion Regex'),
|
||||
'title' => __('Add a regex pattern for detecting iocs that should be skipped (this can be useful to exclude any references to the actual report / feed for example)'),
|
||||
'div' => 'input clear',
|
||||
'placeholder' => __('Regex pattern, for example: "/^https://myfeedurl/i"'),
|
||||
'class' => 'form-control span6'
|
||||
));
|
||||
?>
|
||||
</div>
|
||||
<div id="PublishDiv" class="input clear optionalField">
|
||||
<?php
|
||||
echo $this->Form->input('publish', array(
|
||||
'label' => __('Auto Publish'),
|
||||
'type' => 'checkbox',
|
||||
'class' => 'form-control'
|
||||
));
|
||||
?>
|
||||
</div>
|
||||
<div id="OverrideIdsDiv" class="input clear optionalField">
|
||||
<?php
|
||||
echo $this->Form->input('override_ids', array(
|
||||
'label' => __('Override IDS Flag'),
|
||||
'title' => __('If checked, the IDS flags will always be set to off when pulling from this feed'),
|
||||
'type' => 'checkbox',
|
||||
'class' => 'form-control'
|
||||
));
|
||||
?>
|
||||
</div>
|
||||
<div id="DeltaMergeDiv" class="input clear optionalField">
|
||||
<?php
|
||||
echo $this->Form->input('delta_merge', array(
|
||||
'label' => __('Delta Merge'),
|
||||
'title' => __('Merge attributes (only add new attributes, remove revoked attributes)'),
|
||||
'type' => 'checkbox',
|
||||
'class' => 'form-control'
|
||||
));
|
||||
?>
|
||||
</div>
|
||||
<?php
|
||||
echo $this->Form->input('distribution', array(
|
||||
'options' => array($distributionLevels),
|
||||
'div' => 'input clear',
|
||||
'label' => __('Distribution'),
|
||||
));
|
||||
?>
|
||||
<div id="SGContainer" style="display:none;">
|
||||
<?php
|
||||
if (!empty($sharingGroups)) {
|
||||
echo $this->Form->input('sharing_group_id', array(
|
||||
'options' => array($sharingGroups),
|
||||
'label' => __('Sharing Group'),
|
||||
));
|
||||
}
|
||||
?>
|
||||
</div>
|
||||
<div class="input clear"></div>
|
||||
<?php
|
||||
echo $this->Form->input('tag_id', array(
|
||||
'options' => $tags,
|
||||
'label' => __('Default Tag'),
|
||||
));
|
||||
echo $this->Form->input('pull_rules', array('style' => 'display:none;', 'label' => false, 'div' => false));
|
||||
?>
|
||||
</fieldset>
|
||||
<b><?php echo __('Filter rules');?>:</b><br />
|
||||
<span id="pull_tags_OR" style="display:none;"><?php echo __('Events with the following tags allowed');?>: <span id="pull_tags_OR_text" style="color:green;"></span><br /></span>
|
||||
<span id="pull_tags_NOT" style="display:none;"><?php echo __('Events with the following tags blocked');?>: <span id="pull_tags_NOT_text" style="color:red;"></span><br /></span>
|
||||
<span id="pull_orgs_OR" style="display:none;"><?php echo __('Events with the following organisations allowed');?>: <span id="pull_orgs_OR_text" style="color:green;"></span><br /></span>
|
||||
<span id="pull_orgs_NOT" style="display:none;"><?php echo __('Events with the following organisations blocked');?>: <span id="pull_orgs_NOT_text" style="color:red;"></span><br /></span>
|
||||
<span id="pull_url_params" style="display:none;"><?php echo __('Additional parameters: ');?><span id="pull_url_params_text" style="color:green;"></span><br /></span>
|
||||
<span id="pull_modify" class="btn btn-inverse" style="line-height:10px; padding: 4px 4px;"><?php echo __('Modify');?></span><br /><br />
|
||||
<?php
|
||||
echo $this->Form->button(__('Edit'), array('class' => 'btn btn-primary'));
|
||||
echo $this->Form->end();
|
||||
?>
|
||||
<div id="hiddenRuleForms">
|
||||
<?php
|
||||
$pullRules = json_decode($feed['Feed']['rules'], true);
|
||||
$pullRules['url_params'] = json_decode($pullRules['url_params'], true);
|
||||
$modalData = [
|
||||
'data' => [
|
||||
'title' => __('Set PULL rules'),
|
||||
'content' => [
|
||||
[
|
||||
'html' => sprintf('<h5 style="font-weight: normal;"><i>%s</i></h5>', __('Configure the rules to be applied when PULLing data from the server'))
|
||||
],
|
||||
[
|
||||
'html' => $this->element('serverRuleElements/pull', [
|
||||
'context' => 'feeds',
|
||||
'allTags' => $tags,
|
||||
'allOrganisations' => $orgs,
|
||||
'ruleObject' => $pullRules
|
||||
])
|
||||
]
|
||||
],
|
||||
],
|
||||
'type' => 'xl',
|
||||
'class' => 'pull-rule-modal',
|
||||
'confirm' => [
|
||||
'title' => __('Update'),
|
||||
'onclick' => "serverRulesUpdateState('pull');"
|
||||
]
|
||||
];
|
||||
echo $this->element('genericElements/infoModal', $modalData);
|
||||
?>
|
||||
</div>
|
||||
</div>
|
||||
<?php
|
||||
echo $this->element('/genericElements/SideMenu/side_menu', array('menuList' => 'feeds', 'menuItem' => 'edit'));
|
||||
?>
|
||||
<script type="text/javascript">
|
||||
//
|
||||
var formInfoValues = {
|
||||
'ServerUrl' : "<?php echo __('The base-url to the external server you want to sync with. Example: https://misppriv.circl.lu');?>",
|
||||
'ServerName' : "<?php echo __('A name that will make it clear to your users what this instance is. For example: Organisation A\'s instance');?>",
|
||||
'ServerOrganization' : "<?php echo __('The organization having the external server you want to sync with. Example: BE');?>",
|
||||
'ServerAuthkey' : "<?php echo __('You can find the authentication key on your profile on the external server.');?>",
|
||||
'ServerPush' : "<?php echo __('Allow the upload of events and their attributes.');?>",
|
||||
'ServerPull' : "<?php echo __('Allow the download of events and their attributes from the server.');?>",
|
||||
'ServerUnpublishEvent' : '<?php echo __('Unpublish new event (working with Push event).');?>',
|
||||
'ServerPublishWithoutEmail' : '<?php echo __('Publish new event without email (working with Pull event).');?>',
|
||||
'ServerSubmittedCert' : "<?php echo __('You can also upload a certificate file if the instance you are trying to connect to has its own signing authority.');?>",
|
||||
'ServerSelfSigned' : "<?php echo __('Click this, if you would like to allow a connection despite the other instance using a self-signed certificate (not recommended).');?>"
|
||||
};
|
||||
|
||||
|
||||
var rules = {"pull": {"tags": {"OR":[], "NOT":[]}, "orgs": {"OR":[], "NOT":[]}}};
|
||||
var validOptions = ['pull'];
|
||||
var validFields = ['tags', 'orgs'];
|
||||
var modelContext = 'Feed';
|
||||
var tags = [];
|
||||
var orgs = [];
|
||||
|
||||
$(document).ready(function() {
|
||||
rules = convertServerFilterRules(rules);
|
||||
feedDistributionChange();
|
||||
$("#pull_modify").click(function() {
|
||||
$('#genericModal.pull-rule-modal').modal()
|
||||
.on('shown', function () {
|
||||
var $containers = $(this).find('.rules-widget-container')
|
||||
$containers.each(function() {
|
||||
var initFun = $(this).data('funname');
|
||||
if (typeof window[initFun] === 'function') {
|
||||
window[initFun]()
|
||||
}
|
||||
})
|
||||
if (typeof window['cm'] === "object") {
|
||||
window['cm'].refresh()
|
||||
}
|
||||
})
|
||||
.on('hidden', function () {
|
||||
var $containers = $(this).find('.rules-widget-container')
|
||||
$containers.each(function() {
|
||||
if ($(this).data('resetrulesfun') !== undefined) {
|
||||
$(this).data('resetrulesfun')()
|
||||
}
|
||||
})
|
||||
});
|
||||
});
|
||||
$("#FeedDistribution").change(function() {
|
||||
feedDistributionChange();
|
||||
});
|
||||
$('#basicAuthFormEnable').click(function() {
|
||||
$('#basicAuthFormEnable').hide();
|
||||
$('#basicAuthForm').show();
|
||||
})
|
||||
feedFormUpdate();
|
||||
});
|
||||
|
||||
$("#FeedSourceFormat, #FeedFixedEvent, #FeedInputSource").change(function() {
|
||||
feedFormUpdate();
|
||||
});
|
||||
</script>
|
|
@ -2,7 +2,7 @@
|
|||
echo '<div class="index">';
|
||||
echo $this->element('/genericElements/IndexTable/index_table', array(
|
||||
'data' => array(
|
||||
'data' => $feeds,
|
||||
'data' => $data,
|
||||
'primary_id_path' => 'Feed.id',
|
||||
'top_bar' => array(
|
||||
'children' => array(
|
||||
|
@ -67,7 +67,7 @@
|
|||
'button' => __('Filter'),
|
||||
'placeholder' => __('Enter value to search'),
|
||||
'data' => '',
|
||||
'searchKey' => 'value'
|
||||
'searchKey' => 'quickFilter'
|
||||
)
|
||||
)
|
||||
),
|
||||
|
|
|
@ -1,17 +1,17 @@
|
|||
<?php
|
||||
$table_data = array();
|
||||
$table_data[] = array('key' => __('ID'), 'value' => $feed['Feed']['id']);
|
||||
$table_data[] = array('key' => __('Name'), 'value' => $feed['Feed']['name']);
|
||||
$table_data[] = array('key' => __('URL'), 'value' => $feed['Feed']['url']);
|
||||
$table_data[] = array('key' => __('ID'), 'value' => $data['Feed']['id']);
|
||||
$table_data[] = array('key' => __('Name'), 'value' => $data['Feed']['name']);
|
||||
$table_data[] = array('key' => __('URL'), 'value' => $data['Feed']['url']);
|
||||
$table_data[] = array(
|
||||
'key' => __('Source format'),
|
||||
'html' => $feed['Feed']['source_format'] !== 'misp' ? h($feed['Feed']['source_format']) : sprintf(
|
||||
'html' => $data['Feed']['source_format'] !== 'misp' ? h($data['Feed']['source_format']) : sprintf(
|
||||
'%s%s',
|
||||
'<span class="blue bold">M</span>',
|
||||
'<span class="black bold">ISP</span>'
|
||||
)
|
||||
);
|
||||
if (!empty($feed['Tag']['id'])) {
|
||||
if (!empty($data['Tag']['id'])) {
|
||||
$table_data[] = array(
|
||||
'key' => __('Tags'),
|
||||
'html' => sprintf(
|
||||
|
@ -20,7 +20,7 @@
|
|||
'ajaxTags',
|
||||
array(
|
||||
'scope' => 'feed',
|
||||
'tags' => array(array('Tag' => $feed['Tag'])),
|
||||
'tags' => array(array('Tag' => $data['Tag'])),
|
||||
'tagAccess' => false,
|
||||
'localTagAccess' => false,
|
||||
'static_tags_only' => true
|
||||
|
@ -29,8 +29,8 @@
|
|||
)
|
||||
);
|
||||
}
|
||||
$table_data[] = array('key' => __('Provider'), 'value' => $feed['Feed']['provider']);
|
||||
$temp = json_decode($feed['Feed']['rules'], true);
|
||||
$table_data[] = array('key' => __('Provider'), 'value' => $data['Feed']['provider']);
|
||||
$temp = json_decode($data['Feed']['rules'], true);
|
||||
if ($temp) {
|
||||
$scopes = array('tags', 'orgs');
|
||||
$booleanScopeColours = array('OR' => 'green', 'NOT' => 'red');
|
||||
|
@ -55,18 +55,18 @@
|
|||
}
|
||||
$table_data[] = array('key' => __('Rules'), 'html' => implode('<br />', $rule));
|
||||
}
|
||||
if (!empty($feed['Feed']['settings'])) {
|
||||
if (!empty($data['Feed']['settings'])) {
|
||||
$table_data[] = array('key' => __('Settings'), 'html' => sprintf(
|
||||
'<pre class="red">%s</pre>',
|
||||
h(json_encode(json_decode($feed['Feed']['settings']), JSON_PRETTY_PRINT)))
|
||||
h(json_encode(json_decode($data['Feed']['settings']), JSON_PRETTY_PRINT)))
|
||||
);
|
||||
}
|
||||
$table_data[] = array('key' => __('Enabled'), 'boolean' => $feed['Feed']['enabled']);
|
||||
$table_data[] = array('key' => __('Caching enabled'), 'boolean' => $feed['Feed']['caching_enabled']);
|
||||
$table_data[] = array('key' => __('Enabled'), 'boolean' => $data['Feed']['enabled']);
|
||||
$table_data[] = array('key' => __('Caching enabled'), 'boolean' => $data['Feed']['caching_enabled']);
|
||||
$progress_bar = sprintf(
|
||||
'<div class="progress" style="margin-bottom:0px;"><div class="bar" style="width: %s;">%s</div></div>',
|
||||
h($feed['Feed']['coverage_by_other_feeds']),
|
||||
h($feed['Feed']['coverage_by_other_feeds'])
|
||||
h($data['Feed']['coverage_by_other_feeds']),
|
||||
h($data['Feed']['coverage_by_other_feeds'])
|
||||
);
|
||||
$table_data[] = array(
|
||||
'key' => __('Coverage by other feeds'),
|
||||
|
@ -81,6 +81,6 @@
|
|||
__('Feed'),
|
||||
$this->element('genericElements/viewMetaTable', array('table_data' => $table_data))
|
||||
),
|
||||
$this->element('Feeds/View/feed_overlap_tool', array('other_feeds' => $other_feeds, 'feed' => $feed))
|
||||
$this->element('Feeds/View/feed_overlap_tool', array('other_feeds' => $other_feeds, 'feed' => $data))
|
||||
);
|
||||
echo $this->element('/genericElements/SideMenu/side_menu', array('menuList' => 'feeds', 'menuItem' => 'view'));
|
||||
|
|
Loading…
Reference in New Issue