From 36dabacfa1a4be46a75d434995e441afec893ff7 Mon Sep 17 00:00:00 2001 From: Jakub Onderka Date: Wed, 16 Dec 2020 10:07:36 +0100 Subject: [PATCH] new: [rest] Allow to search sightings by event or attribute UUID --- .../Component/RestResponseComponent.php | 4 +- app/Model/Sighting.php | 37 ++++++++++++------- 2 files changed, 25 insertions(+), 16 deletions(-) diff --git a/app/Controller/Component/RestResponseComponent.php b/app/Controller/Component/RestResponseComponent.php index f4d690de3..76dfe5c32 100644 --- a/app/Controller/Component/RestResponseComponent.php +++ b/app/Controller/Component/RestResponseComponent.php @@ -241,9 +241,9 @@ class RestResponseComponent extends Component 'optional' => array('type', 'source', 'timestamp', 'date', 'time') ), 'restSearch' => array( - 'description' => "Search MISP sightings using a list of filter parameters and return the data in the JSON format. The search is available on an event, attribute or instance level, just select the scope via the URL (/sighting/restSearch/event vs /sighting/restSearch/attribute vs /sighting/restSearch/). id MUST be provided if context is set.", + 'description' => "Search MISP sightings using a list of filter parameters and return the data in the JSON format. The search is available on an event, attribute or instance level, just select the scope via the URL (/sighting/restSearch/event vs /sighting/restSearch/attribute vs /sighting/restSearch/). id or uuid MUST be provided if context is set.", 'mandatory' => array('returnFormat'), - 'optional' => array('id', 'type', 'from', 'to', 'last', 'org_id', 'source', 'includeAttribute', 'includeEvent'), + 'optional' => array('id', 'uuid', 'type', 'from', 'to', 'last', 'org_id', 'source', 'includeAttribute', 'includeEvent'), 'params' => array('context') ), ), diff --git a/app/Model/Sighting.php b/app/Model/Sighting.php index b5303a870..9b7e88f44 100644 --- a/app/Model/Sighting.php +++ b/app/Model/Sighting.php @@ -789,9 +789,9 @@ class Sighting extends AppModel if (isset($filters['context']) && !in_array($filters['context'], $allowedContext, true)) { throw new MethodNotAllowedException(__('Invalid context.')); } - // ensure that an id is provided if context is set - if (!empty($filters['context']) && !isset($filters['id'])) { - throw new MethodNotAllowedException(__('An id must be provided if the context is set.')); + // ensure that an id or uuid is provided if context is set + if (!empty($filters['context']) && !(isset($filters['id']) || isset($filters['uuid'])) ) { + throw new MethodNotAllowedException(__('An ID or UUID must be provided if the context is set.')); } if (!isset($this->validFormats[$returnFormat][1])) { @@ -811,7 +811,9 @@ class Sighting extends AppModel } else { $timeCondition = '30d'; } - $conditions = $this->Attribute->setTimestampConditions($timeCondition, array(), $scope = 'Sighting.date_sighting'); + + $contain = []; + $conditions = $this->Attribute->setTimestampConditions($timeCondition, [], $scope = 'Sighting.date_sighting'); if (isset($filters['type'])) { $conditions['Sighting.type'] = $filters['type']; @@ -824,7 +826,11 @@ class Sighting extends AppModel } foreach ($filters['org_id'] as $k => $org_id) { if (Validation::uuid($org_id)) { - $org = $this->Organisation->find('first', array('conditions' => array('Organisation.uuid' => $org_id), 'recursive' => -1, 'fields' => array('Organisation.id'))); + $org = $this->Organisation->find('first', array( + 'conditions' => array('Organisation.uuid' => $org_id), + 'recursive' => -1, + 'fields' => array('Organisation.id'), + )); if (empty($org)) { $filters['org_id'][$k] = -1; } else { @@ -847,13 +853,23 @@ class Sighting extends AppModel } } + if (!empty($filters['uuid'])) { + if ($filters['context'] === 'attribute') { + $conditions['Attribute.uuid'] = $filters['uuid']; + $contain[] = 'Attribute'; + } elseif ($filters['context'] === 'event') { + $conditions['Event.uuid'] = $filters['uuid']; + $contain[] = 'Event'; + } + } + // fetch sightings matching the query $sightings = $this->find('list', array( 'recursive' => -1, 'conditions' => $conditions, 'fields' => array('id'), + 'contain' => $contain, )); - $sightings = array_values($sightings); $filters['requested_attributes'] = array('id', 'attribute_id', 'event_id', 'org_id', 'date_sighting', 'uuid', 'source', 'type'); @@ -879,9 +895,7 @@ class Sighting extends AppModel $filters['requested_attributes'] = array_merge($filters['requested_attributes'], array('event_uuid', 'event_orgc_id', 'event_org_id', 'event_info', 'event_Orgc_name')); $additional_event_added = true; } - if (!empty($sight)) { - array_push($allowedSightings, $sight); - } + $allowedSightings[] = $sight; } } @@ -889,11 +903,6 @@ class Sighting extends AppModel 'conditions' => array(), //result already filtered ); - if (!isset($this->validFormats[$returnFormat])) { - // this is where the new code path for the export modules will go - throw new NotFoundException('Invalid export format.'); - } - $exportToolParams = array( 'user' => $user, 'params' => $params,