mirror of https://github.com/MISP/MISP
fixes information leakage vulnerability on REST XML outputs
parent
62a3da46f2
commit
0614db919e
|
@ -121,10 +121,7 @@ Configure::write('CyDefSIG.logo', 'orgs/ORGNAME.png'); // used in Events::in
|
|||
Configure::write('CyDefSIG.showorg', 'true'); // show the name/flag of the organisation that uploaded the data
|
||||
|
||||
Configure::write('CyDefSIG.sync', 'true'); // enable features related to syncing with other CyDefSIG instances - should be always on because of the current distribution model.
|
||||
Configure::write('CyDefSIG.private', 'true'); // respect private to org or server.
|
||||
if ('true' == Configure::read('CyDefSIG.private')) {
|
||||
Configure::write('CyDefSIG.sync', 'true');
|
||||
}
|
||||
|
||||
Configure::write('CyDefSIG.email', 'email@address.com'); // email from for all the mails
|
||||
Configure::write('CyDefSIG.contact', 'email@address.com'); // contact address for this instance's support person / group
|
||||
|
||||
|
|
|
@ -78,16 +78,6 @@ class EventsController extends AppController {
|
|||
);
|
||||
}
|
||||
|
||||
//// do not show cluster outside server
|
||||
//if ('true' == Configure::read('CyDefSIG.private')) {
|
||||
// if ($this->_isRest()) {
|
||||
// $this->paginate = Set::merge($this->paginate,array(
|
||||
// 'conditions' =>
|
||||
// array(array('Event.cluster !=' => true)),
|
||||
// //array("AND" => array(array('Event.private !=' => 2))),
|
||||
// ));
|
||||
// }
|
||||
//}
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -268,7 +258,7 @@ class EventsController extends AppController {
|
|||
//return false;
|
||||
$this->Session->setFlash(__('You may only upload GFI Sandbox zip files.'));
|
||||
} else {
|
||||
if ($this->_add($this->request->data, $this->Auth, $this->_isRest(),'')) {
|
||||
if ($this->_add($this->request->data, $this->_isRest(),'')) {
|
||||
if ($this->_isRest()) {
|
||||
// REST users want to see the newly created event
|
||||
$this->view($this->Event->getId());
|
||||
|
@ -333,8 +323,9 @@ class EventsController extends AppController {
|
|||
*
|
||||
* @return bool true if success
|
||||
*/
|
||||
public function _add(&$data, &$auth, $fromXml, $or='', $passAlong = null, $fromPull = false) {
|
||||
public function _add(&$data, $fromXml, $or='', $passAlong = null, $fromPull = false) {
|
||||
// force check userid and orgname to be from yourself
|
||||
$auth = $this->Auth;
|
||||
$data['Event']['user_id'] = $auth->user('id');
|
||||
$data['Event']['org'] = $auth->user('org');
|
||||
//$data['Event']['org'] = strlen($or) ? $or : $auth->user('org'); // FIXME security - org problem
|
||||
|
|
|
@ -1,351 +1,351 @@
|
|||
<?php
|
||||
App::uses('AppController', 'Controller');
|
||||
App::uses('Xml', 'Utility');
|
||||
|
||||
/**
|
||||
* Servers Controller
|
||||
*
|
||||
* @property Server $Server
|
||||
*
|
||||
* @throws ConfigureException // TODO Exception
|
||||
*/
|
||||
class ServersController extends AppController {
|
||||
|
||||
public $components = array('Security' ,'RequestHandler'); // XXX ACL component
|
||||
|
||||
public $paginate = array(
|
||||
'limit' => 60,
|
||||
'maxLimit' => 9999, // LATER we will bump here on a problem once we have more than 9999 events
|
||||
'order' => array(
|
||||
'Server.url' => 'ASC'
|
||||
)
|
||||
);
|
||||
|
||||
public $uses = array('Server', 'Event');
|
||||
|
||||
public function beforeFilter() {
|
||||
parent::beforeFilter();
|
||||
|
||||
// Disable this feature if the sync configuration option is not active
|
||||
if ('true' != Configure::read('CyDefSIG.sync'))
|
||||
throw new ConfigureException("The sync feature is not active in the configuration.");
|
||||
|
||||
// permit reuse of CSRF tokens on some pages.
|
||||
switch ($this->request->params['action']) {
|
||||
case 'push':
|
||||
case 'pull':
|
||||
$this->Security->csrfUseOnce = false;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* index method
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function index() {
|
||||
$this->Server->recursive = 0;
|
||||
if ($this->_IsSiteAdmin()) {
|
||||
$this->paginate = array(
|
||||
'conditions' => array(),
|
||||
);
|
||||
} else {
|
||||
if (!$this->checkAction('perm_sync')) $this->redirect(array('controller' => 'events', 'action' => 'index'));
|
||||
$conditions['Server.org LIKE'] = $this->Auth->user('org');
|
||||
$this->paginate = array(
|
||||
'conditions' => array($conditions),
|
||||
);
|
||||
}
|
||||
$this->set('servers', $this->paginate());
|
||||
}
|
||||
|
||||
/**
|
||||
* add method
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function add() {
|
||||
if ((!$this->_IsSiteAdmin()) && !($this->Server->organization == $this->Auth->user('org') && $this->checkAction('perm_sync'))) $this->redirect(array('controller' => 'servers', 'action' => 'index'));
|
||||
if ($this->request->is('post')) {
|
||||
// force check userid and orgname to be from yourself
|
||||
$this->request->data['Server']['org'] = $this->Auth->user('org');
|
||||
|
||||
$this->Server->create();
|
||||
if ($this->Server->save($this->request->data)) {
|
||||
$this->Session->setFlash(__('The server has been saved'));
|
||||
$this->redirect(array('action' => 'index'));
|
||||
} else {
|
||||
$this->Session->setFlash(__('The server could not be saved. Please, try again.'));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* edit method
|
||||
*
|
||||
* @param string $id
|
||||
* @return void
|
||||
* @throws NotFoundException
|
||||
*/
|
||||
public function edit($id = null) {
|
||||
if (!$this->_IsSiteAdmin() && !($this->Server->organization == $this->Auth->user('org') && $this->checkAction('perm_sync'))) $this->redirect(array('controller' => 'servers', 'action' => 'index'));
|
||||
$this->Server->id = $id;
|
||||
if (!$this->Server->exists()) {
|
||||
throw new NotFoundException(__('Invalid server'));
|
||||
}
|
||||
if ($this->request->is('post') || $this->request->is('put')) {
|
||||
// say what fields are to be updated
|
||||
$fieldList = array('url', 'push', 'pull', 'organization');
|
||||
if ("" != $this->request->data['Server']['authkey'])
|
||||
$fieldList[] = 'authkey';
|
||||
// Save the data
|
||||
if ($this->Server->save($this->request->data, true, $fieldList)) {
|
||||
$this->Session->setFlash(__('The server has been saved'));
|
||||
$this->redirect(array('action' => 'index'));
|
||||
} else {
|
||||
$this->Session->setFlash(__('The server could not be saved. Please, try again.'));
|
||||
}
|
||||
} else {
|
||||
$this->Server->read(null, $id);
|
||||
$this->Server->set('authkey', '');
|
||||
$this->request->data = $this->Server->data;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* delete method
|
||||
*
|
||||
* @param string $id
|
||||
* @return void
|
||||
* @throws MethodNotAllowedException
|
||||
* @throws NotFoundException
|
||||
*/
|
||||
public function delete($id = null) {
|
||||
if(!$this->_IsSiteAdmin() && !($this->Server->id == $this->Auth->user('org') && $this->checkAction('perm_sync'))) $this->redirect(array('controller' => 'servers', 'action' => 'index'));
|
||||
if (!$this->request->is('post')) {
|
||||
throw new MethodNotAllowedException();
|
||||
}
|
||||
$this->Server->id = $id;
|
||||
if (!$this->Server->exists()) {
|
||||
throw new NotFoundException(__('Invalid server'));
|
||||
}
|
||||
if ($this->Server->delete()) {
|
||||
$this->Session->setFlash(__('Server deleted'));
|
||||
$this->redirect(array('action' => 'index'));
|
||||
}
|
||||
$this->Session->setFlash(__('Server was not deleted'));
|
||||
$this->redirect(array('action' => 'index'));
|
||||
}
|
||||
|
||||
public function pull($id = null, $full=false) {
|
||||
// TODO should we de-activate data validation for type and category / and or mapping? Maybe other instances have other configurations that are incompatible.
|
||||
if (!$this->_IsSiteAdmin() && !($this->Server->organization == $this->Auth->user('org') && $this->checkAction('perm_sync'))) $this->redirect(array('controller' => 'servers', 'action' => 'index'));
|
||||
if (!$this->request->is('post')) {
|
||||
throw new MethodNotAllowedException();
|
||||
}
|
||||
$this->Server->id = $id;
|
||||
if (!$this->Server->exists()) {
|
||||
throw new NotFoundException(__('Invalid server'));
|
||||
}
|
||||
|
||||
App::uses('HttpSocket', 'Network/Http');
|
||||
$this->Server->read(null, $id);
|
||||
if (false == $this->Server->data['Server']['pull']) {
|
||||
$this->Session->setFlash(__('Pull setting not enabled for this server.'));
|
||||
$this->redirect(array('action' => 'index'));
|
||||
}
|
||||
|
||||
if ("full" == $full) {
|
||||
// get a list of the event_ids on the server
|
||||
$eventIds = $this->Event->getEventIdsFromServer($this->Server->data);
|
||||
if ($eventIds === 403) {
|
||||
$this->Session->setFlash(__('Not authorised. This is either due to an invalid auth key, or due to the sync user not having authentication permissions enabled on the remote server.'));
|
||||
$this->redirect(array('action' => 'index'));
|
||||
}
|
||||
$successes = array();
|
||||
$fails = array();
|
||||
// download each event
|
||||
if (null != $eventIds) {
|
||||
App::import('Controller', 'Events');
|
||||
$HttpSocket = new HttpSocket();
|
||||
foreach ($eventIds as &$eventId) {
|
||||
$event = $this->Event->downloadEventFromServer(
|
||||
$eventId,
|
||||
$this->Server->data);
|
||||
if (null != $event) {
|
||||
// we have an Event array
|
||||
if (!isset($event['Event']['distribution'])) { // version 1
|
||||
$event['Event']['distribution'] = 'This Community-only';
|
||||
}
|
||||
// Distribution
|
||||
switch($event['Event']['distribution']) {
|
||||
case 'Your organization only': // Distribution, no Org only in Event
|
||||
case 'This server-only':
|
||||
continue 2; // to the next iteration of the outer loop
|
||||
break;
|
||||
case 'This Community-only': // Distribution, correct Community to Org only in Event
|
||||
$event['Event']['distribution'] = 'Your organization only';
|
||||
break;
|
||||
case 'Connected communities': // Distribution, correct All to Community in Event
|
||||
$event['Event']['distribution'] = 'This Community-only';
|
||||
break;
|
||||
}
|
||||
|
||||
// correct $event if just one Attribute
|
||||
if (is_array($event['Event']['Attribute']) && isset($event['Event']['Attribute']['id'])) {
|
||||
$tmp = $event['Event']['Attribute'];
|
||||
unset($event['Event']['Attribute']);
|
||||
$event['Event']['Attribute'][0] = $tmp;
|
||||
}
|
||||
|
||||
if (is_array($event['Event']['Attribute'])) {
|
||||
$toRemove = array();
|
||||
$size = is_array($event['Event']['Attribute']) ? count($event['Event']['Attribute']) : 0;
|
||||
for ($i = 0; $i < $size; $i++) {
|
||||
if (!isset($event['Event']['Attribute'][$i]['distribution'])) { // version 1
|
||||
$event['Event']['Attribute'][$i]['distribution'] = 'This Community-only';
|
||||
}
|
||||
switch($event['Event']['Attribute'][$i]['distribution']) {
|
||||
case 'Your organization only':
|
||||
case 'This server-only':
|
||||
$toRemove[] = $i;
|
||||
break;
|
||||
case 'This Community-only':
|
||||
$event['Event']['Attribute'][$i]['private'] = true;
|
||||
$event['Event']['Attribute'][$i]['cluster'] = false;
|
||||
$event['Event']['Attribute'][$i]['communitie'] = false;
|
||||
$event['Event']['Attribute'][$i]['distribution'] = 'Your organization only';
|
||||
break;
|
||||
case 'Connected communities':
|
||||
$event['Event']['Attribute'][$i]['cluster'] = true;
|
||||
$event['Event']['Attribute'][$i]['distribution'] = 'This Community-only';
|
||||
break;
|
||||
}
|
||||
}
|
||||
foreach ($toRemove as $thisRemove) {
|
||||
unset($event['Event']['Attribute'][$thisRemove]);
|
||||
}
|
||||
$event['Event']['Attribute'] = array_values($event['Event']['Attribute']);
|
||||
} else {
|
||||
unset($event['Event']['Attribute']);
|
||||
}
|
||||
// Distribution, set reporter of the event, being the admin that initiated the pull
|
||||
$event['Event']['user_id'] = $this->Auth->user('id');
|
||||
// check if the event already exist (using the uuid)
|
||||
$existingEventCount = $this->Event->find('count', array('conditions' => array('Event.uuid' => $event['Event']['uuid'])));
|
||||
if ($existingEventCount == 0) {
|
||||
// add data for newly imported events
|
||||
$event['Event']['info'] .= "\n Imported from " . $this->Server->data['Server']['url'];
|
||||
}
|
||||
$eventsController = new EventsController();
|
||||
$eventsController->constructClasses();
|
||||
$passAlong = $this->Server->data['Server']['url'];
|
||||
try {
|
||||
$result = $eventsController->_add($event, $this->Auth, $fromXml = true, $this->Server->data['Server']['organization'], $passAlong, true);
|
||||
} catch (MethodNotAllowedException $e) {
|
||||
if ($e->getMessage() == 'Event already exists') {
|
||||
//$successes[] = $eventId; // commented given it's in a catch..
|
||||
continue;
|
||||
}
|
||||
}
|
||||
$successes[] = $eventId; // ..moved, so $successes does keep administration.
|
||||
//$result = $this->_importEvent($event);
|
||||
// TODO error handling
|
||||
} else {
|
||||
// error
|
||||
$fails[$eventId] = 'failed';
|
||||
}
|
||||
|
||||
}
|
||||
if (count($fails) > 0) {
|
||||
// there are fails, take the lowest fail
|
||||
$lastpulledid = min(array_keys($fails));
|
||||
} else {
|
||||
// no fails, take the highest success
|
||||
$lastpulledid = count($successes) > 0 ? max($successes) : 0;
|
||||
}
|
||||
// increment lastid based on the highest ID seen
|
||||
$this->Server->saveField('lastpulledid', $lastpulledid);
|
||||
|
||||
}
|
||||
|
||||
} else {
|
||||
// TODO incremental pull
|
||||
// lastpulledid
|
||||
throw new NotFoundException('Sorry, this is not yet implemented');
|
||||
|
||||
// increment lastid based on the highest ID seen
|
||||
}
|
||||
|
||||
$this->set('successes', $successes);
|
||||
$this->set('fails', $fails);
|
||||
}
|
||||
|
||||
public function push($id = null, $full=false) {
|
||||
if ($this->Auth->user('org') != 'ADMIN' && !($this->Server->organization == $this->Auth->user('org') && $this->checkAction('perm_sync'))) $this->redirect(array('controller' => 'servers', 'action' => 'index'));
|
||||
if (!$this->request->is('post')) {
|
||||
throw new MethodNotAllowedException();
|
||||
}
|
||||
$this->Server->id = $id;
|
||||
if (!$this->Server->exists()) {
|
||||
throw new NotFoundException(__('Invalid server'));
|
||||
}
|
||||
|
||||
App::uses('HttpSocket', 'Network/Http');
|
||||
$this->Server->read(null, $id);
|
||||
|
||||
if (false == $this->Server->data['Server']['push']) {
|
||||
$this->Session->setFlash(__('Push setting not enabled for this server.'));
|
||||
$this->redirect(array('action' => 'index'));
|
||||
}
|
||||
|
||||
if ("full" == $full) $lastpushedid = 0;
|
||||
else $lastpushedid = $this->Server->data['Server']['lastpushedid'];
|
||||
|
||||
$findParams = array(
|
||||
'conditions' => array(
|
||||
'Event.id >' => $lastpushedid, // TODO think about this one!!
|
||||
'Event.private' => 0,
|
||||
'Event.published' => 1
|
||||
), //array of conditions
|
||||
'recursive' => 1, //int
|
||||
'fields' => array('Event.*'), //array of field names
|
||||
);
|
||||
$events = $this->Event->find('all', $findParams);
|
||||
|
||||
// FIXME now all events are uploaded, even if they exist on the remote server. No merging is done
|
||||
|
||||
$successes = array();
|
||||
$fails = array();
|
||||
$lowestfailedid = null;
|
||||
|
||||
if (!empty($events)) { // do nothing if there are no events to push
|
||||
$HttpSocket = new HttpSocket();
|
||||
|
||||
$this->loadModel('Attribute');
|
||||
// upload each event separately and keep the results in the $successes and $fails arrays
|
||||
foreach ($events as &$event) {
|
||||
$result = $this->Event->uploadEventToServer(
|
||||
$event,
|
||||
$this->Server->data,
|
||||
$HttpSocket);
|
||||
if (true == $result) {
|
||||
$successes[] = $event['Event']['id'];
|
||||
} else {
|
||||
$fails[$event['Event']['id']] = $result;
|
||||
}
|
||||
}
|
||||
if (count($fails) > 0) {
|
||||
// there are fails, take the lowest fail
|
||||
$lastpushedid = min(array_keys($fails));
|
||||
} else {
|
||||
// no fails, take the highest success
|
||||
$lastpushedid = max($successes);
|
||||
}
|
||||
// increment lastid based on the highest ID seen
|
||||
$this->Server->saveField('lastpushedid', $lastpushedid);
|
||||
}
|
||||
$this->set('successes', $successes);
|
||||
$this->set('fails', $fails);
|
||||
}
|
||||
}
|
||||
<?php
|
||||
App::uses('AppController', 'Controller');
|
||||
App::uses('Xml', 'Utility');
|
||||
|
||||
/**
|
||||
* Servers Controller
|
||||
*
|
||||
* @property Server $Server
|
||||
*
|
||||
* @throws ConfigureException // TODO Exception
|
||||
*/
|
||||
class ServersController extends AppController {
|
||||
|
||||
public $components = array('Security' ,'RequestHandler'); // XXX ACL component
|
||||
|
||||
public $paginate = array(
|
||||
'limit' => 60,
|
||||
'maxLimit' => 9999, // LATER we will bump here on a problem once we have more than 9999 events
|
||||
'order' => array(
|
||||
'Server.url' => 'ASC'
|
||||
)
|
||||
);
|
||||
|
||||
public $uses = array('Server', 'Event');
|
||||
|
||||
public function beforeFilter() {
|
||||
parent::beforeFilter();
|
||||
|
||||
// Disable this feature if the sync configuration option is not active
|
||||
if ('true' != Configure::read('CyDefSIG.sync'))
|
||||
throw new ConfigureException("The sync feature is not active in the configuration.");
|
||||
|
||||
// permit reuse of CSRF tokens on some pages.
|
||||
switch ($this->request->params['action']) {
|
||||
case 'push':
|
||||
case 'pull':
|
||||
$this->Security->csrfUseOnce = false;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* index method
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function index() {
|
||||
$this->Server->recursive = 0;
|
||||
if ($this->_IsSiteAdmin()) {
|
||||
$this->paginate = array(
|
||||
'conditions' => array(),
|
||||
);
|
||||
} else {
|
||||
if (!$this->checkAction('perm_sync')) $this->redirect(array('controller' => 'events', 'action' => 'index'));
|
||||
$conditions['Server.org LIKE'] = $this->Auth->user('org');
|
||||
$this->paginate = array(
|
||||
'conditions' => array($conditions),
|
||||
);
|
||||
}
|
||||
$this->set('servers', $this->paginate());
|
||||
}
|
||||
|
||||
/**
|
||||
* add method
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function add() {
|
||||
if ((!$this->_IsSiteAdmin()) && !($this->Server->organization == $this->Auth->user('org') && $this->checkAction('perm_sync'))) $this->redirect(array('controller' => 'servers', 'action' => 'index'));
|
||||
if ($this->request->is('post')) {
|
||||
// force check userid and orgname to be from yourself
|
||||
$this->request->data['Server']['org'] = $this->Auth->user('org');
|
||||
|
||||
$this->Server->create();
|
||||
if ($this->Server->save($this->request->data)) {
|
||||
$this->Session->setFlash(__('The server has been saved'));
|
||||
$this->redirect(array('action' => 'index'));
|
||||
} else {
|
||||
$this->Session->setFlash(__('The server could not be saved. Please, try again.'));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* edit method
|
||||
*
|
||||
* @param string $id
|
||||
* @return void
|
||||
* @throws NotFoundException
|
||||
*/
|
||||
public function edit($id = null) {
|
||||
if (!$this->_IsSiteAdmin() && !($this->Server->organization == $this->Auth->user('org') && $this->checkAction('perm_sync'))) $this->redirect(array('controller' => 'servers', 'action' => 'index'));
|
||||
$this->Server->id = $id;
|
||||
if (!$this->Server->exists()) {
|
||||
throw new NotFoundException(__('Invalid server'));
|
||||
}
|
||||
if ($this->request->is('post') || $this->request->is('put')) {
|
||||
// say what fields are to be updated
|
||||
$fieldList = array('url', 'push', 'pull', 'organization');
|
||||
if ("" != $this->request->data['Server']['authkey'])
|
||||
$fieldList[] = 'authkey';
|
||||
// Save the data
|
||||
if ($this->Server->save($this->request->data, true, $fieldList)) {
|
||||
$this->Session->setFlash(__('The server has been saved'));
|
||||
$this->redirect(array('action' => 'index'));
|
||||
} else {
|
||||
$this->Session->setFlash(__('The server could not be saved. Please, try again.'));
|
||||
}
|
||||
} else {
|
||||
$this->Server->read(null, $id);
|
||||
$this->Server->set('authkey', '');
|
||||
$this->request->data = $this->Server->data;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* delete method
|
||||
*
|
||||
* @param string $id
|
||||
* @return void
|
||||
* @throws MethodNotAllowedException
|
||||
* @throws NotFoundException
|
||||
*/
|
||||
public function delete($id = null) {
|
||||
if(!$this->_IsSiteAdmin() && !($this->Server->id == $this->Auth->user('org') && $this->checkAction('perm_sync'))) $this->redirect(array('controller' => 'servers', 'action' => 'index'));
|
||||
if (!$this->request->is('post')) {
|
||||
throw new MethodNotAllowedException();
|
||||
}
|
||||
$this->Server->id = $id;
|
||||
if (!$this->Server->exists()) {
|
||||
throw new NotFoundException(__('Invalid server'));
|
||||
}
|
||||
if ($this->Server->delete()) {
|
||||
$this->Session->setFlash(__('Server deleted'));
|
||||
$this->redirect(array('action' => 'index'));
|
||||
}
|
||||
$this->Session->setFlash(__('Server was not deleted'));
|
||||
$this->redirect(array('action' => 'index'));
|
||||
}
|
||||
|
||||
public function pull($id = null, $full=false) {
|
||||
// TODO should we de-activate data validation for type and category / and or mapping? Maybe other instances have other configurations that are incompatible.
|
||||
if (!$this->_IsSiteAdmin() && !($this->Server->organization == $this->Auth->user('org') && $this->checkAction('perm_sync'))) $this->redirect(array('controller' => 'servers', 'action' => 'index'));
|
||||
if (!$this->request->is('post')) {
|
||||
throw new MethodNotAllowedException();
|
||||
}
|
||||
$this->Server->id = $id;
|
||||
if (!$this->Server->exists()) {
|
||||
throw new NotFoundException(__('Invalid server'));
|
||||
}
|
||||
|
||||
App::uses('HttpSocket', 'Network/Http');
|
||||
$this->Server->read(null, $id);
|
||||
if (false == $this->Server->data['Server']['pull']) {
|
||||
$this->Session->setFlash(__('Pull setting not enabled for this server.'));
|
||||
$this->redirect(array('action' => 'index'));
|
||||
}
|
||||
|
||||
if ("full" == $full) {
|
||||
// get a list of the event_ids on the server
|
||||
$eventIds = $this->Event->getEventIdsFromServer($this->Server->data);
|
||||
if ($eventIds === 403) {
|
||||
$this->Session->setFlash(__('Not authorised. This is either due to an invalid auth key, or due to the sync user not having authentication permissions enabled on the remote server.'));
|
||||
$this->redirect(array('action' => 'index'));
|
||||
}
|
||||
$successes = array();
|
||||
$fails = array();
|
||||
// download each event
|
||||
if (null != $eventIds) {
|
||||
App::import('Controller', 'Events');
|
||||
$HttpSocket = new HttpSocket();
|
||||
foreach ($eventIds as &$eventId) {
|
||||
$event = $this->Event->downloadEventFromServer(
|
||||
$eventId,
|
||||
$this->Server->data);
|
||||
if (null != $event) {
|
||||
// we have an Event array
|
||||
if (!isset($event['Event']['distribution'])) { // version 1
|
||||
$event['Event']['distribution'] = 'This Community-only';
|
||||
}
|
||||
// Distribution
|
||||
switch($event['Event']['distribution']) {
|
||||
case 'Your organization only': // Distribution, no Org only in Event
|
||||
case 'This server-only':
|
||||
continue 2; // to the next iteration of the outer loop
|
||||
break;
|
||||
case 'This Community-only': // Distribution, correct Community to Org only in Event
|
||||
$event['Event']['distribution'] = 'Your organization only';
|
||||
break;
|
||||
case 'Connected communities': // Distribution, correct All to Community in Event
|
||||
$event['Event']['distribution'] = 'This Community-only';
|
||||
break;
|
||||
}
|
||||
|
||||
// correct $event if just one Attribute
|
||||
if (is_array($event['Event']['Attribute']) && isset($event['Event']['Attribute']['id'])) {
|
||||
$tmp = $event['Event']['Attribute'];
|
||||
unset($event['Event']['Attribute']);
|
||||
$event['Event']['Attribute'][0] = $tmp;
|
||||
}
|
||||
|
||||
if (is_array($event['Event']['Attribute'])) {
|
||||
$toRemove = array();
|
||||
$size = is_array($event['Event']['Attribute']) ? count($event['Event']['Attribute']) : 0;
|
||||
for ($i = 0; $i < $size; $i++) {
|
||||
if (!isset($event['Event']['Attribute'][$i]['distribution'])) { // version 1
|
||||
$event['Event']['Attribute'][$i]['distribution'] = 'This Community-only';
|
||||
}
|
||||
switch($event['Event']['Attribute'][$i]['distribution']) {
|
||||
case 'Your organization only':
|
||||
case 'This server-only':
|
||||
$toRemove[] = $i;
|
||||
break;
|
||||
case 'This Community-only':
|
||||
$event['Event']['Attribute'][$i]['private'] = true;
|
||||
$event['Event']['Attribute'][$i]['cluster'] = false;
|
||||
$event['Event']['Attribute'][$i]['communitie'] = false;
|
||||
$event['Event']['Attribute'][$i]['distribution'] = 'Your organization only';
|
||||
break;
|
||||
case 'Connected communities':
|
||||
$event['Event']['Attribute'][$i]['cluster'] = true;
|
||||
$event['Event']['Attribute'][$i]['distribution'] = 'This Community-only';
|
||||
break;
|
||||
}
|
||||
}
|
||||
foreach ($toRemove as $thisRemove) {
|
||||
unset($event['Event']['Attribute'][$thisRemove]);
|
||||
}
|
||||
$event['Event']['Attribute'] = array_values($event['Event']['Attribute']);
|
||||
} else {
|
||||
unset($event['Event']['Attribute']);
|
||||
}
|
||||
// Distribution, set reporter of the event, being the admin that initiated the pull
|
||||
$event['Event']['user_id'] = $this->Auth->user('id');
|
||||
// check if the event already exist (using the uuid)
|
||||
$existingEventCount = $this->Event->find('count', array('conditions' => array('Event.uuid' => $event['Event']['uuid'])));
|
||||
if ($existingEventCount == 0) {
|
||||
// add data for newly imported events
|
||||
$event['Event']['info'] .= "\n Imported from " . $this->Server->data['Server']['url'];
|
||||
}
|
||||
$eventsController = new EventsController();
|
||||
$eventsController->constructClasses();
|
||||
$passAlong = $this->Server->data['Server']['url'];
|
||||
try {
|
||||
$result = $eventsController->_add($event, $fromXml = true, $this->Server->data['Server']['organization'], $passAlong, true);
|
||||
} catch (MethodNotAllowedException $e) {
|
||||
if ($e->getMessage() == 'Event already exists') {
|
||||
//$successes[] = $eventId; // commented given it's in a catch..
|
||||
continue;
|
||||
}
|
||||
}
|
||||
$successes[] = $eventId; // ..moved, so $successes does keep administration.
|
||||
//$result = $this->_importEvent($event);
|
||||
// TODO error handling
|
||||
} else {
|
||||
// error
|
||||
$fails[$eventId] = 'failed';
|
||||
}
|
||||
|
||||
}
|
||||
if (count($fails) > 0) {
|
||||
// there are fails, take the lowest fail
|
||||
$lastpulledid = min(array_keys($fails));
|
||||
} else {
|
||||
// no fails, take the highest success
|
||||
$lastpulledid = count($successes) > 0 ? max($successes) : 0;
|
||||
}
|
||||
// increment lastid based on the highest ID seen
|
||||
$this->Server->saveField('lastpulledid', $lastpulledid);
|
||||
|
||||
}
|
||||
|
||||
} else {
|
||||
// TODO incremental pull
|
||||
// lastpulledid
|
||||
throw new NotFoundException('Sorry, this is not yet implemented');
|
||||
|
||||
// increment lastid based on the highest ID seen
|
||||
}
|
||||
|
||||
$this->set('successes', $successes);
|
||||
$this->set('fails', $fails);
|
||||
}
|
||||
|
||||
public function push($id = null, $full=false) {
|
||||
if ($this->Auth->user('org') != 'ADMIN' && !($this->Server->organization == $this->Auth->user('org') && $this->checkAction('perm_sync'))) $this->redirect(array('controller' => 'servers', 'action' => 'index'));
|
||||
if (!$this->request->is('post')) {
|
||||
throw new MethodNotAllowedException();
|
||||
}
|
||||
$this->Server->id = $id;
|
||||
if (!$this->Server->exists()) {
|
||||
throw new NotFoundException(__('Invalid server'));
|
||||
}
|
||||
|
||||
App::uses('HttpSocket', 'Network/Http');
|
||||
$this->Server->read(null, $id);
|
||||
|
||||
if (false == $this->Server->data['Server']['push']) {
|
||||
$this->Session->setFlash(__('Push setting not enabled for this server.'));
|
||||
$this->redirect(array('action' => 'index'));
|
||||
}
|
||||
|
||||
if ("full" == $full) $lastpushedid = 0;
|
||||
else $lastpushedid = $this->Server->data['Server']['lastpushedid'];
|
||||
|
||||
$findParams = array(
|
||||
'conditions' => array(
|
||||
'Event.id >' => $lastpushedid, // TODO think about this one!!
|
||||
'Event.private' => 0,
|
||||
'Event.published' => 1
|
||||
), //array of conditions
|
||||
'recursive' => 1, //int
|
||||
'fields' => array('Event.*'), //array of field names
|
||||
);
|
||||
$events = $this->Event->find('all', $findParams);
|
||||
|
||||
// FIXME now all events are uploaded, even if they exist on the remote server. No merging is done
|
||||
|
||||
$successes = array();
|
||||
$fails = array();
|
||||
$lowestfailedid = null;
|
||||
|
||||
if (!empty($events)) { // do nothing if there are no events to push
|
||||
$HttpSocket = new HttpSocket();
|
||||
|
||||
$this->loadModel('Attribute');
|
||||
// upload each event separately and keep the results in the $successes and $fails arrays
|
||||
foreach ($events as &$event) {
|
||||
$result = $this->Event->uploadEventToServer(
|
||||
$event,
|
||||
$this->Server->data,
|
||||
$HttpSocket);
|
||||
if (true == $result) {
|
||||
$successes[] = $event['Event']['id'];
|
||||
} else {
|
||||
$fails[$event['Event']['id']] = $result;
|
||||
}
|
||||
}
|
||||
if (count($fails) > 0) {
|
||||
// there are fails, take the lowest fail
|
||||
$lastpushedid = min(array_keys($fails));
|
||||
} else {
|
||||
// no fails, take the highest success
|
||||
$lastpushedid = max($successes);
|
||||
}
|
||||
// increment lastid based on the highest ID seen
|
||||
$this->Server->saveField('lastpushedid', $lastpushedid);
|
||||
}
|
||||
$this->set('successes', $successes);
|
||||
$this->set('fails', $fails);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,30 +1,30 @@
|
|||
<?php
|
||||
$xmlArray = array();
|
||||
foreach ($attributes as $key => $attribute) {
|
||||
// rearrange things to be compatible with the Xml::fromArray()
|
||||
$attributes[$key] = $attributes[$key]['Attribute'];
|
||||
|
||||
// cleanup the array from things we do not want to expose
|
||||
unset($attributes[$key]['Event']);
|
||||
// hide the private field is we are not in sync mode
|
||||
if ('true' != Configure::read('CyDefSIG.sync')) {
|
||||
unset($attributes[$key]['private']);
|
||||
}
|
||||
unset($attributes[$key]['sharing']);
|
||||
unset($attributes[$key]['cluster']);
|
||||
}
|
||||
|
||||
// display the XML to the user
|
||||
$xmlArray['response']['Attribute'] = $attributes;
|
||||
$xmlObject = Xml::fromArray($xmlArray, array('format' => 'tags'));
|
||||
echo $xmlObject->asXML();
|
||||
?><!--
|
||||
Please note that this XML page is a representation of the /attributes/index page.
|
||||
Because the /attributes/index page is paginated you will have a limited number of results.
|
||||
|
||||
You can for example ask: /attributes/index/limit:999.xml to get the 999 first records.
|
||||
(A maximum has been set to 9999)
|
||||
|
||||
|
||||
To export all the attributes at once, with their events, use the export functionality.
|
||||
<?php
|
||||
$xmlArray = array();
|
||||
foreach ($attributes as $key => $attribute) {
|
||||
// rearrange things to be compatible with the Xml::fromArray()
|
||||
$attributes[$key] = $attributes[$key]['Attribute'];
|
||||
|
||||
// cleanup the array from things we do not want to expose
|
||||
unset($attributes[$key]['Event']);
|
||||
// hide the private field is we are not in sync mode
|
||||
if ('true' != Configure::read('CyDefSIG.sync')) {
|
||||
unset($attributes[$key]['private']);
|
||||
}
|
||||
|
||||
unset($attributes[$key]['cluster']);
|
||||
}
|
||||
|
||||
// display the XML to the user
|
||||
$xmlArray['response']['Attribute'] = $attributes;
|
||||
$xmlObject = Xml::fromArray($xmlArray, array('format' => 'tags'));
|
||||
echo $xmlObject->asXML();
|
||||
?><!--
|
||||
Please note that this XML page is a representation of the /attributes/index page.
|
||||
Because the /attributes/index page is paginated you will have a limited number of results.
|
||||
|
||||
You can for example ask: /attributes/index/limit:999.xml to get the 999 first records.
|
||||
(A maximum has been set to 9999)
|
||||
|
||||
|
||||
To export all the attributes at once, with their events, use the export functionality.
|
||||
-->
|
|
@ -1,36 +1,37 @@
|
|||
<?php
|
||||
// TODO also output a kind of status code and data what was requested in the REST result
|
||||
$xmlArray = array();
|
||||
foreach ($events as $key => $event) {
|
||||
// rearrange things to be compatible with the Xml::fromArray()
|
||||
$events[$key] = $events[$key]['Event'];
|
||||
|
||||
// cleanup the array from things we do not want to expose
|
||||
unset($events[$key]['Event']);
|
||||
// hide the private field is we are not in sync mode
|
||||
if ('true' != Configure::read('CyDefSIG.sync')) {
|
||||
unset($events[$key]['private']);
|
||||
}
|
||||
unset($events[$key]['cluster']);
|
||||
unset($events[$key]['sharing']);
|
||||
// hide the org field is we are not in showorg mode
|
||||
if ('true' != Configure::read('CyDefSIG.showorg') && !$isAdmin) {
|
||||
unset($events[$key]['org']);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// display the XML to the user
|
||||
$xmlArray['response']['Event'] = $events;
|
||||
$xmlObject = Xml::fromArray($xmlArray, array('format' => 'tags'));
|
||||
echo $xmlObject->asXML();
|
||||
?><!--
|
||||
Please note that this XML page is a representation of the /events/index page.
|
||||
Because the /events/index page is paginated you will have a limited number of results.
|
||||
|
||||
You can for example ask: /events/index/limit:999.xml to get the 999 first records.
|
||||
(A maximum has been set to 9999)
|
||||
|
||||
|
||||
To export all the events at once, with their attributes, use the export functionality.
|
||||
<?php
|
||||
// TODO also output a kind of status code and data what was requested in the REST result
|
||||
$xmlArray = array();
|
||||
|
||||
foreach ($events as $key => $event) {
|
||||
// rearrange things to be compatible with the Xml::fromArray()
|
||||
$events[$key] = $events[$key]['Event'];
|
||||
unset($events[$key]['Event']);
|
||||
|
||||
// cleanup the array from things we do not want to expose
|
||||
unset($events[$key]['user_id']);
|
||||
unset($events[$key]['cluster']);
|
||||
unset($events[$key]['private']);
|
||||
unset($events[$key]['communitie']);
|
||||
// hide the org field is we are not in showorg mode
|
||||
if ('true' != Configure::read('CyDefSIG.showorg') && !$isAdmin) {
|
||||
unset($events[$key]['org']);
|
||||
unset($events[$key]['orgc']);
|
||||
unset($events[$key]['from']);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// display the XML to the user
|
||||
$xmlArray['response']['Event'] = $events;
|
||||
$xmlObject = Xml::fromArray($xmlArray, array('format' => 'tags'));
|
||||
echo $xmlObject->asXML();
|
||||
?><!--
|
||||
Please note that this XML page is a representation of the /events/index page.
|
||||
Because the /events/index page is paginated you will have a limited number of results.
|
||||
|
||||
You can for example ask: /events/index/limit:999.xml to get the 999 first records.
|
||||
(A maximum has been set to 9999)
|
||||
|
||||
|
||||
To export all the events at once, with their attributes, use the export functionality.
|
||||
-->
|
|
@ -1,41 +1,52 @@
|
|||
<?php
|
||||
$xmlArray = array();
|
||||
// rearrange things to be compatible with the Xml::fromArray()
|
||||
$event['Event']['Attribute'] = $event['Attribute'];
|
||||
unset($event['Attribute']);
|
||||
|
||||
// cleanup the array from things we do not want to expose
|
||||
// remove value1 and value2 from the output
|
||||
foreach ($event['Event']['Attribute'] as $key => $value) {
|
||||
unset($event['Event']['Attribute'][$key]['value1']);
|
||||
unset($event['Event']['Attribute'][$key]['value2']);
|
||||
unset($event['Event']['Attribute'][$key]['category_order']);
|
||||
|
||||
unset($event['Event']['Attribute'][$key]['private']);
|
||||
unset($event['Event']['Attribute'][$key]['communitie']);
|
||||
unset($event['Event']['Attribute'][$key]['cluster']);
|
||||
}
|
||||
|
||||
// hide the share fields is we are not in private mode
|
||||
unset($event['Event']['cluster']);
|
||||
unset($event['Event']['sharing']);
|
||||
foreach ($event['Event']['Attribute'] as $key => $value) {
|
||||
unset($event['Event']['Attribute'][$key]['sharing']);
|
||||
}
|
||||
|
||||
// hide the org field is we are not in showorg mode
|
||||
if ('true' != Configure::read('CyDefSIG.showorg') && !$isAdmin) {
|
||||
unset($event['Event']['org']);
|
||||
}
|
||||
|
||||
// build up a list of the related events
|
||||
if (isset($relatedEvents)) {
|
||||
foreach ($relatedEvents as $relatedEvent) {
|
||||
$event['Event']['RelatedEvent'][] = $relatedEvent['Event'];
|
||||
}
|
||||
}
|
||||
|
||||
// display the XML to the user
|
||||
$xmlArray['response']['Event'][] = $event['Event'];
|
||||
$xmlObject = Xml::fromArray($xmlArray, array('format' => 'tags'));
|
||||
echo $xmlObject->asXML();
|
||||
<?php
|
||||
$xmlArray = array();
|
||||
// rearrange things to be compatible with the Xml::fromArray()
|
||||
$event['Event']['Attribute'] = $event['Attribute'];
|
||||
unset($event['Attribute']);
|
||||
|
||||
// build up a list of the related events
|
||||
if (isset($relatedEvents)) {
|
||||
foreach ($relatedEvents as $relatedEvent) {
|
||||
$event['Event']['RelatedEvent'][] = $relatedEvent['Event'];
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// cleanup the array from things we do not want to expose
|
||||
//
|
||||
unset($event['Event']['user_id']);
|
||||
unset($event['Event']['cluster']);
|
||||
unset($event['Event']['private']);
|
||||
unset($event['Event']['communitie']);
|
||||
// hide the org field is we are not in showorg mode
|
||||
if ('true' != Configure::read('CyDefSIG.showorg') && !$isAdmin) {
|
||||
unset($event['Event']['org']);
|
||||
unset($event['Event']['orgc']);
|
||||
unset($event['Event']['from']);
|
||||
}
|
||||
|
||||
// remove value1 and value2 from the output
|
||||
foreach ($event['Event']['Attribute'] as $key => $value) {
|
||||
unset($event['Event']['Attribute'][$key]['private']);
|
||||
unset($event['Event']['Attribute'][$key]['communitie']);
|
||||
unset($event['Event']['Attribute'][$key]['cluster']);
|
||||
|
||||
unset($event['Event']['Attribute'][$key]['value1']);
|
||||
unset($event['Event']['Attribute'][$key]['value2']);
|
||||
}
|
||||
foreach ($event['Event']['RelatedEvent'] as $key => $value) {
|
||||
unset($event['Event']['RelatedEvent'][$key]['user_id']);
|
||||
unset($event['Event']['RelatedEvent'][$key]['private']);
|
||||
unset($event['Event']['RelatedEvent'][$key]['communitie']);
|
||||
unset($event['Event']['RelatedEvent'][$key]['cluster']);
|
||||
if ('true' != Configure::read('CyDefSIG.showorg') && !$isAdmin) {
|
||||
unset($event['Event']['RelatedEvent'][$key]['org']);
|
||||
unset($event['Event']['RelatedEvent'][$key]['orgc']);
|
||||
unset($event['Event']['RelatedEvent'][$key]['from']);
|
||||
}
|
||||
}
|
||||
|
||||
// display the XML to the user
|
||||
$xmlArray['response']['Event'][] = $event['Event'];
|
||||
$xmlObject = Xml::fromArray($xmlArray, array('format' => 'tags'));
|
||||
echo $xmlObject->asXML();
|
||||
|
|
Loading…
Reference in New Issue