Further progress on the feeds

pull/1050/head
Iglocska 2016-02-29 22:32:04 +01:00
parent 9cb796b394
commit 255c65942e
10 changed files with 168 additions and 64 deletions

View File

@ -63,17 +63,40 @@ class FeedsController extends AppController {
if (!$this->Feed->exists()) throw new NotFoundException('Invalid feed.');
$this->Feed->read();
if ($this->request->is('post') || $this->request->is('put')) {
if (isset($this->request->data['Feed']['pull_rules'])) $this->request->data['Feed']['rules'] = $this->request->data['Feed']['pull_rules'];
$this->request->data['Feed']['id'] = $feedId;
$fields = array('id', 'name', 'provider', 'enabled', 'rules', 'url');
$feed = array();
foreach ($fields as $field) $feed[$field] = $this->request->data['Feed'][$field];
$result = $this->Feed->save($feed);
if ($result) {
$this->Session->setFlash('Feed updated.');
$this->redirect(array('controller' => 'feeds', 'action' => 'index'));
}
else $this->Session->setFlash('Feed could not be updated.');
} else {
$this->request->data = $this->Feed->data;
}
}
public function delete($feedId) {
if (!$this->request->is('post')) throw new MethodNotAllowedException('This action requires a post request.');
$this->Feed->id = $feedId;
if (!$this->Feed->exists()) throw new NotFoundException('Invalid feed.');
if ($this->Feed->delete($feedId)) $this->Session->setFlash('Feed deleted.');
else $this->Session->setFlash('Feed could not be deleted.');
$this->redirect(array('controller' => 'feeds', 'action' => 'index'));
}
public function fetchFromFeed($feedId) {
$this->Feed->id = $feedId;
if (!$this->Feed->exists()) throw new NotFoundException('Invalid feed.');
App::uses('SyncTool', 'Tools');
$syncTool = new SyncTool();
$this->Feed->read();
$HttpSocket = $syncTool->setupHttpSocketFeed($this->Feed->data);
$actions = $this->Feed->getNewEventUuids($this->Feed->data, $HttpSocket);
$result = $this->Feed->downloadFromFeed($actions, $this->Feed->data, $HttpSocket, $this->Auth->user());
}
}

View File

@ -15,4 +15,12 @@ class SyncTool {
if (isset($proxy['host']) && !empty($proxy['host'])) $HttpSocket->configProxy($proxy['host'], $proxy['port'], $proxy['method'], $proxy['user'], $proxy['password']);
return $HttpSocket;
}
public function setupHttpSocketFeed($feed = null) {
App::uses('HttpSocket', 'Network/Http');
$HttpSocket = new HttpSocket();
$proxy = Configure::read('Proxy');
if (isset($proxy['host']) && !empty($proxy['host'])) $HttpSocket->configProxy($proxy['host'], $proxy['port'], $proxy['method'], $proxy['user'], $proxy['password']);
return $HttpSocket;
}
}

View File

@ -1917,6 +1917,7 @@ class Event extends AppModel {
$date = $dateObj->getTimestamp();
if (count($existingEvent)) {
$data['Event']['id'] = $existingEvent['Event']['id'];
$id = $existingEvent['Event']['id'];
// Conditions affecting all:
// user.org == event.org
// edit timestamp newer than existing event timestamp

121
app/Model/Feed.php Normal file
View File

@ -0,0 +1,121 @@
<?php
App::uses('AppModel', 'Model');
class Feed extends AppModel {
public $actsAs = array('SysLogLogable.SysLogLogable' => array(
'change' => 'full'
),
'Trim',
'Containable'
);
/**
* Validation rules
*
* @var array
*/
public $validate = array(
'url' => array( // TODO add extra validation to refuse multiple time the same url from the same org
'rule' => array('url'),
'message' => 'Please enter a valid url.',
),
'provider' => array(
'valueNotEmpty' => array(
'rule' => array('valueNotEmpty'),
),
),
'name' => array(
'valueNotEmpty' => array(
'rule' => array('valueNotEmpty'),
),
),
);
// gets the event UUIDs from the feed by ID
// returns an array with the UUIDs of events that are new or that need updating
public function getNewEventUuids($feed, $HttpSocket) {
$result = array();
$request = $this->__createFeedRequest();
$uri = $feed['Feed']['url'] . '/manifest.json';
$response = $HttpSocket->get($uri, '', $request);
if ($response->code != 200) return 1;
$manifest = json_decode($response->body, true);
if (!$manifest) return 2;
$this->Event = ClassRegistry::init('Event');
$events = $this->Event->find('all', array(
'conditions' => array(
'Event.uuid' => array_keys($manifest),
),
'recursive' => -1,
'fields' => array('Event.id', 'Event.uuid', 'Event.timestamp')
));
foreach ($events as &$event) {
if ($event['Event']['timestamp'] < $manifest[$event['Event']['uuid']]) $result['edit'][] = array('uuid' => $event['Event']['uuid'], 'id' => $event['Event']['id']);
unset($manifest[$event['Event']['uuid']]);
}
$result['add'] = array_keys($manifest);
return $result;
}
public function downloadFromFeed($actions, $feed, $HttpSocket, $user) {
$this->Event = ClassRegistry::init('Event');
if (isset($actions['add']) && !empty($actions['add'])) {
foreach ($actions['add'] as $uuid) {
$this->__addEventFromFeed($HttpSocket, $feed, $uuid, $user);
}
}
if (isset($actions['edit']) && !empty($actions['edit'])) {
foreach ($actions['edit'] as $editTarget) {
$this->__updateEventFromFeed($HttpSocket, $feed, $editTarget['uuid'], $editTarget['id'], $user);
}
}
}
private function __createFeedRequest() {
$version = $this->checkMISPVersion();
$version = implode('.', $version);
return array(
'header' => array(
'Accept' => 'application/json',
'Content-Type' => 'application/json',
'MISP-version' => $version
)
);
}
private function __addEventFromFeed($HttpSocket, $feed, $uuid, $user) {
$request = $this->__createFeedRequest();
$uri = $feed['Feed']['url'] . '/' . $uuid . '.json';
$response = $HttpSocket->get($uri, '', $request);
if ($response->code != 200) {
return false;
} else {
$event = json_decode($response->body, true);
if (isset($event['response'])) $event = $event['response'];
if (isset($event[0])) $event = $event[0];
if (!isset($event['Event']['uuid'])) return false;
$this->Event = ClassRegistry::init('Event');
return $this->Event->_add($event, true, $user);
}
}
private function __updateEventFromFeed($HttpSocket, $feed, $uuid, $eventId, $user) {
debug($uuid);
$request = $this->__createFeedRequest();
$uri = $feed['Feed']['url'] . '/' . $uuid . '.json';
$response = $HttpSocket->get($uri, '', $request);
if ($response->code != 200) {
return false;
} else {
$event = json_decode($response->body, true);
if (isset($event['response'])) $event = $event['response'];
if (isset($event[0])) $event = $event[0];
if (!isset($event['Event']['uuid'])) return false;
$this->Event = ClassRegistry::init('Event');
debug($this->Event->_edit($event, $user, $uuid, $jobId = null));
//return $this->Event->_edit($event, $user, $uuid, $jobId = null);
}
}
}

View File

@ -1,56 +0,0 @@
<?php
App::uses('AppModel', 'Model');
/**
* Feed Model
*
*/
class Feed extends AppModel {
public $name = 'Feed';
public $actsAs = array('SysLogLogable.SysLogLogable' => array(
'change' => 'full'
),
'Trim',
'Containable'
);
public $belongsTo = array(
);
public $hasMany = array(
);
/**
* Validation rules
*
* @var array
*/
public $validate = array(
'url' => array( // TODO add extra validation to refuse multiple time the same url from the same org
'rule' => array('url'),
'message' => 'Please enter a valid url.',
),
'provider' => array(
'valueNotEmpty' => array(
'rule' => array('valueNotEmpty'),
),
),
'name' => array(
'valueNotEmpty' => array(
'rule' => array('valueNotEmpty'),
),
),
);
// gets the event UUIDs from the feed by ID
// returns an array with the UUIDs of events that are new or that need updating
public function getNewEventUuids($feedId) {
}
public function downloadEvent($feedId, $eventId) {
}
}

View File

@ -97,6 +97,7 @@
</a>
<ul class="dropdown-menu">
<li><a href="<?php echo $baseurl;?>/servers/index">List Servers</a></li>
<li><a href="<?php echo $baseurl;?>/feeds/index">List Feeds</a></li>
</ul>
</li>
<?php endif;?>

View File

@ -293,6 +293,14 @@
endif;
endif;
break;
case 'feeds': ?>
<li id='liindex'><a href="<?php echo $baseurl;?>/feeds/index">List Feeds</a></li>
<li id='liadd'><a href="<?php echo $baseurl;?>/feeds/add">Add Feed</a></li>
<?php if ($menuItem === 'edit'): ?>
<li class="active"><a href="#">Edit Feed</a></li>
<?php endif;
break;
}
?>
</ul>

View File

@ -16,8 +16,6 @@
'div' => 'input clear',
'placeholder' => 'URL of the feed'
));
?>
<?php
echo $this->Form->input('pull_rules', array('style' => 'display:none;', 'label' => false, 'div' => false));
?>
</fieldset>
@ -36,7 +34,7 @@
</div>
</div>
<?php
echo $this->element('side_menu', array('menuList' => 'feed', 'menuItem' => 'add'));
echo $this->element('side_menu', array('menuList' => 'feeds', 'menuItem' => 'add'));
?>
<script type="text/javascript">
//

View File

@ -25,5 +25,5 @@ echo $this->Form->end();
?>
</div>
<?php
echo $this->element('side_menu', array('menuList' => 'admin', 'menuItem' => 'eventBlacklistsAdd'));
echo $this->element('side_menu', array('menuList' => 'feeds', 'menuItem' => 'edit'));
?>

View File

@ -82,5 +82,5 @@ endforeach; ?>
</div>
<?php
echo $this->element('side_menu', array('menuList' => 'feed', 'menuItem' => 'index'));
echo $this->element('side_menu', array('menuList' => 'feeds', 'menuItem' => 'index'));
?>