diff --git a/app/Config/config.default.php b/app/Config/config.default.php index 7545b3394..1d1700ba7 100644 --- a/app/Config/config.default.php +++ b/app/Config/config.default.php @@ -36,6 +36,7 @@ $config = array( 'take_ownership_xml_import' => false, 'unpublishedprivate' => false, 'disable_emailing' => false, + 'Attributes_Values_Filter_In_Event' => 'id, uuid, value, comment, type, category, Tag.name', ), 'GnuPG' => array( diff --git a/app/Controller/AppController.php b/app/Controller/AppController.php index 34736dba0..9c2040bb5 100755 --- a/app/Controller/AppController.php +++ b/app/Controller/AppController.php @@ -46,7 +46,7 @@ class AppController extends Controller { public $helpers = array('Utility'); - private $__queryVersion = '20'; + private $__queryVersion = '21'; public $pyMispVersion = '2.4.80'; public $phpmin = '5.6.5'; public $phprec = '7.0.16'; diff --git a/app/Controller/EventsController.php b/app/Controller/EventsController.php index 0b2c7e6d2..8beda1a42 100644 --- a/app/Controller/EventsController.php +++ b/app/Controller/EventsController.php @@ -714,6 +714,51 @@ class EventsController extends AppController { $this->layout = 'ajax'; } + /* + * Search for a value on an attribute level for a specific field. + * $attribute : (array) an attribute + * $fields : (array) list of keys in attribute to search in + * $searchValue : Value to search + * returns true on match + */ + private function __valueInFieldAttribute($attribute, $fields, $searchValue) { + foreach ($attribute as $k => $v){ // look in attributes line + if (is_string($v)) { + foreach ($fields as $field){ + if (strpos(".", $field) === false) { // check sub array after + // check for key in attribut + if (isset($attribute[$field])) { + $temp_value = strtolower($attribute[$field]); + $temp_search = strtolower($searchValue); + if(strpos($temp_value, $temp_search) !==false) { + return true; + } + } + } + } + } else { + // check for tag in attribut maybe for other thing later + if($k === 'AttributeTag'){ + foreach ($v as $tag) { + foreach ($fields as $field) { + if (strpos(strtolower($field), "tag.") !== false) { // check sub array + $tagKey = explode('tag.', strtolower($field))[1]; + if (isset($tag['Tag'][$tagKey])) { + $temp_value = strtolower($tag['Tag'][$tagKey]); + $temp_search = strtolower($searchValue); + if (strpos($temp_value, $temp_search) !==false) { + return true; + } + } + } + } + } + } + } + } + return false; + } + public function viewEventAttributes($id, $all = false) { if (isset($this->params['named']['focus'])) { $this->set('focus', $this->params['named']['focus']); @@ -725,6 +770,50 @@ class EventsController extends AppController { $results = $this->Event->fetchEvent($this->Auth->user(), $conditions); if (empty($results)) throw new NotFoundException('Invalid event'); $event = $results[0]; + + if (!empty($this->params['named']['searchFor'])) { + $filterColumns = empty(Configure::read('MISP.event_view_filter_fields')) ? 'id, uuid, value, comment, type, category, Tag.name' : Configure::read('MISP.event_view_filter_fields'); + $filterValue = array_map('trim', explode(",", $filterColumns)); + $validFilters = array('id', 'uuid', 'value', 'comment', 'type', 'category', 'Tag.name'); + foreach ($filterValue as $k => $v) { + if (!in_array($v, $validFilters)) { + unset($filterValue[$k]); + } + } + + // search in all attributes + foreach ($event['Attribute'] as $k => $attribute) { + if (!$this->__valueInFieldAttribute($attribute, $filterValue, $this->params['named']['searchFor'])) { + unset($event['Attribute'][$k]); + } + } + $event['Attribute'] = array_values($event['Attribute']); + + // search in all attributes + foreach ($event['ShadowAttribute'] as $k => $proposals) { + if (!$this->__valueInFieldAttribute($proposals, $filterValue, $this->params['named']['searchFor'])) { + unset($event['ShadowAttribute'][$k]); + } + } + $event['ShadowAttribute'] = array_values($event['ShadowAttribute']); + + // search for all attributes in object + foreach ($event['Object'] as $k => $object) { + foreach ($object['Attribute'] as $k2 => $attribute){ + if (!$this->__valueInFieldAttribute($attribute, $filterValue, $this->params['named']['searchFor'])) { + unset($event['Object'][$k]['Attribute'][$k2]); + } + } + if (count($event['Object'][$k]['Attribute']) == 0){ + // remove object if empty + unset($event['Object'][$k]); + } else { + $event['Object'][$k]['Attribute'] = array_values($event['Object'][$k]['Attribute']); + } + } + $event['Object'] = array_values($event['Object']); + $this->set('passedArgsArray', array('all' => $this->params['named']['searchFor'])); + } $emptyEvent = (empty($event['Object']) && empty($event['Attribute'])); $this->set('emptyEvent', $emptyEvent); $params = $this->Event->rearrangeEventForView($event, $this->passedArgs, $all); diff --git a/app/Model/Server.php b/app/Model/Server.php index 5aee6bcda..dfde2dec3 100644 --- a/app/Model/Server.php +++ b/app/Model/Server.php @@ -792,6 +792,14 @@ class Server extends AppModel { 'test' => null, 'type' => 'string', 'redacted' => true + ), + 'event_view_filter_fields' => array( + 'level' => 2, + 'description' => 'Specify which fields to filter on when you search on the event view. Default values are : "id, uuid, value, comment, type, category, Tag.name"', + 'value' => 'id, uuid, value, comment, type, category, Tag.name', + 'errorMessage' => '', + 'test' => null, + 'type' => 'string', ) ), 'GnuPG' => array( diff --git a/app/View/Elements/eventattribute.ctp b/app/View/Elements/eventattribute.ctp index 1f8f31d13..4f1592d33 100644 --- a/app/View/Elements/eventattribute.ctp +++ b/app/View/Elements/eventattribute.ctp @@ -33,6 +33,12 @@ } } } + $filtered = false; + if(isset($passedArgsArray)){ + if (count($passedArgsArray) > 0) { + $filtered = true; + } + } ?>