Check hash of message when determining if it is a new match

This commit is contained in:
Mark Veidemanis 2023-02-02 18:58:40 +00:00
parent 66596cda42
commit 0cbd2d8a6f
Signed by: m
GPG Key ID: 5ACFCEED46C0904F
2 changed files with 19 additions and 5 deletions

View File

@ -10,6 +10,7 @@ except ImportError:
import orjson
from asgiref.sync import async_to_sync
from siphashc import siphash
from core.lib.notify import sendmsg
from core.lib.parsing import parse_index, parse_source
@ -205,8 +206,13 @@ class NotificationRuleData(object):
Store a match result.
Accepts None for the index to set all indices.
:param index: the index to store the match for, can be None
:param match: True or False, indicating if the rule matched
:param match: the object that matched
"""
if match is not False:
# Dump match to JSON while sorting the keys
match_normalised = orjson.dumps(match, option=orjson.OPT_SORT_KEYS)
match = siphash(self.db.hash_key, match_normalised)
if self.object.match is None:
self.object.match = {}
if not isinstance(self.object.match, dict):
@ -220,7 +226,7 @@ class NotificationRuleData(object):
self.object.save()
log.debug(f"Stored match: {index} - {match}")
def get_match(self, index=None):
def get_match(self, index=None, match=None):
"""
Get a match result for an index.
If the index is None, it will return True if any index has a match.
@ -237,6 +243,13 @@ class NotificationRuleData(object):
# Check if we have any matches on all indices
return any(self.object.match.values())
# Check if it's the same hash
if match is not None:
match_normalised = orjson.dumps(match, option=orjson.OPT_SORT_KEYS)
match = siphash(self.db.hash_key, match_normalised)
hash_matches = self.object.match.get(index) == match
return hash_matches
return self.object.match.get(index)
def format_aggs(self, aggs):
@ -268,13 +281,13 @@ class NotificationRuleData(object):
:param message: the message object that matched
:param aggs: the aggregations that matched
"""
current_match = self.get_match(index)
current_match = self.get_match(index, message)
log.debug(f"Rule matched: {index} - current match: {current_match}")
if current_match is False:
# Matched now, but not before
meta["matched"] = self.format_aggs(meta["aggs"])
rule_notify(self.object, index, message, meta)
self.store_match(index, True)
self.store_match(index, message)
def rule_no_match(self, index=None):
"""

View File

@ -203,7 +203,8 @@ class NotificationRule(models.Model):
Get the total number of matches for this rule.
"""
if isinstance(self.match, dict):
return f"{sum(list(self.match.values()))}/{len(self.match)}"
truthy_values = [x for x in self.match.values() if x is not False]
return f"{len(truthy_values)}/{len(self.match)}"
def get_notification_settings(self, check=True):
"""