Make notification rules queryable
This commit is contained in:
parent
df1e82c5f2
commit
81c8e34211
|
@ -14,6 +14,7 @@ from core.lib.parsing import (
|
||||||
QueryError,
|
QueryError,
|
||||||
parse_date_time,
|
parse_date_time,
|
||||||
parse_index,
|
parse_index,
|
||||||
|
parse_rule,
|
||||||
parse_sentiment,
|
parse_sentiment,
|
||||||
parse_size,
|
parse_size,
|
||||||
parse_sort,
|
parse_sort,
|
||||||
|
@ -32,6 +33,7 @@ mapping = {
|
||||||
"ts": {"type": "date", "format": "epoch_second"},
|
"ts": {"type": "date", "format": "epoch_second"},
|
||||||
"match_ts": {"type": "date", "format": "iso8601"},
|
"match_ts": {"type": "date", "format": "iso8601"},
|
||||||
"file_tim": {"type": "date", "format": "epoch_millis"},
|
"file_tim": {"type": "date", "format": "epoch_millis"},
|
||||||
|
"rule_uuid": {"type": "keyword"},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -271,7 +273,6 @@ class ElasticsearchBackend(StorageBackend):
|
||||||
if self.async_client is None:
|
if self.async_client is None:
|
||||||
await self.async_initialise()
|
await self.async_initialise()
|
||||||
for match in matches:
|
for match in matches:
|
||||||
print("INDEXING", match)
|
|
||||||
result = await self.async_client.index(
|
result = await self.async_client.index(
|
||||||
index=settings.INDEX_RULE_STORAGE, body=match
|
index=settings.INDEX_RULE_STORAGE, body=match
|
||||||
)
|
)
|
||||||
|
@ -439,10 +440,18 @@ class ElasticsearchBackend(StorageBackend):
|
||||||
if isinstance(size, dict):
|
if isinstance(size, dict):
|
||||||
return size
|
return size
|
||||||
|
|
||||||
# I - Index
|
rule_object = parse_rule(request.user, query_params)
|
||||||
index = parse_index(request.user, query_params)
|
if isinstance(rule_object, dict):
|
||||||
if isinstance(index, dict):
|
return rule_object
|
||||||
return index
|
|
||||||
|
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
|
# Q/T - Query/Tags
|
||||||
search_query = self.parse_query(
|
search_query = self.parse_query(
|
||||||
|
|
|
@ -1,12 +1,40 @@
|
||||||
from datetime import datetime
|
from datetime import datetime
|
||||||
|
|
||||||
from django.conf import settings
|
from django.conf import settings
|
||||||
|
from django.core.exceptions import ValidationError
|
||||||
|
|
||||||
|
from core.models import NotificationRule
|
||||||
|
|
||||||
|
|
||||||
class QueryError(Exception):
|
class QueryError(Exception):
|
||||||
pass
|
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):
|
def parse_size(query_params, sizes):
|
||||||
if "size" in query_params:
|
if "size" in query_params:
|
||||||
size = query_params["size"]
|
size = query_params["size"]
|
||||||
|
|
|
@ -284,7 +284,6 @@ class NotificationRuleData(object):
|
||||||
if not isinstance(matches, list):
|
if not isinstance(matches, list):
|
||||||
matches = [matches]
|
matches = [matches]
|
||||||
matches_copy = matches.copy()
|
matches_copy = matches.copy()
|
||||||
print("MATHCES COPY: ", matches_copy)
|
|
||||||
match_ts = datetime.utcnow().isoformat()
|
match_ts = datetime.utcnow().isoformat()
|
||||||
for match_index, _ in enumerate(matches_copy):
|
for match_index, _ in enumerate(matches_copy):
|
||||||
matches_copy[match_index]["index"] = index
|
matches_copy[match_index]["index"] = index
|
||||||
|
|
|
@ -66,6 +66,10 @@ $(document).ready(function(){
|
||||||
"file_size": "off",
|
"file_size": "off",
|
||||||
"lang_code": "off",
|
"lang_code": "off",
|
||||||
"tokens": "off",
|
"tokens": "off",
|
||||||
|
"rule_uuid": "off",
|
||||||
|
"index": "off",
|
||||||
|
"meta": "off",
|
||||||
|
"match_ts": "off",
|
||||||
//"lang_name": "off",
|
//"lang_name": "off",
|
||||||
// "words_noun": "off",
|
// "words_noun": "off",
|
||||||
// "words_adj": "off",
|
// "words_adj": "off",
|
||||||
|
|
|
@ -14,7 +14,9 @@
|
||||||
</span>
|
</span>
|
||||||
{% endif %}
|
{% 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 %}
|
{% if exemption is not None %}
|
||||||
<span class="icon has-tooltip-bottom" data-tooltip="God mode">
|
<span class="icon has-tooltip-bottom" data-tooltip="God mode">
|
||||||
|
|
|
@ -3,6 +3,7 @@
|
||||||
{% load static %}
|
{% load static %}
|
||||||
{% load joinsep %}
|
{% load joinsep %}
|
||||||
{% load urlsafe %}
|
{% load urlsafe %}
|
||||||
|
{% load pretty %}
|
||||||
{% block table-wrapper %}
|
{% block table-wrapper %}
|
||||||
<script src="{% static 'js/column-shifter.js' %}"></script>
|
<script src="{% static 'js/column-shifter.js' %}"></script>
|
||||||
<div id="drilldown-table" class="column-shifter-container" style="position:relative; z-index:1;">
|
<div id="drilldown-table" class="column-shifter-container" style="position:relative; z-index:1;">
|
||||||
|
@ -373,6 +374,10 @@
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
</div>
|
</div>
|
||||||
</td>
|
</td>
|
||||||
|
{% elif column.name == "meta" %}
|
||||||
|
<td class="{{ column.name }}">
|
||||||
|
<pre>{{ cell|pretty }}</pre>
|
||||||
|
</td>
|
||||||
{% else %}
|
{% else %}
|
||||||
<td class="{{ column.name }}">
|
<td class="{{ column.name }}">
|
||||||
<a
|
<a
|
||||||
|
|
|
@ -22,7 +22,7 @@
|
||||||
</thead>
|
</thead>
|
||||||
{% for item in object_list %}
|
{% for item in object_list %}
|
||||||
<tr>
|
<tr>
|
||||||
<td>{{ item.id }}</td>
|
<td><a href="/search/?rule={{ item.id }}&query=*&source=all">{{ item.id }}</a></td>
|
||||||
<td>{{ item.user }}</td>
|
<td>{{ item.user }}</td>
|
||||||
<td>{{ item.name }}</td>
|
<td>{{ item.name }}</td>
|
||||||
<td>{{ item.interval }}s</td>
|
<td>{{ item.interval }}s</td>
|
||||||
|
|
|
@ -7,7 +7,9 @@
|
||||||
</span>
|
</span>
|
||||||
{% endif %}
|
{% 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 %}
|
{% if exemption is not None %}
|
||||||
<span class="icon has-tooltip-bottom" data-tooltip="God mode">
|
<span class="icon has-tooltip-bottom" data-tooltip="God mode">
|
||||||
|
|
|
@ -404,4 +404,9 @@
|
||||||
value="{{ params.tags }}">
|
value="{{ params.tags }}">
|
||||||
</div>
|
</div>
|
||||||
<div class="is-hidden"></div>
|
<div class="is-hidden"></div>
|
||||||
|
{% if params.rule is not None %}
|
||||||
|
<div style="display:none;">
|
||||||
|
<input name="rule" value="{{ params.rule }}">
|
||||||
|
</div>
|
||||||
|
{% endif %}
|
||||||
</form>
|
</form>
|
|
@ -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")
|
|
@ -76,6 +76,10 @@ class DrilldownTable(Table):
|
||||||
file_md5 = Column()
|
file_md5 = Column()
|
||||||
file_ext = Column()
|
file_ext = Column()
|
||||||
file_size = Column()
|
file_size = Column()
|
||||||
|
rule_uuid = Column()
|
||||||
|
index = Column()
|
||||||
|
meta = Column()
|
||||||
|
match_ts = Column()
|
||||||
|
|
||||||
template_name = "ui/drilldown/table_results.html"
|
template_name = "ui/drilldown/table_results.html"
|
||||||
paginate_by = settings.DRILLDOWN_RESULTS_PER_PAGE
|
paginate_by = settings.DRILLDOWN_RESULTS_PER_PAGE
|
||||||
|
|
Loading…
Reference in New Issue