From ebbc7390d1703ec068fc17171070330ff5934cb4 Mon Sep 17 00:00:00 2001 From: Iglocska Date: Tue, 18 Aug 2015 19:51:41 +0200 Subject: [PATCH] Added event ID field to restSearch APIs, to assist #456 - eventid a new parameter for both event and attribute restsearch - these APIs now accept arrays in both json and xml format (you can send "eventid": ["15", "16"] instead of "eventid": "15&&16" in addition to the old functionality --- VERSION.json | 2 +- app/Controller/AttributesController.php | 19 +++++++++++-------- app/Controller/EventsController.php | 17 +++++++++++------ app/View/Events/automation.ctp | 12 +++++------- 4 files changed, 28 insertions(+), 22 deletions(-) diff --git a/VERSION.json b/VERSION.json index c87b5bd53..02617fe3d 100644 --- a/VERSION.json +++ b/VERSION.json @@ -1 +1 @@ -{"major":2, "minor":3, "hotfix":111} \ No newline at end of file +{"major":2, "minor":3, "hotfix":112} \ No newline at end of file diff --git a/app/Controller/AttributesController.php b/app/Controller/AttributesController.php index a726d47bc..37d4861be 100755 --- a/app/Controller/AttributesController.php +++ b/app/Controller/AttributesController.php @@ -1451,7 +1451,7 @@ class AttributesController extends AppController { // the last 4 fields accept the following operators: // && - you can use && between two search values to put a logical OR between them. for value, 1.1.1.1&&2.2.2.2 would find attributes with the value being either of the two. // ! - you can negate a search term. For example: google.com&&!mail would search for all attributes with value google.com but not ones that include mail. www.google.com would get returned, mail.google.com wouldn't. - public function restSearch($key='download', $value=false, $type=false, $category=false, $org=false, $tags=false, $from=false, $to=false, $last=false) { + public function restSearch($key='download', $value=false, $type=false, $category=false, $org=false, $tags=false, $from=false, $to=false, $last=false, $eventid=false) { if ($tags) $tags = str_replace(';', ':', $tags); if ($key!=null && $key!='download') { $user = $this->checkAuthUser($key); @@ -1477,15 +1477,15 @@ class AttributesController extends AppController { } else { throw new BadRequestException('Either specify the search terms in the url, or POST a json array / xml (with the root element being "request" and specify the correct accept and content type headers.'); } - $paramArray = array('value', 'type', 'category', 'org', 'tags', 'from', 'to', 'last'); + $paramArray = array('value', 'type', 'category', 'org', 'tags', 'from', 'to', 'last', 'eventid'); foreach ($paramArray as $p) { if (isset($data['request'][$p])) ${$p} = $data['request'][$p]; else ${$p} = null; } } - $simpleFalse = array('value' , 'type', 'category', 'org', 'tags', 'from', 'to', 'last'); + $simpleFalse = array('value' , 'type', 'category', 'org', 'tags', 'from', 'to', 'last', 'eventid'); foreach ($simpleFalse as $sF) { - if (${$sF} === 'null' || ${$sF} == '0' || ${$sF} === false || strtolower(${$sF}) === 'false') ${$sF} = false; + if (!is_array(${$sF}) && (${$sF} === 'null' || ${$sF} == '0' || ${$sF} === false || strtolower(${$sF})) === 'false') ${$sF} = false; } if ($from) $from = $this->Attribute->Event->dateFieldCheck($from); @@ -1506,11 +1506,11 @@ class AttributesController extends AppController { $this->loadModel('Attribute'); // add the values as specified in the 2nd parameter to the conditions $values = explode('&&', $value); - $parameters = array('value', 'type', 'category', 'org'); - + $parameters = array('value', 'type', 'category', 'org', 'eventid'); foreach ($parameters as $k => $param) { if (isset(${$parameters[$k]}) && ${$parameters[$k]}!=='null') { - $elements = explode('&&', ${$parameters[$k]}); + if (is_array(${$parameters[$k]})) $elements = ${$parameters[$k]}; + else $elements = explode('&&', ${$parameters[$k]}); foreach($elements as $v) { if (substr($v, 0, 1) == '!') { if ($parameters[$k] === 'value' && preg_match('@^(([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\.){3}([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])(\/(\d|[1-2]\d|3[0-2]))$@', substr($v, 1))) { @@ -1521,6 +1521,8 @@ class AttributesController extends AppController { } else { if ($parameters[$k] === 'org') { $subcondition['AND'][] = array('Event.' . $parameters[$k] . ' NOT LIKE' => '%'.substr($v, 1).'%'); + } elseif ($parameters[$k] === 'eventid') { + $subcondition['AND'][] = array('Attribute.event_id !=' => substr($v, 1)); } else { $subcondition['AND'][] = array('Attribute.' . $parameters[$k] . ' NOT LIKE' => '%'.substr($v, 1).'%'); } @@ -1534,6 +1536,8 @@ class AttributesController extends AppController { } else { if ($parameters[$k] === 'org') { $subcondition['OR'][] = array('Event.' . $parameters[$k] . ' LIKE' => '%'.$v.'%'); + } elseif ($parameters[$k] === 'eventid') { + $subcondition['OR'][] = array('Attribute.event_id' => $v); } else { $subcondition['OR'][] = array('Attribute.' . $parameters[$k] . ' LIKE' => '%'.$v.'%'); } @@ -1544,7 +1548,6 @@ class AttributesController extends AppController { $subcondition = array(); } } - // If we are looking for an attribute, we want to retrieve some extra data about the event to be able to check for the permissions. if (!$user['User']['siteAdmin']) { diff --git a/app/Controller/EventsController.php b/app/Controller/EventsController.php index e01c7e997..b70d16e47 100755 --- a/app/Controller/EventsController.php +++ b/app/Controller/EventsController.php @@ -2429,7 +2429,7 @@ class EventsController extends AppController { // the last 4 fields accept the following operators: // && - you can use && between two search values to put a logical OR between them. for value, 1.1.1.1&&2.2.2.2 would find attributes with the value being either of the two. // ! - you can negate a search term. For example: google.com&&!mail would search for all attributes with value google.com but not ones that include mail. www.google.com would get returned, mail.google.com wouldn't. - public function restSearch($key='download', $value=false, $type=false, $category=false, $org=false, $tags = false, $searchall=false, $from=false, $to=false, $last = false) { + public function restSearch($key='download', $value=false, $type=false, $category=false, $org=false, $tags=false, $searchall=false, $from=false, $to=false, $last=false, $eventid=false) { if ($key!='download') { $user = $this->checkAuthUser($key); } else { @@ -2453,16 +2453,16 @@ class EventsController extends AppController { } else { throw new BadRequestException('Either specify the search terms in the url, or POST a json array / xml (with the root element being "request" and specify the correct headers based on content type.'); } - $paramArray = array('value', 'type', 'category', 'org', 'tags', 'searchall', 'from', 'to', 'last'); + $paramArray = array('value', 'type', 'category', 'org', 'tags', 'searchall', 'from', 'to', 'last', 'eventid'); foreach ($paramArray as $p) { if (isset($data['request'][$p])) ${$p} = $data['request'][$p]; else ${$p} = null; } } - $simpleFalse = array('value' , 'type', 'category', 'org', 'tags', 'searchall', 'from', 'to', 'last'); + $simpleFalse = array('value' , 'type', 'category', 'org', 'tags', 'searchall', 'from', 'to', 'last', 'eventid'); foreach ($simpleFalse as $sF) { - if (${$sF} === 'null' || ${$sF} == '0' || ${$sF} === false || strtolower(${$sF}) === 'false') ${$sF} = false; + if (!is_array(${$sF}) && (${$sF} === 'null' || ${$sF} == '0' || ${$sF} === false || strtolower(${$sF})) === 'false') ${$sF} = false; } if ($from) $from = $this->Event->dateFieldCheck($from); @@ -2479,10 +2479,11 @@ class EventsController extends AppController { if (isset($searchall) && ($searchall == 1 || $searchall === true || $searchall == 'true')) { $eventIds = $this->__quickFilter($value); } else { - $parameters = array('value', 'type', 'category', 'org'); + $parameters = array('value', 'type', 'category', 'org', 'eventid'); foreach ($parameters as $k => $param) { if (isset(${$parameters[$k]})) { - $elements = explode('&&', ${$parameters[$k]}); + if (is_array(${$parameters[$k]})) $elements = ${$parameters[$k]}; + else $elements = explode('&&', ${$parameters[$k]}); foreach($elements as $v) { if (substr($v, 0, 1) == '!') { if ($parameters[$k] === 'value' && preg_match('@^(([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\.){3}([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])(\/(\d|[1-2]\d|3[0-2]))$@', substr($v, 1))) { @@ -2493,6 +2494,8 @@ class EventsController extends AppController { } else { if ($parameters[$k] === 'org') { $subcondition['AND'][] = array('Event.' . $parameters[$k] . ' NOT LIKE' => '%'.substr($v, 1).'%'); + } elseif ($parameters[$k] === 'eventid') { + $subcondition['AND'][] = array('Attribute.event_id !=' => substr($v, 1)); } else { $subcondition['AND'][] = array('Attribute.' . $parameters[$k] . ' NOT LIKE' => '%'.substr($v, 1).'%'); } @@ -2506,6 +2509,8 @@ class EventsController extends AppController { } else { if ($parameters[$k] === 'org') { $subcondition['OR'][] = array('Event.' . $parameters[$k] . ' LIKE' => '%'.$v.'%'); + } elseif ($parameters[$k] === 'eventid') { + $subcondition['OR'][] = array('Attribute.event_id' => $v); } else { $subcondition['OR'][] = array('Attribute.' . $parameters[$k] . ' LIKE' => '%'.$v.'%'); } diff --git a/app/View/Events/automation.ctp b/app/View/Events/automation.ctp index bb4d52ac2..52aab6053 100644 --- a/app/View/Events/automation.ctp +++ b/app/View/Events/automation.ctp @@ -242,6 +242,7 @@ Use semicolons instead (the search will automatically search for colons instead) from: Events with the date set to a date after the one specified in the from field (format: 2015-02-15)
to: Events with the date set to a date before the one specified in the to field (format: 2015-02-15)
last: Events published within the last x amount of time, where x can be defined in days, hours, minutes (for example 5d or 12h or 30m)
+eventid: The events that should be included / excluded from the search

The keywords false or null should be used for optional empty parameters in the URL.

For example, to find any event with the term "red october" mentioned, use the following syntax (the example is shown as a POST request instead of a GET, which is highly recommended):

POST to:

@@ -251,13 +252,9 @@ Use semicolons instead (the search will automatically search for colons instead) ?>

POST message payload (XML):

-

-<request><value>red october</value><searchall>1</searchall></request> -

+

red october1!15'); ?>

POST message payload (json):

-

-{"request": {"value":"red october","searchall":1}} -

+

{"request": {"value":"red october","searchall":1,"eventid":"!15"}}

To just return a list of attributes, use the following syntax:

value: Search for the given value in the attributes' value field.
type: The attribute type, any valid MISP attribute type is accepted.
@@ -269,10 +266,11 @@ Use semicolons instead (the search will automatically search for colons instead) from: Events with the date set to a date after the one specified in the from field (format: 2015-02-15)
to: Events with the date set to a date before the one specified in the to field (format: 2015-02-15)
last: Events published within the last x amount of time, where x can be defined in days, hours, minutes (for example 5d or 12h or 30m)
+eventid: The events that should be included / excluded from the search

The keywords false or null should be used for optional empty parameters in the URL.

 
 

value, type, category and org are optional. It is possible to search for several terms in each category by joining them with the '&&' operator. It is also possible to negate a term with the '!' operator. Please be aware the colons (:) cannot be used in the tag search. Use semicolons instead (the search will automatically search for colons instead).