howler-api 2.13.0.dev341__py3-none-any.whl → 2.13.0.dev342__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Potentially problematic release.
This version of howler-api might be problematic. Click here for more details.
- howler/api/v1/search.py +74 -1
- {howler_api-2.13.0.dev341.dist-info → howler_api-2.13.0.dev342.dist-info}/METADATA +1 -1
- {howler_api-2.13.0.dev341.dist-info → howler_api-2.13.0.dev342.dist-info}/RECORD +5 -5
- {howler_api-2.13.0.dev341.dist-info → howler_api-2.13.0.dev342.dist-info}/WHEEL +0 -0
- {howler_api-2.13.0.dev341.dist-info → howler_api-2.13.0.dev342.dist-info}/entry_points.txt +0 -0
howler/api/v1/search.py
CHANGED
|
@@ -1,6 +1,9 @@
|
|
|
1
|
+
import re
|
|
2
|
+
from copy import deepcopy
|
|
1
3
|
from typing import Any, Union
|
|
2
4
|
|
|
3
5
|
from elasticsearch import BadRequestError
|
|
6
|
+
from elasticsearch._sync.client.indices import IndicesClient
|
|
4
7
|
from flask import request
|
|
5
8
|
from sigma.backends.elasticsearch import LuceneBackend
|
|
6
9
|
from sigma.rule import SigmaRule
|
|
@@ -14,7 +17,7 @@ from howler.common.swagger import generate_swagger_docs
|
|
|
14
17
|
from howler.datastore.exceptions import SearchException
|
|
15
18
|
from howler.helper.search import get_collection, get_default_sort, has_access_control, list_all_fields
|
|
16
19
|
from howler.security import api_login
|
|
17
|
-
from howler.services import hit_service
|
|
20
|
+
from howler.services import hit_service, lucene_service
|
|
18
21
|
|
|
19
22
|
SUB_API = "search"
|
|
20
23
|
search_api = make_subapi_blueprint(SUB_API, api_version=1)
|
|
@@ -146,6 +149,76 @@ def search(index, **kwargs):
|
|
|
146
149
|
return bad_request(err=f"SearchException: {e}")
|
|
147
150
|
|
|
148
151
|
|
|
152
|
+
@generate_swagger_docs()
|
|
153
|
+
@search_api.route("/<index>/explain", methods=["GET", "POST"])
|
|
154
|
+
@api_login(required_priv=["R"])
|
|
155
|
+
def explain_query(index, **kwargs):
|
|
156
|
+
"""Search through specified index for a given Lucene query. Uses Lucene search syntax for query.
|
|
157
|
+
|
|
158
|
+
Variables:
|
|
159
|
+
index => Index to explain against (hit, user,...)
|
|
160
|
+
|
|
161
|
+
Arguments:
|
|
162
|
+
query => Lucene Query to explain
|
|
163
|
+
|
|
164
|
+
Data Block:
|
|
165
|
+
# Note that the data block is for POST requests only!
|
|
166
|
+
{
|
|
167
|
+
"query": "id:*", # Lucene Query to explain
|
|
168
|
+
}
|
|
169
|
+
|
|
170
|
+
|
|
171
|
+
Result Example:
|
|
172
|
+
{
|
|
173
|
+
'valid': True,
|
|
174
|
+
'explanations': [
|
|
175
|
+
{
|
|
176
|
+
'valid': True,
|
|
177
|
+
'explanation': 'ConstantScore(FieldExistsQuery [field=id])'
|
|
178
|
+
}
|
|
179
|
+
]
|
|
180
|
+
}
|
|
181
|
+
"""
|
|
182
|
+
user = kwargs["user"]
|
|
183
|
+
collection = get_collection(index, user)
|
|
184
|
+
|
|
185
|
+
if collection is None:
|
|
186
|
+
return bad_request(err=f"Not a valid index to explain: {index}")
|
|
187
|
+
|
|
188
|
+
fields = ["query"]
|
|
189
|
+
multi_fields: list[str] = []
|
|
190
|
+
|
|
191
|
+
params, req_data = generate_params(request, fields, multi_fields)
|
|
192
|
+
|
|
193
|
+
params["as_obj"] = False
|
|
194
|
+
|
|
195
|
+
query = req_data.get("query", None)
|
|
196
|
+
if not query:
|
|
197
|
+
return bad_request(err="There was no query.")
|
|
198
|
+
|
|
199
|
+
# This regex checks for lucene phrases (i.e. the "Example Analytic" part of howler.analytic:"Example Analytic")
|
|
200
|
+
# And then escapes them.
|
|
201
|
+
# https://regex101.com/r/8u5F6a/1
|
|
202
|
+
escaped_lucene = re.sub(r'((:\()?(".+?")(\)?))', lucene_service.replace_lucene_phrase, query)
|
|
203
|
+
|
|
204
|
+
try:
|
|
205
|
+
indices_client = IndicesClient(datastore().hit.datastore.client)
|
|
206
|
+
|
|
207
|
+
result = deepcopy(
|
|
208
|
+
indices_client.validate_query(q=escaped_lucene, explain=True, index=collection().index_name).body
|
|
209
|
+
)
|
|
210
|
+
|
|
211
|
+
del result["_shards"]
|
|
212
|
+
|
|
213
|
+
for explanation in result["explanations"]:
|
|
214
|
+
del explanation["index"]
|
|
215
|
+
|
|
216
|
+
return ok(result)
|
|
217
|
+
except Exception as e:
|
|
218
|
+
logger.exception("Exception on query explanation")
|
|
219
|
+
return bad_request(err=f"Exception: {e}")
|
|
220
|
+
|
|
221
|
+
|
|
149
222
|
@generate_swagger_docs()
|
|
150
223
|
@search_api.route("/<index>/eql", methods=["GET", "POST"])
|
|
151
224
|
@api_login(required_priv=["R"])
|
|
@@ -24,7 +24,7 @@ howler/api/v1/help.py,sha256=hqBvzW-DYX-I4Q85dbCQgpHsXyWDXp06a1fE9zhFMH4,823
|
|
|
24
24
|
howler/api/v1/hit.py,sha256=HKaI72k7VC0v4QPjE2zcAV6jizvY2ZWEpk1BiAklvgU,34031
|
|
25
25
|
howler/api/v1/notebook.py,sha256=-cahdJ9u1lAB_nheztayHKtXvoPZcj04N8nqQ2U-HLo,2015
|
|
26
26
|
howler/api/v1/overview.py,sha256=e-WiHuMvOPy8Y7xIGnceagdI0_jebqlgDxi6GE6tfaA,4999
|
|
27
|
-
howler/api/v1/search.py,sha256=
|
|
27
|
+
howler/api/v1/search.py,sha256=24r1vaYaxDhddzDR-c5dBdRKyag6aIggvHSWPWudqN8,26372
|
|
28
28
|
howler/api/v1/template.py,sha256=oexzUpAMVdgI6IOXITPx0iEfZIVP-kvlExRdFd6QVdk,5769
|
|
29
29
|
howler/api/v1/tool.py,sha256=6CN5LIXgxaAvxEHE6s4IFtAEhQo_zBLtl6ghbM8whjE,6737
|
|
30
30
|
howler/api/v1/user.py,sha256=YQh6eCAi4bsC_w9eGX0ZgnLoFL4z4efEc1knJsZhj4k,13842
|
|
@@ -194,7 +194,7 @@ howler/utils/path.py,sha256=DfOU4i4zSs4wchHoE8iE7aWVLkTxiC_JRGepF2hBYBk,690
|
|
|
194
194
|
howler/utils/socket_utils.py,sha256=nz1SklC9xBHUSfHyTJjpq3mbozX1GDf01WzdGxfaUII,2212
|
|
195
195
|
howler/utils/str_utils.py,sha256=HE8Hqh2HlOLaj16w0H9zKOyDJLp-f1LQ50y_WeGZaEk,8389
|
|
196
196
|
howler/utils/uid.py,sha256=p9dsqyvZ-lpiAuzZWCPCeEM99kdk0Ly9czf04HNdSuw,1341
|
|
197
|
-
howler_api-2.13.0.
|
|
198
|
-
howler_api-2.13.0.
|
|
199
|
-
howler_api-2.13.0.
|
|
200
|
-
howler_api-2.13.0.
|
|
197
|
+
howler_api-2.13.0.dev342.dist-info/METADATA,sha256=k-G9s9TnSg4YhLHLrWrci6m16oU21RbtaJ1kwD_F-3M,2805
|
|
198
|
+
howler_api-2.13.0.dev342.dist-info/WHEEL,sha256=zp0Cn7JsFoX2ATtOhtaFYIiE2rmFAD4OcMhtUki8W3U,88
|
|
199
|
+
howler_api-2.13.0.dev342.dist-info/entry_points.txt,sha256=Lu9SBGvwe0wczJHmc-RudC24lmQk7tv3ZBXon9RIihg,259
|
|
200
|
+
howler_api-2.13.0.dev342.dist-info/RECORD,,
|
|
File without changes
|
|
File without changes
|