diff --git a/app/Model/Attribute.php b/app/Model/Attribute.php index 3ecd6080e..e4269ce98 100644 --- a/app/Model/Attribute.php +++ b/app/Model/Attribute.php @@ -3129,6 +3129,8 @@ class Attribute extends AppModel 'Attribute' => array( 'sharinggroup' => array('function' => 'set_filter_sharing_group'), 'value' => array('function' => 'set_filter_value'), + 'value1' => array('function' => 'set_filter_simple_attribute'), + 'value2' => array('function' => 'set_filter_simple_attribute'), 'category' => array('function' => 'set_filter_simple_attribute'), 'type' => array('function' => 'set_filter_type'), 'object_relation' => array('function' => 'set_filter_simple_attribute'), diff --git a/app/Model/Event.php b/app/Model/Event.php index 1c3454a6e..5278e700f 100755 --- a/app/Model/Event.php +++ b/app/Model/Event.php @@ -2711,17 +2711,8 @@ class Event extends AppModel public function set_filter_value(&$params, $conditions, $options) { if (!empty($params['value'])) { - $params[$options['filter']] = $this->convert_filters($params[$options['filter']]); - $conditions = $this->generic_add_filter($conditions, $params[$options['filter']], ['Attribute.value1', 'Attribute.value2']); - // Allows searching for ['value1' => [full, part1], 'value2' => [full, part2]] - if (is_string($params['value']) && strpos('|', $params['value']) !== false) { - $valueParts = explode('|', $params['value'], 2); - $convertedFilterVal1 = $this->convert_filters($valueParts[0]); - $convertedFilterVal2 = $this->convert_filters($valueParts[1]); - $conditionVal1 = $this->generic_add_filter([], $convertedFilterVal1, ['Attribute.value1'])['AND'][0]['OR']; - $conditionVal2 = $this->generic_add_filter([], $convertedFilterVal2, ['Attribute.value2'])['AND'][0]['OR']; - $conditions['AND'][0]['OR']['OR']['AND'] = [$conditionVal1, $conditionVal2]; - } + $params[$options['filter']] = $this->convert_filters($params['value']); + $conditions = $this->generic_add_filter($conditions, $params['value'], ['Attribute.value1', 'Attribute.value2']); } return $conditions; diff --git a/app/webroot/doc/openapi.yaml b/app/webroot/doc/openapi.yaml index 40ecefb44..25f644713 100644 --- a/app/webroot/doc/openapi.yaml +++ b/app/webroot/doc/openapi.yaml @@ -2822,6 +2822,10 @@ components: $ref: "#/components/schemas/LimitSearchFilter" value: $ref: "#/components/schemas/AttributeValue" + value1: + $ref: "#/components/schemas/AttributeValue" + value2: + $ref: "#/components/schemas/AttributeValue" type: $ref: "#/components/schemas/AttributeType" category: diff --git a/tests/testlive_comprehensive_local.py b/tests/testlive_comprehensive_local.py index e1b6359a2..bc9a28973 100644 --- a/tests/testlive_comprehensive_local.py +++ b/tests/testlive_comprehensive_local.py @@ -863,12 +863,49 @@ class TestComprehensive(unittest.TestCase): self.admin_misp_connector.delete_event(event) + def test_restsearch_composite_attribute(self): + event = create_simple_event() + attribute_1 = event.add_attribute('ip-src|port', '10.0.0.1|8080') + attribute_2 = event.add_attribute('ip-src|port', '10.0.0.2|8080') + event = self.user_misp_connector.add_event(event) + check_response(event) + + search_result = self._search_attribute({'value': '10.0.0.1', 'eventid': event.id}) + self.assertEqual(search_result['Attribute'][0]['uuid'], attribute_1.uuid) + self.assertEqual(len(search_result['Attribute']), 1) + + search_result = self._search_attribute({'value': '8080', 'eventid': event.id}) + self.assertEqual(len(search_result['Attribute']), 2) + + search_result = self._search_attribute({'value1': '10.0.0.1', 'eventid': event.id}) + self.assertEqual(len(search_result['Attribute']), 1) + self.assertEqual(search_result['Attribute'][0]['uuid'], attribute_1.uuid) + + search_result = self._search_attribute({'value1': '10.0.0.2', 'eventid': event.id}) + self.assertEqual(len(search_result['Attribute']), 1) + self.assertEqual(search_result['Attribute'][0]['uuid'], attribute_2.uuid) + + search_result = self._search_attribute({'value2': '8080', 'eventid': event.id}) + self.assertEqual(len(search_result['Attribute']), 2) + + search_result = self._search_attribute({'value1': '10.0.0.1', 'value2': '8080', 'eventid': event.id}) + self.assertEqual(len(search_result['Attribute']), 1) + self.assertEqual(search_result['Attribute'][0]['uuid'], attribute_1.uuid) + + self.admin_misp_connector.delete_event(event) + + def _search(self, query: dict): response = self.admin_misp_connector._prepare_request('POST', 'events/restSearch', data=query) response = self.admin_misp_connector._check_response(response) check_response(response) return response + def _search_attribute(self, query: dict): + response = self.admin_misp_connector._prepare_request('POST', 'attributes/restSearch', data=query) + response = self.admin_misp_connector._check_response(response) + check_response(response) + return response if __name__ == '__main__': unittest.main()