From 3831ee2e900ec6ed66ad9f843eb2de785bb31fd9 Mon Sep 17 00:00:00 2001 From: Iglocska Date: Mon, 7 Dec 2015 01:32:51 +0100 Subject: [PATCH] Further work on the sync --- app/Controller/EventsController.php | 2 +- app/Model/Event.php | 28 +++++++------- app/Model/Server.php | 58 ++++++++++++++++++++--------- app/Model/SharingGroup.php | 10 ++--- app/Model/SharingGroupServer.php | 3 +- app/View/Servers/add.ctp | 10 +++-- 6 files changed, 69 insertions(+), 42 deletions(-) diff --git a/app/Controller/EventsController.php b/app/Controller/EventsController.php index 5a522e1b7..65d01cf05 100755 --- a/app/Controller/EventsController.php +++ b/app/Controller/EventsController.php @@ -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; diff --git a/app/Model/Event.php b/app/Model/Event.php index 3a8c14be5..4e31424ab 100755 --- a/app/Model/Event.php +++ b/app/Model/Event.php @@ -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']); } diff --git a/app/Model/Server.php b/app/Model/Server.php index 3073a0b65..6286b4a22 100755 --- a/app/Model/Server.php +++ b/app/Model/Server.php @@ -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; } diff --git a/app/Model/SharingGroup.php b/app/Model/SharingGroup.php index af75ead88..3ff1f87bf 100644 --- a/app/Model/SharingGroup.php +++ b/app/Model/SharingGroup.php @@ -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 diff --git a/app/Model/SharingGroupServer.php b/app/Model/SharingGroupServer.php index 44c7c9b26..50735c16b 100644 --- a/app/Model/SharingGroupServer.php +++ b/app/Model/SharingGroupServer.php @@ -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; } diff --git a/app/View/Servers/add.ctp b/app/View/Servers/add.ctp index aab5a8d0f..dbffa7502 100755 --- a/app/View/Servers/add.ctp +++ b/app/View/Servers/add.ctp @@ -10,12 +10,15 @@ 'label' => 'Instance name', )); ?> -
- +
+
+

Information about the organisation that will receive the events, typically the remote instance's host organisation.

+
+
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( )); ?> +

Form->input('push', array(