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
$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];
if (!empty($validationErrors)) {
$event['errors'] = $validationErrors;

View File

@ -708,9 +708,7 @@ class Event extends AppModel {
if (!$found) return 403;
}
}
$serverModel = ClassRegistry::init('Server');
$servers = $serverModel->find('all', array('conditions' => array('push' => 1)));
$server = $serverModel->eventFilterPushableServers($event, array($server));
if (empty($server)) return 403;
$server = $server[0];
@ -785,13 +783,14 @@ class Event extends AppModel {
// rearrange things to be compatible with the Xml::fromArray()
$objectsToRearrange = array('Attribute', 'Orgc', 'SharingGroup', 'EventTag', 'Org');
foreach ($objectsToRearrange as $o) {
$event['Event'][$o] = $event[$o];
unset($event[$o]);
if (isset($event[$o])) {
$event['Event'][$o] = $event[$o];
unset($event[$o]);
}
}
// 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 ($event['Event']['EventTag'] as $kt => $tag) {
if (!$tag['Tag']['exportable']) unset($event['Event']['EventTag'][$kt]);
}
@ -993,22 +992,19 @@ class Event extends AppModel {
// includeAllTags: true will include the tags
// includeAttachments: true will attach the attachments to the attributes in the data field
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;
if ($options['eventid']) {
$this->id = $options['eventid'];
if (!$this->exists()) {
throw new NotFoundException(__('Invalid event'));
}
$conditions = array("Event.id" => $options['eventid']);
$conditions['AND'][] = array("Event.id" => $options['eventid']);
} else {
$conditions = array();
}
if (!isset($user['org_id'])) throw new Exception('There was an error with the user account.');
$isSiteAdmin = $user['Role']['perm_site_admin'];
if (isset($options['disableSiteAdmin']) && $options['disableSiteAdmin']) $isSiteAdmin = false;
$conditionsAttributes = array();
//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);
$conditions['AND']['OR'] = array(
'Event.org_id' => $user['org_id'],
@ -1017,6 +1013,7 @@ class Event extends AppModel {
'Event.distribution >' => 0,
'Event.distribution <' => 4,
Configure::read('MISP.unpublishedprivate') ? array('Event.published =' => 1) : array(),
$options['distribution'] !== false ? array('Event.distribution =' => $options['distribution']) : array(),
),
),
array(
@ -1024,6 +1021,7 @@ class Event extends AppModel {
'Event.sharing_group_id' => $sgids,
'Event.distribution' => 4,
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(
'Attribute.distribution >' => 0,
'Attribute.distribution !=' => 4,
$options['distribution'] !== false ? array('Attribute.distribution =' => $options['distribution']) : array(),
)),
array('AND' => array(
'Attribute.distribution' => 4,
'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']
);
@ -1042,6 +1042,8 @@ class Event extends AppModel {
if ($options['from']) $conditions['AND'][] = array('Event.date >=' => $options['from']);
if ($options['to']) $conditions['AND'][] = array('Event.date <=' => $options['to']);
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']) {
$conditions['AND'][] = array('Event.id' => $options['idList']);
@ -1068,7 +1070,7 @@ class Event extends AppModel {
$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']);
}

View File

@ -1114,7 +1114,7 @@ class Server extends AppModel {
$job = ClassRegistry::init('Job');
$job->read(null, $jobId);
}
$eventModel = ClassRegistry::init('Event');
$this->Event = ClassRegistry::init('Event');
$this->read(null, $id);
$url = $this->data['Server']['url'];
if (!$this->checkVersionCompatibility($id, $user)['canPush']) {
@ -1139,20 +1139,44 @@ class Server extends AppModel {
$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(
'conditions' => array(
$eventid_conditions_key => $eventid_conditions_value,
'Event.distribution >' => 0,
'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
'recursive' => -1, //int
'fields' => array('Event.id', 'Event.timestamp', 'Event.uuid'), //array of field names
);
$eventIds = $eventModel->find('all', $findParams);
$eventUUIDsFiltered = $this->filterEventIdsForPush($id, $HttpSocket, $eventIds);
if ($eventUUIDsFiltered === false) $pushFailed = true;
$eventIds = $this->Event->find('all', $findParams);
$eventUUIDsFiltered = $this->getEventIdsForPush($id, $HttpSocket, $eventIds, $user);
if ($eventUUIDsFiltered === false || empty($eventUUIDsFiltered)) $pushFailed = true;
if (!empty($eventUUIDsFiltered)) {
$eventCount = count($eventUUIDsFiltered);
//debug($eventIds);
@ -1162,11 +1186,10 @@ class Server extends AppModel {
$fails = array();
$lowestfailedid = null;
foreach ($eventUUIDsFiltered as $k => $eventUuid) {
$eventModel->recursive=1;
$eventModel->contain(array('Attribute'));
$event = $eventModel->findByUuid($eventUuid);
$event = $this->Event->fetchEvent($user, array('event_uuid' => $eventUuid, 'includeAttachments' => true));
$event = $event[0];
$event['Event']['locked'] = true;
$result = $eventModel->uploadEventToServer(
$result = $this->Event->uploadEventToServer(
$event,
$this->data,
$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($fails)) $fails = null;
@ -1206,7 +1229,7 @@ class Server extends AppModel {
'email' => $user['email'],
'action' => 'push',
'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.'
));
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) {
unset($eventIds[$k]['Event']['id']);
}
$server = $this->read(null, $id);
if (null == $HttpSocket) {
App::uses('SyncTool', 'Tools');
$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.
// returns the server objects that would allow the event to be pushed
public function eventFilterPushableServers($event, $servers) {
debug($event);
$eventTags = array();
$validServers = array();
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 (!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;
}

View File

@ -85,13 +85,9 @@ class SharingGroup extends AppModel {
public function fetchAllAuthorisedForServer($server) {
$conditions = array();
$ids = array();
//fetchAllSGsForServer($server_id)
$sgs = $this->find('list', array(
'recursive' => -1,
'fields' => array('id', 'name'),
'order' => 'name ASC',
'conditions' => $conditions,
));
$sgs = $this->SharingGroupOrg->fetchAllAuthorised($server['RemoteOrg']['id']);
$sgs = array_merge($sgs, $this->SharingGroupServer->fetchAllSGsForServer($server['Server']['id']));
return $sgs;
}
// 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,
'conditions' => array('server_id' => $server_id)
));
if (empty($sgs)) return array();
$sgids = array();
foreach ($sgs as &$temp) {
$sgids[] = $temp[$this->alias][$id];
$sgids[] = $temp[$this->alias]['id'];
}
return $sgids;
}

View File

@ -10,12 +10,15 @@
'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
if ($isSiteAdmin) :
echo $this->Form->input('organisation_type', array(
'label' => 'Organisation Type',
'label' => 'Remote Sync Organisation Type',
'options' => $organisationOptions,
));
?>
@ -45,6 +48,7 @@
echo $this->Form->input('authkey', array(
));
?>
<div class = "input clear" style="width:100%;"><hr /></div>
<div class = "input clear"></div>
<?php
echo $this->Form->input('push', array(