diff --git a/core/db/elastic.py b/core/db/elastic.py index 177f037..0ed9668 100644 --- a/core/db/elastic.py +++ b/core/db/elastic.py @@ -14,6 +14,7 @@ from core.lib.parsing import ( QueryError, parse_date_time, parse_index, + parse_rule, parse_sentiment, parse_size, parse_sort, @@ -32,6 +33,7 @@ mapping = { "ts": {"type": "date", "format": "epoch_second"}, "match_ts": {"type": "date", "format": "iso8601"}, "file_tim": {"type": "date", "format": "epoch_millis"}, + "rule_uuid": {"type": "keyword"}, } } } @@ -271,7 +273,6 @@ class ElasticsearchBackend(StorageBackend): if self.async_client is None: await self.async_initialise() for match in matches: - print("INDEXING", match) result = await self.async_client.index( index=settings.INDEX_RULE_STORAGE, body=match ) @@ -439,10 +440,18 @@ class ElasticsearchBackend(StorageBackend): if isinstance(size, dict): return size - # I - Index - index = parse_index(request.user, query_params) - if isinstance(index, dict): - return index + rule_object = parse_rule(request.user, query_params) + if isinstance(rule_object, dict): + return rule_object + + if rule_object is not None: + index = settings.INDEX_RULE_STORAGE + add_bool.append({"rule_uuid": str(rule_object.id)}) + else: + # I - Index + index = parse_index(request.user, query_params) + if isinstance(index, dict): + return index # Q/T - Query/Tags search_query = self.parse_query( diff --git a/core/lib/parsing.py b/core/lib/parsing.py index 13efda3..31ce031 100644 --- a/core/lib/parsing.py +++ b/core/lib/parsing.py @@ -1,12 +1,40 @@ from datetime import datetime from django.conf import settings +from django.core.exceptions import ValidationError + +from core.models import NotificationRule class QueryError(Exception): pass +def parse_rule(user, query_params): + """ + Parse a rule query. + """ + if "rule" in query_params: + try: + rule_object = NotificationRule.objects.filter(id=query_params["rule"]) + except ValidationError: + message = "Rule is not a valid UUID" + message_class = "danger" + return {"message": message, "class": message_class} + if not rule_object.exists(): + message = "Rule does not exist" + message_class = "danger" + return {"message": message, "class": message_class} + rule_object = rule_object.first() + if not rule_object.user == user: + message = "Rule does not belong to you" + message_class = "danger" + return {"message": message, "class": message_class} + return rule_object + else: + return None + + def parse_size(query_params, sizes): if "size" in query_params: size = query_params["size"] diff --git a/core/lib/rules.py b/core/lib/rules.py index ca94bd1..6b71863 100644 --- a/core/lib/rules.py +++ b/core/lib/rules.py @@ -284,7 +284,6 @@ class NotificationRuleData(object): if not isinstance(matches, list): matches = [matches] matches_copy = matches.copy() - print("MATHCES COPY: ", matches_copy) match_ts = datetime.utcnow().isoformat() for match_index, _ in enumerate(matches_copy): matches_copy[match_index]["index"] = index diff --git a/core/static/js/column-shifter.js b/core/static/js/column-shifter.js index 327ceb3..1d1180a 100644 --- a/core/static/js/column-shifter.js +++ b/core/static/js/column-shifter.js @@ -66,6 +66,10 @@ $(document).ready(function(){ "file_size": "off", "lang_code": "off", "tokens": "off", + "rule_uuid": "off", + "index": "off", + "meta": "off", + "match_ts": "off", //"lang_name": "off", // "words_noun": "off", // "words_adj": "off", diff --git a/core/templates/partials/results_load.html b/core/templates/partials/results_load.html index 5f6903d..4538e26 100644 --- a/core/templates/partials/results_load.html +++ b/core/templates/partials/results_load.html @@ -14,7 +14,9 @@ {% endif %} - fetched {{ table.data|length }} hits in {{ took }}ms + fetched {{ table.data|length }} + {% if params.rule is None %} hits {% else %} rule hits for {{ params.rule }}{% endif %} + in {{ took }}ms {% if exemption is not None %} diff --git a/core/templates/partials/results_table.html b/core/templates/partials/results_table.html index 8a331b2..7a36e05 100644 --- a/core/templates/partials/results_table.html +++ b/core/templates/partials/results_table.html @@ -3,6 +3,7 @@ {% load static %} {% load joinsep %} {% load urlsafe %} +{% load pretty %} {% block table-wrapper %}
@@ -373,6 +374,10 @@ {% endfor %}
+ {% elif column.name == "meta" %} + +
{{ cell|pretty }}
+ {% else %} {% for item in object_list %} - {{ item.id }} + {{ item.id }} {{ item.user }} {{ item.name }} {{ item.interval }}s diff --git a/core/templates/window-content/results.html b/core/templates/window-content/results.html index b2fad2e..fca799d 100644 --- a/core/templates/window-content/results.html +++ b/core/templates/window-content/results.html @@ -7,7 +7,9 @@
{% endif %} -fetched {{ table.data|length }} hits in {{ took }}ms +fetched {{ table.data|length }} +{% if params.rule is None %} hits {% else %} rule hits for {{ params.rule }}{% endif %} +in {{ took }}ms {% if exemption is not None %} diff --git a/core/templates/window-content/search.html b/core/templates/window-content/search.html index 2b004a8..5ad2f36 100644 --- a/core/templates/window-content/search.html +++ b/core/templates/window-content/search.html @@ -404,4 +404,9 @@ value="{{ params.tags }}"> + {% if params.rule is not None %} +
+ +
+ {% endif %} \ No newline at end of file diff --git a/core/templatetags/pretty.py b/core/templatetags/pretty.py new file mode 100644 index 0000000..74e7401 --- /dev/null +++ b/core/templatetags/pretty.py @@ -0,0 +1,9 @@ +import orjson +from django import template + +register = template.Library() + + +@register.filter +def pretty(data): + return orjson.dumps(data, option=orjson.OPT_INDENT_2).decode("utf-8") diff --git a/core/views/ui/tables.py b/core/views/ui/tables.py index b96426b..962f6fb 100644 --- a/core/views/ui/tables.py +++ b/core/views/ui/tables.py @@ -76,6 +76,10 @@ class DrilldownTable(Table): file_md5 = Column() file_ext = Column() file_size = Column() + rule_uuid = Column() + index = Column() + meta = Column() + match_ts = Column() template_name = "ui/drilldown/table_results.html" paginate_by = settings.DRILLDOWN_RESULTS_PER_PAGE