@@ -43,7 +43,7 @@ def _evaluate_nested_event_pattern_on_dict(self, event_pattern, payload: dict) -
43
43
44
44
# TODO: maybe save/cache the flattened/expanded pattern?
45
45
flat_pattern_conditions = self .flatten_pattern (event_pattern )
46
- flat_payloads = self .flatten_payload (payload )
46
+ flat_payloads = self .flatten_payload (payload , flat_pattern_conditions )
47
47
48
48
return any (
49
49
all (
@@ -59,9 +59,6 @@ def _evaluate_nested_event_pattern_on_dict(self, event_pattern, payload: dict) -
59
59
for flat_pattern in flat_pattern_conditions
60
60
)
61
61
62
- def _build_event_branches (self , pattern , event ):
63
- pass
64
-
65
62
def _evaluate_condition (self , value , condition , field_exists : bool ):
66
63
if not isinstance (condition , dict ):
67
64
return field_exists and value == condition
@@ -150,7 +147,7 @@ def _evaluate_cidr(condition: str, value: str) -> bool:
150
147
151
148
@staticmethod
152
149
def _evaluate_wildcard (condition : str , value : str ) -> bool :
153
- return re .match (re .escape (condition ).replace ("\\ *" , ".+" ) + "$" , value )
150
+ return bool ( re .match (re .escape (condition ).replace ("\\ *" , ".+" ) + "$" , value ) )
154
151
155
152
@staticmethod
156
153
def _evaluate_numeric_condition (conditions : list , value : t .Any ) -> bool :
@@ -240,18 +237,24 @@ def _traverse_event_pattern(obj, array=None, parent_key=None) -> list:
240
237
return _traverse_event_pattern (nested_dict )
241
238
242
239
@staticmethod
243
- def flatten_payload (nested_dict : dict ) -> list [dict ]:
240
+ def flatten_payload (payload : dict , patterns : list [ dict ] ) -> list [dict ]:
244
241
"""
245
242
Takes a dictionary as input and will output the dictionary on a single level.
246
243
The dictionary can have lists containing other dictionaries, and one root level entry will be created for every
247
- item in a list.
244
+ item in a list if it corresponds to the entries of the patterns .
248
245
Input:
246
+ payload:
249
247
`{"field1": {
250
248
"field2: [
251
249
{"field3: "val1", "field4": "val2"},
252
250
{"field3: "val3", "field4": "val4"},
253
251
}
254
252
]}`
253
+ patterns:
254
+ `[
255
+ "field1.field2.field3": <condition>,
256
+ "field1.field2.field4": <condition>,
257
+ ]`
255
258
Output:
256
259
`[
257
260
{
@@ -263,16 +266,25 @@ def flatten_payload(nested_dict: dict) -> list[dict]:
263
266
"field1.field2.field4": "val4"
264
267
},
265
268
]`
266
- :param nested_dict: a (nested) dictionary
269
+ :param payload: a (nested) dictionary, the event payload
270
+ :param patterns: the flattened patterns from the EventPattern (see flatten_pattern)
267
271
:return: flatten_dict: a dictionary with no nested dict inside, flattened to a single level
268
272
"""
273
+ patterns_keys = {key for keys in patterns for key in keys }
274
+
275
+ def _is_key_in_patterns (key : str ) -> bool :
276
+ return key is None or any (pattern_key .startswith (key ) for pattern_key in patterns_keys )
269
277
270
278
def _traverse (_object : dict , array = None , parent_key = None ) -> list :
271
279
if isinstance (_object , dict ):
272
280
for key , values in _object .items ():
273
- # We update the parent key do that {"key1": {"key2": ""}} becomes "key1.key2"
281
+ # We update the parent key so that {"key1": {"key2": ""}} becomes "key1.key2"
274
282
_parent_key = f"{ parent_key } .{ key } " if parent_key else key
275
- array = _traverse (values , array , _parent_key )
283
+
284
+ # we make sure that we are building only the relevant parts of the payload related to the pattern
285
+ # the payload could be very complex, and the pattern only applies to part of it
286
+ if _is_key_in_patterns (_parent_key ):
287
+ array = _traverse (values , array , _parent_key )
276
288
277
289
elif isinstance (_object , list ):
278
290
if not _object :
@@ -282,7 +294,7 @@ def _traverse(_object: dict, array=None, parent_key=None) -> list:
282
294
array = [{** item , parent_key : _object } for item in array ]
283
295
return array
284
296
285
- return _traverse (nested_dict , array = [{}], parent_key = None )
297
+ return _traverse (payload , array = [{}], parent_key = None )
286
298
287
299
288
300
class EventPatternCompiler :
0 commit comments