Check hash of message when determining if it is a new match
This commit is contained in:
parent
66596cda42
commit
0cbd2d8a6f
|
@ -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):
|
||||
"""
|
||||
|
|
|
@ -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):
|
||||
"""
|
||||
|
|
Loading…
Reference in New Issue