synapse 2.192.0__py311-none-any.whl → 2.194.0__py311-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 synapse might be problematic. Click here for more details.
- synapse/common.py +15 -0
- synapse/cortex.py +19 -25
- synapse/datamodel.py +6 -3
- synapse/exc.py +6 -1
- synapse/lib/agenda.py +17 -6
- synapse/lib/ast.py +242 -97
- synapse/lib/auth.py +1 -0
- synapse/lib/cell.py +31 -85
- synapse/lib/cli.py +20 -11
- synapse/lib/parser.py +5 -1
- synapse/lib/snap.py +44 -15
- synapse/lib/storm.lark +16 -1
- synapse/lib/storm.py +40 -21
- synapse/lib/storm_format.py +1 -0
- synapse/lib/stormctrl.py +88 -6
- synapse/lib/stormlib/cache.py +6 -2
- synapse/lib/stormlib/json.py +5 -2
- synapse/lib/stormlib/scrape.py +1 -1
- synapse/lib/stormlib/stix.py +8 -8
- synapse/lib/stormtypes.py +32 -5
- synapse/lib/version.py +2 -2
- synapse/lib/view.py +20 -3
- synapse/models/geopol.py +1 -0
- synapse/models/geospace.py +1 -0
- synapse/models/inet.py +20 -1
- synapse/models/infotech.py +24 -6
- synapse/models/orgs.py +7 -2
- synapse/models/person.py +15 -4
- synapse/models/risk.py +19 -2
- synapse/models/telco.py +10 -3
- synapse/tests/test_axon.py +6 -6
- synapse/tests/test_cortex.py +133 -14
- synapse/tests/test_exc.py +4 -0
- synapse/tests/test_lib_agenda.py +282 -2
- synapse/tests/test_lib_aha.py +13 -6
- synapse/tests/test_lib_ast.py +301 -10
- synapse/tests/test_lib_auth.py +6 -7
- synapse/tests/test_lib_cell.py +71 -1
- synapse/tests/test_lib_grammar.py +14 -0
- synapse/tests/test_lib_layer.py +1 -1
- synapse/tests/test_lib_lmdbslab.py +3 -3
- synapse/tests/test_lib_storm.py +273 -55
- synapse/tests/test_lib_stormctrl.py +65 -0
- synapse/tests/test_lib_stormhttp.py +5 -5
- synapse/tests/test_lib_stormlib_auth.py +5 -5
- synapse/tests/test_lib_stormlib_cache.py +38 -6
- synapse/tests/test_lib_stormlib_json.py +20 -0
- synapse/tests/test_lib_stormlib_modelext.py +3 -3
- synapse/tests/test_lib_stormlib_scrape.py +6 -6
- synapse/tests/test_lib_stormlib_spooled.py +1 -1
- synapse/tests/test_lib_stormlib_xml.py +5 -5
- synapse/tests/test_lib_stormtypes.py +54 -57
- synapse/tests/test_lib_view.py +1 -1
- synapse/tests/test_model_base.py +1 -2
- synapse/tests/test_model_geopol.py +4 -0
- synapse/tests/test_model_geospace.py +6 -0
- synapse/tests/test_model_inet.py +43 -5
- synapse/tests/test_model_infotech.py +10 -1
- synapse/tests/test_model_orgs.py +17 -2
- synapse/tests/test_model_person.py +23 -1
- synapse/tests/test_model_risk.py +13 -0
- synapse/tests/test_tools_healthcheck.py +4 -4
- synapse/tests/test_tools_storm.py +95 -0
- synapse/tests/test_utils.py +17 -18
- synapse/tests/test_utils_getrefs.py +1 -1
- synapse/tests/utils.py +0 -35
- synapse/tools/changelog.py +6 -4
- synapse/tools/storm.py +1 -1
- synapse/utils/getrefs.py +14 -3
- synapse/vendor/cpython/lib/http/__init__.py +0 -0
- synapse/vendor/cpython/lib/http/cookies.py +59 -0
- synapse/vendor/cpython/lib/test/test_http_cookies.py +49 -0
- {synapse-2.192.0.dist-info → synapse-2.194.0.dist-info}/METADATA +6 -6
- {synapse-2.192.0.dist-info → synapse-2.194.0.dist-info}/RECORD +77 -73
- {synapse-2.192.0.dist-info → synapse-2.194.0.dist-info}/WHEEL +1 -1
- {synapse-2.192.0.dist-info → synapse-2.194.0.dist-info}/LICENSE +0 -0
- {synapse-2.192.0.dist-info → synapse-2.194.0.dist-info}/top_level.txt +0 -0
synapse/common.py
CHANGED
|
@@ -29,6 +29,8 @@ import traceback
|
|
|
29
29
|
import contextlib
|
|
30
30
|
import collections
|
|
31
31
|
|
|
32
|
+
import http.cookies
|
|
33
|
+
|
|
32
34
|
import yaml
|
|
33
35
|
import regex
|
|
34
36
|
|
|
@@ -38,6 +40,8 @@ import synapse.lib.msgpack as s_msgpack
|
|
|
38
40
|
import synapse.lib.structlog as s_structlog
|
|
39
41
|
|
|
40
42
|
import synapse.vendor.cpython.lib.ipaddress as ipaddress
|
|
43
|
+
import synapse.vendor.cpython.lib.http.cookies as v_cookies
|
|
44
|
+
|
|
41
45
|
|
|
42
46
|
try:
|
|
43
47
|
from yaml import CSafeLoader as Loader
|
|
@@ -1218,6 +1222,17 @@ def trimText(text: str, n: int = 256, placeholder: str = '...') -> str:
|
|
|
1218
1222
|
assert n > plen
|
|
1219
1223
|
return f'{text[:mlen]}{placeholder}'
|
|
1220
1224
|
|
|
1225
|
+
def _patch_http_cookies():
|
|
1226
|
+
'''
|
|
1227
|
+
Patch stdlib http.cookies._unquote from the 3.11.10 implementation if
|
|
1228
|
+
the interpreter we are using is not patched for CVE-2024-7592.
|
|
1229
|
+
'''
|
|
1230
|
+
if not hasattr(http.cookies, '_QuotePatt'):
|
|
1231
|
+
return
|
|
1232
|
+
http.cookies._unquote = v_cookies._unquote
|
|
1233
|
+
|
|
1234
|
+
_patch_http_cookies()
|
|
1235
|
+
|
|
1221
1236
|
# TODO: Switch back to using asyncio.wait_for when we are using py 3.12+
|
|
1222
1237
|
# This is a workaround for a race where asyncio.wait_for can end up
|
|
1223
1238
|
# ignoring cancellation https://github.com/python/cpython/issues/86296
|
synapse/cortex.py
CHANGED
|
@@ -1556,7 +1556,6 @@ class Cortex(s_oauth.OAuthMixin, s_cell.Cell): # type: ignore
|
|
|
1556
1556
|
async def initServiceActive(self):
|
|
1557
1557
|
|
|
1558
1558
|
await self.stormdmons.start()
|
|
1559
|
-
await self.agenda.clearRunningStatus()
|
|
1560
1559
|
|
|
1561
1560
|
async def _runMigrations():
|
|
1562
1561
|
# Run migrations when this cortex becomes active. This is to prevent
|
|
@@ -2240,7 +2239,7 @@ class Cortex(s_oauth.OAuthMixin, s_cell.Cell): # type: ignore
|
|
|
2240
2239
|
|
|
2241
2240
|
'''
|
|
2242
2241
|
name = cdef.get('name')
|
|
2243
|
-
|
|
2242
|
+
self._setStormCmd(cdef)
|
|
2244
2243
|
self.cmddefs.set(name, cdef)
|
|
2245
2244
|
|
|
2246
2245
|
async def _reqStormCmd(self, cdef):
|
|
@@ -2483,7 +2482,7 @@ class Cortex(s_oauth.OAuthMixin, s_cell.Cell): # type: ignore
|
|
|
2483
2482
|
async for sodes in self._mergeSodes(layers, genrs, cmprkey_indx, filtercmpr, reverse=reverse):
|
|
2484
2483
|
yield sodes
|
|
2485
2484
|
|
|
2486
|
-
|
|
2485
|
+
def _setStormCmd(self, cdef):
|
|
2487
2486
|
'''
|
|
2488
2487
|
Note:
|
|
2489
2488
|
No change control or persistence
|
|
@@ -2543,13 +2542,9 @@ class Cortex(s_oauth.OAuthMixin, s_cell.Cell): # type: ignore
|
|
|
2543
2542
|
name = cdef.get('name')
|
|
2544
2543
|
self.stormcmds[name] = ctor
|
|
2545
2544
|
|
|
2546
|
-
|
|
2547
|
-
|
|
2548
|
-
async def _popStormCmd(self, name):
|
|
2545
|
+
def _popStormCmd(self, name):
|
|
2549
2546
|
self.stormcmds.pop(name, None)
|
|
2550
2547
|
|
|
2551
|
-
await self.fire('core:cmd:change', cmd=name, act='del')
|
|
2552
|
-
|
|
2553
2548
|
async def delStormCmd(self, name):
|
|
2554
2549
|
'''
|
|
2555
2550
|
Remove a previously set pure storm command.
|
|
@@ -2575,8 +2570,6 @@ class Cortex(s_oauth.OAuthMixin, s_cell.Cell): # type: ignore
|
|
|
2575
2570
|
self.cmddefs.pop(name)
|
|
2576
2571
|
self.stormcmds.pop(name, None)
|
|
2577
2572
|
|
|
2578
|
-
await self.fire('core:cmd:change', cmd=name, act='del')
|
|
2579
|
-
|
|
2580
2573
|
async def addStormPkg(self, pkgdef, verify=False):
|
|
2581
2574
|
'''
|
|
2582
2575
|
Add the given storm package to the cortex.
|
|
@@ -2630,11 +2623,11 @@ class Cortex(s_oauth.OAuthMixin, s_cell.Cell): # type: ignore
|
|
|
2630
2623
|
olddef = self.pkgdefs.get(name, None)
|
|
2631
2624
|
if olddef is not None:
|
|
2632
2625
|
if s_hashitem.hashitem(pkgdef) != s_hashitem.hashitem(olddef):
|
|
2633
|
-
|
|
2626
|
+
self._dropStormPkg(olddef)
|
|
2634
2627
|
else:
|
|
2635
2628
|
return
|
|
2636
2629
|
|
|
2637
|
-
|
|
2630
|
+
self.loadStormPkg(pkgdef)
|
|
2638
2631
|
self.pkgdefs.set(name, pkgdef)
|
|
2639
2632
|
|
|
2640
2633
|
self._clearPermDefs()
|
|
@@ -2664,7 +2657,7 @@ class Cortex(s_oauth.OAuthMixin, s_cell.Cell): # type: ignore
|
|
|
2664
2657
|
if pkgdef is None:
|
|
2665
2658
|
return
|
|
2666
2659
|
|
|
2667
|
-
|
|
2660
|
+
self._dropStormPkg(pkgdef)
|
|
2668
2661
|
|
|
2669
2662
|
self._clearPermDefs()
|
|
2670
2663
|
|
|
@@ -2713,7 +2706,7 @@ class Cortex(s_oauth.OAuthMixin, s_cell.Cell): # type: ignore
|
|
|
2713
2706
|
async def _tryLoadStormPkg(self, pkgdef):
|
|
2714
2707
|
try:
|
|
2715
2708
|
await self._normStormPkg(pkgdef, validstorm=False)
|
|
2716
|
-
|
|
2709
|
+
self.loadStormPkg(pkgdef)
|
|
2717
2710
|
|
|
2718
2711
|
except asyncio.CancelledError: # pragma: no cover TODO: remove once >= py 3.8 only
|
|
2719
2712
|
raise
|
|
@@ -2881,7 +2874,9 @@ class Cortex(s_oauth.OAuthMixin, s_cell.Cell): # type: ignore
|
|
|
2881
2874
|
for configvar in pkgdef.get('configvars', ()):
|
|
2882
2875
|
self._reqStormPkgVarType(pkgname, configvar.get('type'))
|
|
2883
2876
|
|
|
2884
|
-
async
|
|
2877
|
+
# N.B. This function is intentionally not async in order to prevent possible user race conditions for code
|
|
2878
|
+
# executing outside of the nexus lock.
|
|
2879
|
+
def loadStormPkg(self, pkgdef):
|
|
2885
2880
|
'''
|
|
2886
2881
|
Load a storm package into the storm library for this cortex.
|
|
2887
2882
|
|
|
@@ -2911,7 +2906,7 @@ class Cortex(s_oauth.OAuthMixin, s_cell.Cell): # type: ignore
|
|
|
2911
2906
|
self.stormmods = stormmods
|
|
2912
2907
|
|
|
2913
2908
|
for cdef in cmds:
|
|
2914
|
-
|
|
2909
|
+
self._setStormCmd(cdef)
|
|
2915
2910
|
|
|
2916
2911
|
for gdef in pkgdef.get('graphs', ()):
|
|
2917
2912
|
gdef = copy.deepcopy(gdef)
|
|
@@ -2937,7 +2932,9 @@ class Cortex(s_oauth.OAuthMixin, s_cell.Cell): # type: ignore
|
|
|
2937
2932
|
await self.fire('core:pkg:onload:complete', pkg=name)
|
|
2938
2933
|
self.schedCoro(_onload())
|
|
2939
2934
|
|
|
2940
|
-
async
|
|
2935
|
+
# N.B. This function is intentionally not async in order to prevent possible user race conditions for code
|
|
2936
|
+
# executing outside of the nexus lock.
|
|
2937
|
+
def _dropStormPkg(self, pkgdef):
|
|
2941
2938
|
'''
|
|
2942
2939
|
Reverse the process of loadStormPkg()
|
|
2943
2940
|
'''
|
|
@@ -2948,7 +2945,7 @@ class Cortex(s_oauth.OAuthMixin, s_cell.Cell): # type: ignore
|
|
|
2948
2945
|
|
|
2949
2946
|
for cdef in pkgdef.get('commands', ()):
|
|
2950
2947
|
name = cdef.get('name')
|
|
2951
|
-
|
|
2948
|
+
self._popStormCmd(name)
|
|
2952
2949
|
|
|
2953
2950
|
pkgname = pkgdef.get('name')
|
|
2954
2951
|
|
|
@@ -4435,7 +4432,7 @@ class Cortex(s_oauth.OAuthMixin, s_cell.Cell): # type: ignore
|
|
|
4435
4432
|
|
|
4436
4433
|
async def _trySetStormCmd(self, name, cdef):
|
|
4437
4434
|
try:
|
|
4438
|
-
|
|
4435
|
+
self._setStormCmd(cdef)
|
|
4439
4436
|
except (asyncio.CancelledError, Exception):
|
|
4440
4437
|
logger.exception(f'Storm command load failed: {name}')
|
|
4441
4438
|
|
|
@@ -5912,7 +5909,6 @@ class Cortex(s_oauth.OAuthMixin, s_cell.Cell): # type: ignore
|
|
|
5912
5909
|
opts = self._initStormOpts(opts)
|
|
5913
5910
|
|
|
5914
5911
|
if self.stormpool is not None and opts.get('mirror', True):
|
|
5915
|
-
extra = await self.getLogExtra(text=text)
|
|
5916
5912
|
proxy = await self._getMirrorProxy(opts)
|
|
5917
5913
|
|
|
5918
5914
|
if proxy is not None:
|
|
@@ -5932,7 +5928,7 @@ class Cortex(s_oauth.OAuthMixin, s_cell.Cell): # type: ignore
|
|
|
5932
5928
|
|
|
5933
5929
|
except s_exc.TimeOut:
|
|
5934
5930
|
mesg = 'Timeout waiting for query mirror, running locally instead.'
|
|
5935
|
-
logger.warning(mesg)
|
|
5931
|
+
logger.warning(mesg, extra=extra)
|
|
5936
5932
|
|
|
5937
5933
|
if (nexsoffs := opts.get('nexsoffs')) is not None:
|
|
5938
5934
|
if not await self.waitNexsOffs(nexsoffs, timeout=opts.get('nexstimeout')):
|
|
@@ -5947,7 +5943,6 @@ class Cortex(s_oauth.OAuthMixin, s_cell.Cell): # type: ignore
|
|
|
5947
5943
|
opts = self._initStormOpts(opts)
|
|
5948
5944
|
|
|
5949
5945
|
if self.stormpool is not None and opts.get('mirror', True):
|
|
5950
|
-
extra = await self.getLogExtra(text=text)
|
|
5951
5946
|
proxy = await self._getMirrorProxy(opts)
|
|
5952
5947
|
|
|
5953
5948
|
if proxy is not None:
|
|
@@ -5964,7 +5959,7 @@ class Cortex(s_oauth.OAuthMixin, s_cell.Cell): # type: ignore
|
|
|
5964
5959
|
return await proxy.callStorm(text, opts=mirropts)
|
|
5965
5960
|
except s_exc.TimeOut:
|
|
5966
5961
|
mesg = 'Timeout waiting for query mirror, running locally instead.'
|
|
5967
|
-
logger.warning(mesg)
|
|
5962
|
+
logger.warning(mesg, extra=extra)
|
|
5968
5963
|
|
|
5969
5964
|
if (nexsoffs := opts.get('nexsoffs')) is not None:
|
|
5970
5965
|
if not await self.waitNexsOffs(nexsoffs, timeout=opts.get('nexstimeout')):
|
|
@@ -5977,7 +5972,6 @@ class Cortex(s_oauth.OAuthMixin, s_cell.Cell): # type: ignore
|
|
|
5977
5972
|
opts = self._initStormOpts(opts)
|
|
5978
5973
|
|
|
5979
5974
|
if self.stormpool is not None and opts.get('mirror', True):
|
|
5980
|
-
extra = await self.getLogExtra(text=text)
|
|
5981
5975
|
proxy = await self._getMirrorProxy(opts)
|
|
5982
5976
|
|
|
5983
5977
|
if proxy is not None:
|
|
@@ -5997,7 +5991,7 @@ class Cortex(s_oauth.OAuthMixin, s_cell.Cell): # type: ignore
|
|
|
5997
5991
|
|
|
5998
5992
|
except s_exc.TimeOut:
|
|
5999
5993
|
mesg = 'Timeout waiting for query mirror, running locally instead.'
|
|
6000
|
-
logger.warning(mesg)
|
|
5994
|
+
logger.warning(mesg, extra=extra)
|
|
6001
5995
|
|
|
6002
5996
|
if (nexsoffs := opts.get('nexsoffs')) is not None:
|
|
6003
5997
|
if not await self.waitNexsOffs(nexsoffs, timeout=opts.get('nexstimeout')):
|
synapse/datamodel.py
CHANGED
|
@@ -445,14 +445,17 @@ class Form:
|
|
|
445
445
|
'''
|
|
446
446
|
return self.props.get(name)
|
|
447
447
|
|
|
448
|
-
def reqProp(self, name):
|
|
448
|
+
def reqProp(self, name, extra=None):
|
|
449
449
|
prop = self.props.get(name)
|
|
450
450
|
if prop is not None:
|
|
451
451
|
return prop
|
|
452
452
|
|
|
453
453
|
full = f'{self.name}:{name}'
|
|
454
|
-
|
|
455
|
-
|
|
454
|
+
exc = s_exc.NoSuchProp.init(full)
|
|
455
|
+
if extra is not None:
|
|
456
|
+
exc = extra(exc)
|
|
457
|
+
|
|
458
|
+
raise exc
|
|
456
459
|
|
|
457
460
|
def pack(self):
|
|
458
461
|
props = {p.name: p.pack() for p in self.props.values()}
|
synapse/exc.py
CHANGED
|
@@ -56,9 +56,14 @@ class SynErr(Exception):
|
|
|
56
56
|
self.errinfo[name] = valu
|
|
57
57
|
self._setExcMesg()
|
|
58
58
|
|
|
59
|
+
def update(self, items: dict):
|
|
60
|
+
'''Update multiple items in the errinfo dict at once.'''
|
|
61
|
+
self.errinfo.update(items)
|
|
62
|
+
self._setExcMesg()
|
|
63
|
+
|
|
59
64
|
class StormRaise(SynErr):
|
|
60
65
|
'''
|
|
61
|
-
This represents a user provided exception
|
|
66
|
+
This represents a user provided exception raised in the Storm runtime. It requires a errname key.
|
|
62
67
|
'''
|
|
63
68
|
def __init__(self, *args, **info):
|
|
64
69
|
SynErr.__init__(self, *args, **info)
|
synapse/lib/agenda.py
CHANGED
|
@@ -5,9 +5,7 @@ import asyncio
|
|
|
5
5
|
import logging
|
|
6
6
|
import calendar
|
|
7
7
|
import datetime
|
|
8
|
-
import functools
|
|
9
8
|
import itertools
|
|
10
|
-
import collections
|
|
11
9
|
from datetime import timezone as tz
|
|
12
10
|
from collections.abc import Iterable, Mapping
|
|
13
11
|
|
|
@@ -681,6 +679,11 @@ class Agenda(s_base.Base):
|
|
|
681
679
|
mesg = f'No cron job with iden: {iden}'
|
|
682
680
|
raise s_exc.NoSuchIden(iden=iden, mesg=mesg)
|
|
683
681
|
|
|
682
|
+
self._delete_appt_from_heap(appt)
|
|
683
|
+
del self.appts[iden]
|
|
684
|
+
self.apptdefs.delete(iden)
|
|
685
|
+
|
|
686
|
+
def _delete_appt_from_heap(self, appt):
|
|
684
687
|
try:
|
|
685
688
|
heappos = self.apptheap.index(appt)
|
|
686
689
|
except ValueError:
|
|
@@ -694,9 +697,6 @@ class Agenda(s_base.Base):
|
|
|
694
697
|
self.apptheap[heappos] = self.apptheap.pop()
|
|
695
698
|
heapq.heapify(self.apptheap)
|
|
696
699
|
|
|
697
|
-
del self.appts[iden]
|
|
698
|
-
self.apptdefs.delete(iden)
|
|
699
|
-
|
|
700
700
|
def _getNowTick(self):
|
|
701
701
|
return time.time() + self.tickoff
|
|
702
702
|
|
|
@@ -709,12 +709,23 @@ class Agenda(s_base.Base):
|
|
|
709
709
|
for appt in list(self.appts.values()):
|
|
710
710
|
if appt.isrunning:
|
|
711
711
|
logger.debug(f'Clearing the isrunning flag for {appt.iden}')
|
|
712
|
-
|
|
712
|
+
|
|
713
|
+
edits = {
|
|
714
|
+
'isrunning': False,
|
|
715
|
+
'lastfinishtime': self._getNowTick(),
|
|
716
|
+
'lasterrs': ['aborted'] + appt.lasterrs[-4:]
|
|
717
|
+
}
|
|
718
|
+
await self.core.addCronEdits(appt.iden, edits)
|
|
719
|
+
await self.core.feedBeholder('cron:stop', {'iden': appt.iden})
|
|
720
|
+
|
|
721
|
+
if appt.nexttime is None:
|
|
722
|
+
self._delete_appt_from_heap(appt)
|
|
713
723
|
|
|
714
724
|
async def runloop(self):
|
|
715
725
|
'''
|
|
716
726
|
Task loop to issue query tasks at the right times.
|
|
717
727
|
'''
|
|
728
|
+
await self.clearRunningStatus()
|
|
718
729
|
while not self.isfini:
|
|
719
730
|
|
|
720
731
|
timeout = None
|