From 9fdd25b99cdbb7d7e7d059937da39eba1940525c Mon Sep 17 00:00:00 2001 From: Federico Foschini Date: Fri, 8 Mar 2024 16:52:08 +0100 Subject: [PATCH 1/3] Fixed a bug when an existing fields didn't match --- CHANGELOG.md | 3 ++ routing_test.py | 6 ++++ routingfilter/filters/filters.py | 29 +++++++++++++----- test_data/test_event_20.json | 10 +++++++ .../test_rule_32_multiple_fields_equal.json | 30 +++++++++++++++++++ 5 files changed, 71 insertions(+), 7 deletions(-) create mode 100644 test_data/test_event_20.json create mode 100644 test_data/test_rule_32_multiple_fields_equal.json diff --git a/CHANGELOG.md b/CHANGELOG.md index e864b17..75e77aa 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,4 +1,7 @@ ## 2.2.x +### 2.2.8 +#### Bugfix +* Fixed a bug when an existing fields didn't match ### 2.2.7 #### Bugfix * Fixed bug in exist filter diff --git a/routing_test.py b/routing_test.py index b56f5ae..4c4d8a8 100644 --- a/routing_test.py +++ b/routing_test.py @@ -40,6 +40,7 @@ def setUp(self): self.test_event_17 = load_test_data("test_event_17") self.test_event_18 = load_test_data("test_event_18") self.test_event_19 = load_test_data("test_event_19") + self.test_event_20 = load_test_data("test_event_20") self.test_event_with_list_1 = load_test_data("test_event_with_list_1") self.test_event_with_list_2 = load_test_data("test_event_with_list_2") @@ -474,6 +475,11 @@ def test_exist_source_ip(self): self.assertTrue(match) self.assertDictEqual(match[0].output, {"Workshop": {"workers_needed": 1}}) + def test_multiple_fields_equal(self): + self.routing.load_from_dicts([load_test_data("test_rule_32_multiple_fields_equal")]) + match = self.routing.match(self.test_event_20) + self.assertTrue(match) + self.assertDictEqual(match[0].output, {"Workshop": {"workers_needed": 1}}) if __name__ == "__main__": unittest.main() diff --git a/routingfilter/filters/filters.py b/routingfilter/filters/filters.py index 66aa13f..1a0926e 100644 --- a/routingfilter/filters/filters.py +++ b/routingfilter/filters/filters.py @@ -133,7 +133,10 @@ def match(self, event: DictQuery) -> bool: event_value = event.get(key, []) event_value = event_value if isinstance(event_value, list) else [event_value] for value in event_value: - return self._check_startswith(str(value)) + if self._check_startswith(str(value)): + return True + return False + def _check_startswith(self, value: str) -> bool: """ @@ -166,7 +169,9 @@ def match(self, event: DictQuery) -> bool: event_value = event.get(key, []) event_value = event_value if isinstance(event_value, list) else [event_value] for value in event_value: - return self._check_endswith(str(value)) + if self._check_endswith(str(value)): + return True + return False def _check_endswith(self, value): """ @@ -199,7 +204,9 @@ def match(self, event: DictQuery) -> bool: event_value = event.get(key, []) event_value = event_value if isinstance(event_value, list) else [event_value] for value in event_value: - return self._check_keyword(str(value)) + if self._check_keyword(str(value)): + return True + return False def _check_keyword(self, value: str) -> bool: """ @@ -247,7 +254,9 @@ def match(self, event: DictQuery) -> bool: event_value = event.get(key, []) event_value = event_value if isinstance(event_value, list) else [event_value] for value in event_value: - return self._check_regex(str(value)) + if self._check_regex(str(value)): + return True + return False def _check_regex(self, value: str) -> bool: """ @@ -299,7 +308,9 @@ def match(self, event: DictQuery) -> bool: event_value = event.get(key, []) event_value = event_value if isinstance(event_value, list) else [event_value] for ip_address in event_value: - return self._check_network(str(ip_address)) + if self._check_network(str(ip_address)): + return True + return False def _check_network(self, ip_address: str) -> bool: """ @@ -364,7 +375,9 @@ def match(self, event: DictQuery) -> bool: event_value = event.get(key, []) event_value = event_value if isinstance(event_value, list) else [event_value] for value in event_value: - return self._check_domain(str(value)) + if self._check_domain(str(value)): + return True + return False def _check_domain(self, value: str) -> bool: """ @@ -428,7 +441,9 @@ def match(self, event: DictQuery) -> bool: event_value = event.get(key, []) event_value = event_value if isinstance(event_value, list) else [event_value] for value in event_value: - return self._compare(value) + if self._compare(value): + return True + return False def _compare(self, value: float) -> bool: """ diff --git a/test_data/test_event_20.json b/test_data/test_event_20.json new file mode 100644 index 0000000..84ae094 --- /dev/null +++ b/test_data/test_event_20.json @@ -0,0 +1,10 @@ +{ + "tags": ["mountain_bike", "city_bike"], + "wheel_model": "Superlight", + "frame": "aluminium", + "gears": "1x12", + "suspension": "full", + "ip": "127.0.0.1", + "ip2": "100.0.0.1", + "price": 600 + } \ No newline at end of file diff --git a/test_data/test_rule_32_multiple_fields_equal.json b/test_data/test_rule_32_multiple_fields_equal.json new file mode 100644 index 0000000..6237b18 --- /dev/null +++ b/test_data/test_rule_32_multiple_fields_equal.json @@ -0,0 +1,30 @@ +{ + "streams": { + "rules": { + "mountain_bike": [ + { + "id": "equals-ffh4981", + "filters": [ + { + "id": 5540, + "key": [ + "ip2", + "ip", + "random_field" + ], + "type": "NETWORK", + "value": [ + "127.0.0.0/24" + ] + } + ], + "streams": { + "Workshop": { + "workers_needed": 1 + } + } + } + ] + } + } +} \ No newline at end of file From deb0beaa030c9f97628bd2e1f73a3d7b2fdb36c3 Mon Sep 17 00:00:00 2001 From: Federico Foschini Date: Fri, 8 Mar 2024 16:54:12 +0100 Subject: [PATCH 2/3] Added test --- routing_test.py | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/routing_test.py b/routing_test.py index 4c4d8a8..4749a8d 100644 --- a/routing_test.py +++ b/routing_test.py @@ -481,5 +481,9 @@ def test_multiple_fields_equal(self): self.assertTrue(match) self.assertDictEqual(match[0].output, {"Workshop": {"workers_needed": 1}}) + self.test_event_20["ip"] = "4.4.4.4" + match = self.routing.match(self.test_event_20) + self.assertFalse(match) + if __name__ == "__main__": unittest.main() From 86a14248a182a943f39da2d37fe729c9de69b541 Mon Sep 17 00:00:00 2001 From: Federico Foschini Date: Fri, 8 Mar 2024 16:58:07 +0100 Subject: [PATCH 3/3] Fixed linting --- docs/conf.py | 25 +++++++++++-------------- routing_test.py | 1 + routingfilter/filters/filters.py | 1 - 3 files changed, 12 insertions(+), 15 deletions(-) diff --git a/docs/conf.py b/docs/conf.py index d3f6a67..600053c 100644 --- a/docs/conf.py +++ b/docs/conf.py @@ -13,18 +13,19 @@ import os import sys import sphinx_rtd_theme + # sys.path.insert(0, os.path.abspath('.')) -sys.path.insert(0, os.path.abspath('..')) +sys.path.insert(0, os.path.abspath("..")) # -- Project information ----------------------------------------------------- -project = 'routingfilter' -copyright = '2020, Certego' -author = 'Certego S.r.l.' +project = "routingfilter" +copyright = "2020, Certego" +author = "Certego S.r.l." # The full version, including alpha/beta/rc tags -release = '1.0' +release = "1.0" master_doc = "index" # Tell ReadTheDocs the master doc file @@ -33,19 +34,15 @@ # Add any Sphinx extension module names here, as strings. They can be # extensions coming with Sphinx (named 'sphinx.ext.*') or your custom # ones. -extensions = [ - 'recommonmark', - 'sphinx_rtd_theme', - 'sphinx.ext.autodoc' -] +extensions = ["recommonmark", "sphinx_rtd_theme", "sphinx.ext.autodoc"] # Add any paths that contain templates here, relative to this directory. -templates_path = ['_templates'] +templates_path = ["_templates"] # List of patterns, relative to source directory, that match files and # directories to ignore when looking for source files. # This pattern also affects html_static_path and html_extra_path. -exclude_patterns = ['_build', 'Thumbs.db', '.DS_Store'] +exclude_patterns = ["_build", "Thumbs.db", ".DS_Store"] # -- Options for HTML output ------------------------------------------------- @@ -53,9 +50,9 @@ # The theme to use for HTML and HTML Help pages. See the documentation for # a list of builtin themes. # -html_theme = 'sphinx_rtd_theme' +html_theme = "sphinx_rtd_theme" # Add any paths that contain custom static files (such as style sheets) here, # relative to this directory. They are copied after the builtin static files, # so a file named "default.css" will overwrite the builtin "default.css". -html_static_path = ['_static'] \ No newline at end of file +html_static_path = ["_static"] diff --git a/routing_test.py b/routing_test.py index 4749a8d..d696629 100644 --- a/routing_test.py +++ b/routing_test.py @@ -485,5 +485,6 @@ def test_multiple_fields_equal(self): match = self.routing.match(self.test_event_20) self.assertFalse(match) + if __name__ == "__main__": unittest.main() diff --git a/routingfilter/filters/filters.py b/routingfilter/filters/filters.py index 1a0926e..e2b22e1 100644 --- a/routingfilter/filters/filters.py +++ b/routingfilter/filters/filters.py @@ -136,7 +136,6 @@ def match(self, event: DictQuery) -> bool: if self._check_startswith(str(value)): return True return False - def _check_startswith(self, value: str) -> bool: """