Further work on the sync

pull/762/head
Iglocska 2015-12-07 01:32:51 +01:00
parent fa7fa322cb
commit 3831ee2e90
6 changed files with 69 additions and 42 deletions

View File

@ -1175,7 +1175,7 @@ class EventsController extends AppController {
} }
// REST users want to see the newly created event // REST users want to see the newly created event
$results = $this->Event->fetchEvent($id, false, $this->Auth->user('org'), $this->_isSiteAdmin()); $results = $this->Event->fetchEvent($this->Auth->user(), array('eventid' => $id));
$event = &$results[0]; $event = &$results[0];
if (!empty($validationErrors)) { if (!empty($validationErrors)) {
$event['errors'] = $validationErrors; $event['errors'] = $validationErrors;

View File

@ -708,9 +708,7 @@ class Event extends AppModel {
if (!$found) return 403; if (!$found) return 403;
} }
} }
$serverModel = ClassRegistry::init('Server'); $serverModel = ClassRegistry::init('Server');
$servers = $serverModel->find('all', array('conditions' => array('push' => 1)));
$server = $serverModel->eventFilterPushableServers($event, array($server)); $server = $serverModel->eventFilterPushableServers($event, array($server));
if (empty($server)) return 403; if (empty($server)) return 403;
$server = $server[0]; $server = $server[0];
@ -785,13 +783,14 @@ class Event extends AppModel {
// rearrange things to be compatible with the Xml::fromArray() // rearrange things to be compatible with the Xml::fromArray()
$objectsToRearrange = array('Attribute', 'Orgc', 'SharingGroup', 'EventTag', 'Org'); $objectsToRearrange = array('Attribute', 'Orgc', 'SharingGroup', 'EventTag', 'Org');
foreach ($objectsToRearrange as $o) { foreach ($objectsToRearrange as $o) {
$event['Event'][$o] = $event[$o]; if (isset($event[$o])) {
unset($event[$o]); $event['Event'][$o] = $event[$o];
unset($event[$o]);
}
} }
// cleanup the array from things we do not want to expose // cleanup the array from things we do not want to expose
foreach (array('Org', 'org_id', 'orgc_id', 'proposal_email_lock', 'locked', 'org', 'orgc') as $field) unset($event['Event'][$field]); foreach (array('Org', 'org_id', 'orgc_id', 'proposal_email_lock', 'locked', 'org', 'orgc') as $field) unset($event['Event'][$field]);
foreach ($event['Event']['EventTag'] as $kt => $tag) { foreach ($event['Event']['EventTag'] as $kt => $tag) {
if (!$tag['Tag']['exportable']) unset($event['Event']['EventTag'][$kt]); if (!$tag['Tag']['exportable']) unset($event['Event']['EventTag'][$kt]);
} }
@ -993,22 +992,19 @@ class Event extends AppModel {
// includeAllTags: true will include the tags // includeAllTags: true will include the tags
// includeAttachments: true will attach the attachments to the attributes in the data field // includeAttachments: true will attach the attachments to the attributes in the data field
public function fetchEvent($user, $options = array()) { public function fetchEvent($user, $options = array()) {
$possibleOptions = array('eventid', 'idList', 'tags', 'from', 'to', 'last', 'to_ids', 'includeAllTags', 'includeAttachments'); $possibleOptions = array('eventid', 'idList', 'tags', 'from', 'to', 'last', 'to_ids', 'includeAllTags', 'includeAttachments', 'event_uuid', 'distribution', 'sharing_group_id', 'disableSiteAdmin');
foreach ($possibleOptions as &$opt) if (!isset($options[$opt])) $options[$opt] = false; foreach ($possibleOptions as &$opt) if (!isset($options[$opt])) $options[$opt] = false;
if ($options['eventid']) { if ($options['eventid']) {
$this->id = $options['eventid']; $conditions['AND'][] = array("Event.id" => $options['eventid']);
if (!$this->exists()) {
throw new NotFoundException(__('Invalid event'));
}
$conditions = array("Event.id" => $options['eventid']);
} else { } else {
$conditions = array(); $conditions = array();
} }
if (!isset($user['org_id'])) throw new Exception('There was an error with the user account.'); if (!isset($user['org_id'])) throw new Exception('There was an error with the user account.');
$isSiteAdmin = $user['Role']['perm_site_admin']; $isSiteAdmin = $user['Role']['perm_site_admin'];
if (isset($options['disableSiteAdmin']) && $options['disableSiteAdmin']) $isSiteAdmin = false;
$conditionsAttributes = array(); $conditionsAttributes = array();
//restricting to non-private or same org if the user is not a site-admin. //restricting to non-private or same org if the user is not a site-admin.
if (!$user['Role']['perm_site_admin']) { if (!$isSiteAdmin) {
$sgids = $this->SharingGroup->fetchAllAuthorised($user); $sgids = $this->SharingGroup->fetchAllAuthorised($user);
$conditions['AND']['OR'] = array( $conditions['AND']['OR'] = array(
'Event.org_id' => $user['org_id'], 'Event.org_id' => $user['org_id'],
@ -1017,6 +1013,7 @@ class Event extends AppModel {
'Event.distribution >' => 0, 'Event.distribution >' => 0,
'Event.distribution <' => 4, 'Event.distribution <' => 4,
Configure::read('MISP.unpublishedprivate') ? array('Event.published =' => 1) : array(), Configure::read('MISP.unpublishedprivate') ? array('Event.published =' => 1) : array(),
$options['distribution'] !== false ? array('Event.distribution =' => $options['distribution']) : array(),
), ),
), ),
array( array(
@ -1024,6 +1021,7 @@ class Event extends AppModel {
'Event.sharing_group_id' => $sgids, 'Event.sharing_group_id' => $sgids,
'Event.distribution' => 4, 'Event.distribution' => 4,
Configure::read('MISP.unpublishedprivate') ? array('Event.published =' => 1) : array(), Configure::read('MISP.unpublishedprivate') ? array('Event.published =' => 1) : array(),
$options['sharing_group_id'] !== false ? array('Event.sharing_group_id =' => $options['sharing_group_id']) : array(),
) )
) )
); );
@ -1031,10 +1029,12 @@ class Event extends AppModel {
array('AND' => array( array('AND' => array(
'Attribute.distribution >' => 0, 'Attribute.distribution >' => 0,
'Attribute.distribution !=' => 4, 'Attribute.distribution !=' => 4,
$options['distribution'] !== false ? array('Attribute.distribution =' => $options['distribution']) : array(),
)), )),
array('AND' => array( array('AND' => array(
'Attribute.distribution' => 4, 'Attribute.distribution' => 4,
'Attribute.sharing_group_id' => $sgids, 'Attribute.sharing_group_id' => $sgids,
$options['sharing_group_id'] !== false ? array('Attribute.sharing_group_id =' => $options['sharing_group_id']) : array(),
)), )),
'(SELECT events.org_id FROM events WHERE events.id = Attribute.event_id)' => $user['org_id'] '(SELECT events.org_id FROM events WHERE events.id = Attribute.event_id)' => $user['org_id']
); );
@ -1042,6 +1042,8 @@ class Event extends AppModel {
if ($options['from']) $conditions['AND'][] = array('Event.date >=' => $options['from']); if ($options['from']) $conditions['AND'][] = array('Event.date >=' => $options['from']);
if ($options['to']) $conditions['AND'][] = array('Event.date <=' => $options['to']); if ($options['to']) $conditions['AND'][] = array('Event.date <=' => $options['to']);
if ($options['last']) $conditions['AND'][] = array('Event.publish_timestamp >=' => $last); if ($options['last']) $conditions['AND'][] = array('Event.publish_timestamp >=' => $last);
if ($options['event_uuid']) $conditions['AND'][] = array('Event.uuid' => $options['event_uuid']);
if ($options['idList'] && !$options['tags']) { if ($options['idList'] && !$options['tags']) {
$conditions['AND'][] = array('Event.id' => $options['idList']); $conditions['AND'][] = array('Event.id' => $options['idList']);
@ -1068,7 +1070,7 @@ class Event extends AppModel {
$conditionsAttributes['AND'][] = array('Attribute.to_ids' => 1); $conditionsAttributes['AND'][] = array('Attribute.to_ids' => 1);
} }
if ($user['Server']['push_rules']) { if (isset($user['Server']) && $user['Server']['push_rules']) {
$conditions['AND'][] = $this->filterRulesToConditions($user['Server']['push_rules']); $conditions['AND'][] = $this->filterRulesToConditions($user['Server']['push_rules']);
} }

View File

@ -1114,7 +1114,7 @@ class Server extends AppModel {
$job = ClassRegistry::init('Job'); $job = ClassRegistry::init('Job');
$job->read(null, $jobId); $job->read(null, $jobId);
} }
$eventModel = ClassRegistry::init('Event'); $this->Event = ClassRegistry::init('Event');
$this->read(null, $id); $this->read(null, $id);
$url = $this->data['Server']['url']; $url = $this->data['Server']['url'];
if (!$this->checkVersionCompatibility($id, $user)['canPush']) { if (!$this->checkVersionCompatibility($id, $user)['canPush']) {
@ -1139,20 +1139,44 @@ class Server extends AppModel {
$this->redirect(array('action' => 'index')); $this->redirect(array('action' => 'index'));
} }
// Update distribution checks - move to fetchEvent()? $sgs = $this->Event->SharingGroup->find('all', array(
'recursive' => -1,
'contain' => array('Organisation', 'SharingGroupOrg', 'SharingGroupServer')
));
$sgIds = array();
foreach ($sgs as $k => $sg) {
if (!$this->Event->SharingGroup->checkIfServerInSG($sg, $this->data)) {
unset($sgs[$k]);
continue;
}
$sgIds[] = $sg['SharingGroup']['id'];
}
$findParams = array( $findParams = array(
'conditions' => array( 'conditions' => array(
$eventid_conditions_key => $eventid_conditions_value, $eventid_conditions_key => $eventid_conditions_value,
'Event.distribution >' => 0,
'Event.published' => 1, 'Event.published' => 1,
'Event.attribute_count >' => 0 'Event.attribute_count >' => 0,
'OR' => array(
array(
'AND' => array(
array('Event.distribution >' => 0),
array('Event.distribution <' => 4),
),
),
array(
'AND' => array(
'Event.distribution' => 4,
'Event.sharing_group_id' => $sgIds
),
)
)
), //array of conditions ), //array of conditions
'recursive' => -1, //int 'recursive' => -1, //int
'fields' => array('Event.id', 'Event.timestamp', 'Event.uuid'), //array of field names 'fields' => array('Event.id', 'Event.timestamp', 'Event.uuid'), //array of field names
); );
$eventIds = $eventModel->find('all', $findParams); $eventIds = $this->Event->find('all', $findParams);
$eventUUIDsFiltered = $this->filterEventIdsForPush($id, $HttpSocket, $eventIds); $eventUUIDsFiltered = $this->getEventIdsForPush($id, $HttpSocket, $eventIds, $user);
if ($eventUUIDsFiltered === false) $pushFailed = true; if ($eventUUIDsFiltered === false || empty($eventUUIDsFiltered)) $pushFailed = true;
if (!empty($eventUUIDsFiltered)) { if (!empty($eventUUIDsFiltered)) {
$eventCount = count($eventUUIDsFiltered); $eventCount = count($eventUUIDsFiltered);
//debug($eventIds); //debug($eventIds);
@ -1162,11 +1186,10 @@ class Server extends AppModel {
$fails = array(); $fails = array();
$lowestfailedid = null; $lowestfailedid = null;
foreach ($eventUUIDsFiltered as $k => $eventUuid) { foreach ($eventUUIDsFiltered as $k => $eventUuid) {
$eventModel->recursive=1; $event = $this->Event->fetchEvent($user, array('event_uuid' => $eventUuid, 'includeAttachments' => true));
$eventModel->contain(array('Attribute')); $event = $event[0];
$event = $eventModel->findByUuid($eventUuid);
$event['Event']['locked'] = true; $event['Event']['locked'] = true;
$result = $eventModel->uploadEventToServer( $result = $this->Event->uploadEventToServer(
$event, $event,
$this->data, $this->data,
$HttpSocket); $HttpSocket);
@ -1193,7 +1216,7 @@ class Server extends AppModel {
} }
} }
$this->syncProposals($HttpSocket, $this->data, null, null, $eventModel); $this->syncProposals($HttpSocket, $this->data, null, null, $this->Event);
if (!isset($successes)) $successes = null; if (!isset($successes)) $successes = null;
if (!isset($fails)) $fails = null; if (!isset($fails)) $fails = null;
@ -1206,7 +1229,7 @@ class Server extends AppModel {
'email' => $user['email'], 'email' => $user['email'],
'action' => 'push', 'action' => 'push',
'user_id' => $user['id'], 'user_id' => $user['id'],
'title' => 'Push to ' . $url . ' initiated by ' . $email, 'title' => 'Push to ' . $url . ' initiated by ' . $user['email'],
'change' => count($successes) . ' events pushed or updated. ' . count($fails) . ' events failed or didn\'t need an update.' 'change' => count($successes) . ' events pushed or updated. ' . count($fails) . ' events failed or didn\'t need an update.'
)); ));
if ($jobId) { if ($jobId) {
@ -1220,11 +1243,13 @@ class Server extends AppModel {
} }
} }
public function filterEventIdsForPush($id, $HttpSocket, $eventIds) { public function getEventIdsForPush($id, $HttpSocket, $eventIds, $user) {
$server = $this->read(null, $id);
$this->Event = ClassRegistry::init('Event');
foreach ($eventIds as $k => $event) { foreach ($eventIds as $k => $event) {
unset($eventIds[$k]['Event']['id']); unset($eventIds[$k]['Event']['id']);
} }
$server = $this->read(null, $id);
if (null == $HttpSocket) { if (null == $HttpSocket) {
App::uses('SyncTool', 'Tools'); App::uses('SyncTool', 'Tools');
$syncTool = new SyncTool(); $syncTool = new SyncTool();
@ -2258,7 +2283,6 @@ class Server extends AppModel {
// Loops through all servers and checks which servers' push rules don't conflict with the given event. // Loops through all servers and checks which servers' push rules don't conflict with the given event.
// returns the server objects that would allow the event to be pushed // returns the server objects that would allow the event to be pushed
public function eventFilterPushableServers($event, $servers) { public function eventFilterPushableServers($event, $servers) {
debug($event);
$eventTags = array(); $eventTags = array();
$validServers = array(); $validServers = array();
foreach ($event['EventTag'] as $tag) $eventTags[] = $tag['tag_id']; foreach ($event['EventTag'] as $tag) $eventTags[] = $tag['tag_id'];
@ -2276,7 +2300,7 @@ class Server extends AppModel {
if (!in_array($event['Event']['orgc_id'], $push_rules['orgs']['OR'])) continue; if (!in_array($event['Event']['orgc_id'], $push_rules['orgs']['OR'])) continue;
} }
if (!empty($push_rules['orgs']['NOT'])) { if (!empty($push_rules['orgs']['NOT'])) {
if (in_array($event['Event']['orgc_id'], $push_rules['orgs']['OR'])) continue; if (in_array($event['Event']['orgc_id'], $push_rules['orgs']['NOT'])) continue;
} }
$validServers[] = $server; $validServers[] = $server;
} }

View File

@ -85,13 +85,9 @@ class SharingGroup extends AppModel {
public function fetchAllAuthorisedForServer($server) { public function fetchAllAuthorisedForServer($server) {
$conditions = array(); $conditions = array();
$ids = array(); $ids = array();
//fetchAllSGsForServer($server_id) $sgs = $this->SharingGroupOrg->fetchAllAuthorised($server['RemoteOrg']['id']);
$sgs = $this->find('list', array( $sgs = array_merge($sgs, $this->SharingGroupServer->fetchAllSGsForServer($server['Server']['id']));
'recursive' => -1, return $sgs;
'fields' => array('id', 'name'),
'order' => 'name ASC',
'conditions' => $conditions,
));
} }
// returns a list of all sharing groups that the user is allowed to see // returns a list of all sharing groups that the user is allowed to see

View File

@ -104,9 +104,10 @@ class SharingGroupServer extends AppModel {
'recursive' => -1, 'recursive' => -1,
'conditions' => array('server_id' => $server_id) 'conditions' => array('server_id' => $server_id)
)); ));
if (empty($sgs)) return array();
$sgids = array(); $sgids = array();
foreach ($sgs as &$temp) { foreach ($sgs as &$temp) {
$sgids[] = $temp[$this->alias][$id]; $sgids[] = $temp[$this->alias]['id'];
} }
return $sgids; return $sgids;
} }

View File

@ -10,12 +10,15 @@
'label' => 'Instance name', 'label' => 'Instance name',
)); ));
?> ?>
<div class="input clear"></div> <div class="input clear" style="width:100%;">
<hr />
<p class="red">Information about the organisation that will receive the events, typically the remote instance's host organisation.</p>
</div>
<div class = "input clear"></div>
<?php <?php
if ($isSiteAdmin) : if ($isSiteAdmin) :
echo $this->Form->input('organisation_type', array( echo $this->Form->input('organisation_type', array(
'label' => 'Organisation Type', 'label' => 'Remote Sync Organisation Type',
'options' => $organisationOptions, 'options' => $organisationOptions,
)); ));
?> ?>
@ -45,6 +48,7 @@
echo $this->Form->input('authkey', array( echo $this->Form->input('authkey', array(
)); ));
?> ?>
<div class = "input clear" style="width:100%;"><hr /></div>
<div class = "input clear"></div> <div class = "input clear"></div>
<?php <?php
echo $this->Form->input('push', array( echo $this->Form->input('push', array(