synapse 2.165.0__py311-none-any.whl → 2.167.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/axon.py +4 -10
- synapse/cmds/cortex.py +1 -6
- synapse/common.py +6 -0
- synapse/cortex.py +104 -57
- synapse/datamodel.py +32 -0
- synapse/exc.py +1 -0
- synapse/lib/agenda.py +81 -51
- synapse/lib/aha.py +2 -0
- synapse/lib/ast.py +21 -23
- synapse/lib/base.py +11 -10
- synapse/lib/cell.py +24 -24
- synapse/lib/hive.py +11 -0
- synapse/lib/httpapi.py +1 -0
- synapse/lib/nexus.py +3 -2
- synapse/lib/node.py +4 -2
- synapse/lib/schemas.py +3 -1
- synapse/lib/snap.py +50 -0
- synapse/lib/storm.py +19 -17
- synapse/lib/stormlib/aha.py +370 -17
- synapse/lib/stormlib/auth.py +11 -4
- synapse/lib/stormlib/cache.py +202 -0
- synapse/lib/stormlib/cortex.py +69 -7
- synapse/lib/stormlib/macro.py +11 -18
- synapse/lib/stormlib/spooled.py +109 -0
- synapse/lib/stormlib/stix.py +1 -1
- synapse/lib/stormtypes.py +61 -17
- synapse/lib/trigger.py +10 -12
- synapse/lib/types.py +3 -1
- synapse/lib/version.py +2 -2
- synapse/lib/view.py +16 -3
- synapse/models/base.py +8 -0
- synapse/models/files.py +3 -0
- synapse/models/inet.py +74 -2
- synapse/models/orgs.py +52 -8
- synapse/models/person.py +30 -11
- synapse/models/risk.py +44 -3
- synapse/telepath.py +115 -32
- synapse/tests/files/stormpkg/dotstorm/dotstorm.yaml +3 -0
- synapse/tests/test_cortex.py +79 -8
- synapse/tests/test_datamodel.py +22 -0
- synapse/tests/test_lib_agenda.py +8 -1
- synapse/tests/test_lib_aha.py +19 -6
- synapse/tests/test_lib_cell.py +6 -2
- synapse/tests/test_lib_grammar.py +62 -64
- synapse/tests/test_lib_httpapi.py +1 -1
- synapse/tests/test_lib_rstorm.py +4 -4
- synapse/tests/test_lib_storm.py +98 -7
- synapse/tests/test_lib_stormlib_aha.py +196 -0
- synapse/tests/test_lib_stormlib_cache.py +272 -0
- synapse/tests/test_lib_stormlib_compression.py +12 -12
- synapse/tests/test_lib_stormlib_cortex.py +71 -0
- synapse/tests/test_lib_stormlib_macro.py +94 -0
- synapse/tests/test_lib_stormlib_spooled.py +190 -0
- synapse/tests/test_lib_stormtypes.py +71 -37
- synapse/tests/test_lib_view.py +50 -3
- synapse/tests/test_model_files.py +3 -0
- synapse/tests/test_model_inet.py +67 -0
- synapse/tests/test_model_risk.py +6 -0
- synapse/tests/test_telepath.py +30 -7
- synapse/tests/test_tools_genpkg.py +26 -0
- synapse/tests/test_tools_hiveload.py +1 -0
- synapse/tests/test_tools_hivesave.py +1 -0
- synapse/tests/test_tools_modrole.py +81 -0
- synapse/tests/test_tools_moduser.py +105 -0
- synapse/tests/utils.py +22 -3
- synapse/tools/autodoc.py +1 -1
- synapse/tools/hive/load.py +3 -0
- synapse/tools/hive/save.py +3 -0
- synapse/tools/modrole.py +59 -7
- synapse/tools/moduser.py +78 -10
- {synapse-2.165.0.dist-info → synapse-2.167.0.dist-info}/METADATA +3 -3
- {synapse-2.165.0.dist-info → synapse-2.167.0.dist-info}/RECORD +75 -72
- synapse/lib/provenance.py +0 -111
- synapse/tests/test_lib_provenance.py +0 -37
- {synapse-2.165.0.dist-info → synapse-2.167.0.dist-info}/LICENSE +0 -0
- {synapse-2.165.0.dist-info → synapse-2.167.0.dist-info}/WHEEL +0 -0
- {synapse-2.165.0.dist-info → synapse-2.167.0.dist-info}/top_level.txt +0 -0
synapse/tests/test_lib_view.py
CHANGED
|
@@ -11,18 +11,21 @@ from synapse.tests.utils import alist
|
|
|
11
11
|
|
|
12
12
|
class ViewTest(s_t_utils.SynTest):
|
|
13
13
|
|
|
14
|
-
async def
|
|
14
|
+
async def test_view_protected(self):
|
|
15
15
|
async with self.getTestCore() as core:
|
|
16
16
|
view = await core.callStorm('return($lib.view.get().fork().iden)')
|
|
17
17
|
opts = {'view': view}
|
|
18
18
|
|
|
19
19
|
await core.nodes('[ ou:org=* ]', opts=opts)
|
|
20
|
-
await core.nodes('$lib.view.get().set(
|
|
20
|
+
await core.nodes('$lib.view.get().set(protected, $lib.true)', opts=opts)
|
|
21
21
|
|
|
22
22
|
with self.raises(s_exc.CantMergeView):
|
|
23
23
|
await core.nodes('$lib.view.get().merge()', opts=opts)
|
|
24
24
|
|
|
25
|
-
|
|
25
|
+
with self.raises(s_exc.CantDelView):
|
|
26
|
+
await core.nodes('$lib.view.del($lib.view.get().iden)', opts=opts)
|
|
27
|
+
|
|
28
|
+
await core.nodes('$lib.view.get().set(protected, $lib.false)', opts=opts)
|
|
26
29
|
await core.nodes('$lib.view.get().merge()', opts=opts)
|
|
27
30
|
|
|
28
31
|
self.len(1, await core.nodes('ou:org'))
|
|
@@ -31,6 +34,50 @@ class ViewTest(s_t_utils.SynTest):
|
|
|
31
34
|
with self.raises(s_exc.BadOptValu):
|
|
32
35
|
await core.view.setViewInfo('hehe', 10)
|
|
33
36
|
|
|
37
|
+
async with self.getTestCore() as core:
|
|
38
|
+
# Delete this block when nomerge is removed
|
|
39
|
+
view = await core.callStorm('return($lib.view.get().fork().iden)')
|
|
40
|
+
opts = {'view': view}
|
|
41
|
+
|
|
42
|
+
# Setting/getting nomerge should be redirected to protected
|
|
43
|
+
getnomerge = 'return($lib.view.get().get(nomerge))'
|
|
44
|
+
setnomerge = '$lib.view.get().set(nomerge, $valu)'
|
|
45
|
+
|
|
46
|
+
getprotected = 'return($lib.view.get().get(protected))'
|
|
47
|
+
setprotected = '$lib.view.get().set(protected, $valu)'
|
|
48
|
+
|
|
49
|
+
nomerge = await core.callStorm(getnomerge, opts=opts)
|
|
50
|
+
protected = await core.callStorm(getprotected, opts=opts)
|
|
51
|
+
self.false(nomerge)
|
|
52
|
+
self.false(protected)
|
|
53
|
+
|
|
54
|
+
opts['vars'] = {'valu': True}
|
|
55
|
+
await core.callStorm(setnomerge, opts=opts)
|
|
56
|
+
|
|
57
|
+
nomerge = await core.callStorm(getnomerge, opts=opts)
|
|
58
|
+
protected = await core.callStorm(getprotected, opts=opts)
|
|
59
|
+
self.true(nomerge)
|
|
60
|
+
self.true(protected)
|
|
61
|
+
|
|
62
|
+
opts['vars'] = {'valu': False}
|
|
63
|
+
await core.callStorm(setprotected, opts=opts)
|
|
64
|
+
|
|
65
|
+
nomerge = await core.callStorm(getnomerge, opts=opts)
|
|
66
|
+
protected = await core.callStorm(getprotected, opts=opts)
|
|
67
|
+
self.false(nomerge)
|
|
68
|
+
self.false(protected)
|
|
69
|
+
|
|
70
|
+
async def test_view_nomerge_migration(self):
|
|
71
|
+
async with self.getRegrCore('cortex-defaults-v2') as core:
|
|
72
|
+
view = core.getView('0df16dd693c74109da0d58ab87ba768a')
|
|
73
|
+
self.none(view.info.get('nomerge'))
|
|
74
|
+
self.true(view.info.get('protected'))
|
|
75
|
+
|
|
76
|
+
with self.raises(s_exc.CantMergeView):
|
|
77
|
+
await core.callStorm('return($lib.view.get(0df16dd693c74109da0d58ab87ba768a).merge())')
|
|
78
|
+
with self.raises(s_exc.CantDelView):
|
|
79
|
+
await core.callStorm('return($lib.view.del(0df16dd693c74109da0d58ab87ba768a))')
|
|
80
|
+
|
|
34
81
|
async def test_view_set_parent(self):
|
|
35
82
|
|
|
36
83
|
async with self.getTestCore() as core:
|
|
@@ -247,6 +247,9 @@ class FileTest(s_t_utils.SynTest):
|
|
|
247
247
|
self.raises(s_exc.BadTypeValu, base.norm, 'foo/bar.exe')
|
|
248
248
|
self.raises(s_exc.BadTypeValu, base.norm, '/haha')
|
|
249
249
|
|
|
250
|
+
norm, info = path.norm('../.././..')
|
|
251
|
+
self.eq(norm, '')
|
|
252
|
+
|
|
250
253
|
norm, info = path.norm('c:\\Windows\\System32\\calc.exe')
|
|
251
254
|
|
|
252
255
|
self.eq(norm, 'c:/windows/system32/calc.exe')
|
synapse/tests/test_model_inet.py
CHANGED
|
@@ -2767,3 +2767,70 @@ class InetModelTest(s_t_utils.SynTest):
|
|
|
2767
2767
|
self.eq(nodes[0].get('client'), 'tcp://1.2.3.4')
|
|
2768
2768
|
self.eq(nodes[0].get('client:ipv4'), 0x01020304)
|
|
2769
2769
|
self.eq(nodes[0].get('client:ipv6'), '::1')
|
|
2770
|
+
|
|
2771
|
+
async def test_model_inet_tls_handshake(self):
|
|
2772
|
+
|
|
2773
|
+
async with self.getTestCore() as core:
|
|
2774
|
+
props = {
|
|
2775
|
+
'ja3': '1' * 32,
|
|
2776
|
+
'ja3s': '2' * 32,
|
|
2777
|
+
'client': 'tcp://1.2.3.4:8888',
|
|
2778
|
+
'server': 'tcp://5.6.7.8:9999'
|
|
2779
|
+
}
|
|
2780
|
+
|
|
2781
|
+
nodes = await core.nodes('''
|
|
2782
|
+
[
|
|
2783
|
+
inet:tls:handshake=*
|
|
2784
|
+
:time=now
|
|
2785
|
+
:flow=*
|
|
2786
|
+
:server=$server
|
|
2787
|
+
:server:cert=*
|
|
2788
|
+
:server:fingerprint:ja3=$ja3s
|
|
2789
|
+
:client=$client
|
|
2790
|
+
:client:cert=*
|
|
2791
|
+
:client:fingerprint:ja3=$ja3
|
|
2792
|
+
]
|
|
2793
|
+
''', opts={'vars': props})
|
|
2794
|
+
self.len(1, nodes)
|
|
2795
|
+
self.nn(nodes[0].get('time'))
|
|
2796
|
+
self.nn(nodes[0].get('flow'))
|
|
2797
|
+
self.nn(nodes[0].get('server:cert'))
|
|
2798
|
+
self.nn(nodes[0].get('client:cert'))
|
|
2799
|
+
|
|
2800
|
+
self.eq(props['ja3'], nodes[0].get('client:fingerprint:ja3'))
|
|
2801
|
+
self.eq(props['ja3s'], nodes[0].get('server:fingerprint:ja3'))
|
|
2802
|
+
|
|
2803
|
+
self.eq(props['client'], nodes[0].get('client'))
|
|
2804
|
+
self.eq(props['server'], nodes[0].get('server'))
|
|
2805
|
+
|
|
2806
|
+
async def test_model_inet_ja3(self):
|
|
2807
|
+
|
|
2808
|
+
async with self.getTestCore() as core:
|
|
2809
|
+
|
|
2810
|
+
ja3 = '76e7b0cb0994d60a4b3f360a088fac39'
|
|
2811
|
+
nodes = await core.nodes('[ inet:tls:ja3:sample=(tcp://1.2.3.4, $md5) ]', opts={'vars': {'md5': ja3}})
|
|
2812
|
+
self.len(1, nodes)
|
|
2813
|
+
self.eq(nodes[0].get('client'), 'tcp://1.2.3.4')
|
|
2814
|
+
self.eq(nodes[0].get('ja3'), ja3)
|
|
2815
|
+
|
|
2816
|
+
ja3 = '4769ad08107979c719d86270e706fed5'
|
|
2817
|
+
nodes = await core.nodes('[ inet:tls:ja3s:sample=(tcp://2.2.2.2, $md5) ]', opts={'vars': {'md5': ja3}})
|
|
2818
|
+
self.len(1, nodes)
|
|
2819
|
+
self.eq(nodes[0].get('server'), 'tcp://2.2.2.2')
|
|
2820
|
+
self.eq(nodes[0].get('ja3s'), ja3)
|
|
2821
|
+
|
|
2822
|
+
async def test_model_inet_tls_certs(self):
|
|
2823
|
+
|
|
2824
|
+
async with self.getTestCore() as core:
|
|
2825
|
+
|
|
2826
|
+
server = 'e4f6db65dbaa7a4598f7379f75dcd5f5'
|
|
2827
|
+
client = 'df8d1f7e04f7c4a322e04b0b252e2851'
|
|
2828
|
+
nodes = await core.nodes('[inet:tls:servercert=(tcp://1.2.3.4:1234, $server)]', opts={'vars': {'server': server}})
|
|
2829
|
+
self.len(1, nodes)
|
|
2830
|
+
self.eq(nodes[0].get('server'), 'tcp://1.2.3.4:1234')
|
|
2831
|
+
self.eq(nodes[0].get('cert'), server)
|
|
2832
|
+
|
|
2833
|
+
nodes = await core.nodes('[inet:tls:clientcert=(tcp://5.6.7.8:5678, $client)]', opts={'vars': {'client': client}})
|
|
2834
|
+
self.len(1, nodes)
|
|
2835
|
+
self.eq(nodes[0].get('client'), 'tcp://5.6.7.8:5678')
|
|
2836
|
+
self.eq(nodes[0].get('cert'), client)
|
synapse/tests/test_model_risk.py
CHANGED
|
@@ -435,6 +435,8 @@ class RiskModelTest(s_t_utils.SynTest):
|
|
|
435
435
|
:public:url=https://wikileaks.org/acme
|
|
436
436
|
:reporter={ gen.ou.org vertex }
|
|
437
437
|
:reporter:name=vertex
|
|
438
|
+
:size:bytes=99
|
|
439
|
+
:extortion=*
|
|
438
440
|
]''')
|
|
439
441
|
self.len(1, nodes)
|
|
440
442
|
self.eq('wikileaks acme leak', nodes[0].get('name'))
|
|
@@ -442,9 +444,11 @@ class RiskModelTest(s_t_utils.SynTest):
|
|
|
442
444
|
self.eq(1698883200000, nodes[0].get('disclosed'))
|
|
443
445
|
self.eq('public.', nodes[0].get('type'))
|
|
444
446
|
self.eq(1, nodes[0].get('public'))
|
|
447
|
+
self.eq(99, nodes[0].get('size:bytes'))
|
|
445
448
|
self.eq('https://wikileaks.org/acme', nodes[0].get('public:url'))
|
|
446
449
|
self.eq('vertex', nodes[0].get('reporter:name'))
|
|
447
450
|
|
|
451
|
+
self.len(1, await core.nodes('risk:leak -> risk:extortion'))
|
|
448
452
|
self.len(1, await core.nodes('risk:leak -> risk:leak:type:taxonomy'))
|
|
449
453
|
self.len(1, await core.nodes('risk:leak :owner -> ps:contact +:orgname=acme'))
|
|
450
454
|
self.len(1, await core.nodes('risk:leak :leaker -> ps:contact +:orgname=wikileaks'))
|
|
@@ -454,6 +458,7 @@ class RiskModelTest(s_t_utils.SynTest):
|
|
|
454
458
|
|
|
455
459
|
nodes = await core.nodes('''[ risk:extortion=*
|
|
456
460
|
:demanded=20231102
|
|
461
|
+
:deadline=20240329
|
|
457
462
|
:name="APT99 Extorted ACME"
|
|
458
463
|
:desc="APT99 extorted ACME for a zillion vertex coins."
|
|
459
464
|
:type=fingain
|
|
@@ -474,6 +479,7 @@ class RiskModelTest(s_t_utils.SynTest):
|
|
|
474
479
|
self.eq('apt99 extorted acme', nodes[0].get('name'))
|
|
475
480
|
self.eq('APT99 extorted ACME for a zillion vertex coins.', nodes[0].get('desc'))
|
|
476
481
|
self.eq(1698883200000, nodes[0].get('demanded'))
|
|
482
|
+
self.eq(1711670400000, nodes[0].get('deadline'))
|
|
477
483
|
self.eq('fingain.', nodes[0].get('type'))
|
|
478
484
|
self.eq(1, nodes[0].get('public'))
|
|
479
485
|
self.eq(1, nodes[0].get('success'))
|
synapse/tests/test_telepath.py
CHANGED
|
@@ -831,15 +831,17 @@ class TeleTest(s_t_utils.SynTest):
|
|
|
831
831
|
|
|
832
832
|
await targ.waitready()
|
|
833
833
|
|
|
834
|
-
|
|
834
|
+
prox00 = await targ.proxy(timeout=12)
|
|
835
|
+
self.eq(110, await prox00.dostuff(100))
|
|
836
|
+
|
|
835
837
|
self.eq(1, fail0.count)
|
|
836
838
|
self.eq(0, fail1.count)
|
|
837
839
|
|
|
838
|
-
_prox = await targ.proxy()
|
|
839
840
|
await dmon0.fini()
|
|
840
|
-
self.true(await
|
|
841
|
+
self.true(await prox00.waitfini(10))
|
|
841
842
|
|
|
842
|
-
|
|
843
|
+
prox01 = await targ.proxy(timeout=12)
|
|
844
|
+
self.eq(110, await prox01.dostuff(100))
|
|
843
845
|
self.eq(1, fail0.count)
|
|
844
846
|
self.eq(1, fail1.count)
|
|
845
847
|
|
|
@@ -855,15 +857,36 @@ class TeleTest(s_t_utils.SynTest):
|
|
|
855
857
|
mesgs = stream.read()
|
|
856
858
|
self.notin('password', mesgs)
|
|
857
859
|
|
|
858
|
-
|
|
860
|
+
prox00 = await targ.proxy(timeout=12)
|
|
861
|
+
self.eq(110, await prox00.dostuff(100))
|
|
859
862
|
|
|
860
863
|
self.eq(1, fail0.count)
|
|
861
864
|
self.eq(2, fail1.count)
|
|
862
865
|
|
|
863
866
|
async with await s_telepath.open(url1) as targ:
|
|
864
|
-
await targ.waitready()
|
|
865
|
-
|
|
867
|
+
await targ.waitready(timeout=12)
|
|
868
|
+
prox00 = await targ.proxy(timeout=12)
|
|
869
|
+
self.eq(110, await prox00.dostuff(100))
|
|
870
|
+
|
|
871
|
+
async def onlink(proxy, urlinfo):
|
|
872
|
+
self.eq(110, await proxy.dostuff(100))
|
|
873
|
+
_url = s_telepath.zipurl(urlinfo)
|
|
874
|
+
logger.info(f'Connected to url={_url}')
|
|
875
|
+
|
|
876
|
+
with self.getAsyncLoggerStream('synapse.tests.test_telepath',
|
|
877
|
+
f'Connected to url=tcp://127.0.0.1:{addr1[1]}/foo') as stream:
|
|
878
|
+
async with await s_telepath.open(url1, onlink=onlink) as targ:
|
|
879
|
+
self.true(await stream.wait(timeout=12))
|
|
880
|
+
|
|
881
|
+
# Coverage
|
|
882
|
+
async def badonlink(proxy, urlinfo):
|
|
883
|
+
raise ValueError('oopsie')
|
|
884
|
+
|
|
885
|
+
with self.getAsyncLoggerStream('synapse.telepath', 'onlink: ') as stream:
|
|
886
|
+
async with await s_telepath.open(url1, onlink=badonlink) as targ:
|
|
887
|
+
self.true(await stream.wait(timeout=12))
|
|
866
888
|
|
|
889
|
+
await dmon0.fini()
|
|
867
890
|
await dmon1.fini()
|
|
868
891
|
|
|
869
892
|
async def test_telepath_poolsize(self):
|
|
@@ -254,7 +254,33 @@ class TestStormPkgTest(s_test.StormPkgTest):
|
|
|
254
254
|
assetdir = s_common.genpath(dirname, 'files', 'stormpkg', 'dotstorm', 'testassets')
|
|
255
255
|
pkgprotos = (s_common.genpath(dirname, 'files', 'stormpkg', 'dotstorm', 'dotstorm.yaml'),)
|
|
256
256
|
|
|
257
|
+
async def initTestCore(self, core):
|
|
258
|
+
await core.callStorm('$lib.globals.set(inittestcore, frob)')
|
|
259
|
+
|
|
257
260
|
async def test_stormpkg_base(self):
|
|
258
261
|
async with self.getTestCore() as core:
|
|
259
262
|
msgs = await core.stormlist('dotstorm.bar')
|
|
260
263
|
self.stormHasNoWarnErr(msgs)
|
|
264
|
+
self.eq('frob', await core.callStorm('return($lib.globals.get(inittestcore))'))
|
|
265
|
+
|
|
266
|
+
async def stormpkg_preppkghook(self, core):
|
|
267
|
+
await core.callStorm('$lib.globals.set(stormpkg_preppkghook, boundmethod)')
|
|
268
|
+
|
|
269
|
+
async def test_stormpkg_preppkghook(self):
|
|
270
|
+
|
|
271
|
+
# inline example
|
|
272
|
+
async def hook(core):
|
|
273
|
+
await core.callStorm('$lib.globals.set(inlinehook, haha)')
|
|
274
|
+
|
|
275
|
+
async with self.getTestCore(prepkghook=hook) as core:
|
|
276
|
+
msgs = await core.stormlist('dotstorm.bar')
|
|
277
|
+
self.stormHasNoWarnErr(msgs)
|
|
278
|
+
self.eq('haha', await core.callStorm('return($lib.globals.get(inlinehook))'))
|
|
279
|
+
self.eq('frob', await core.callStorm('return($lib.globals.get(inittestcore))'))
|
|
280
|
+
|
|
281
|
+
# bound method example
|
|
282
|
+
async with self.getTestCore(prepkghook=self.stormpkg_preppkghook) as core:
|
|
283
|
+
msgs = await core.stormlist('dotstorm.bar')
|
|
284
|
+
self.stormHasNoWarnErr(msgs)
|
|
285
|
+
self.eq('boundmethod', await core.callStorm('return($lib.globals.get(stormpkg_preppkghook))'))
|
|
286
|
+
self.eq('frob', await core.callStorm('return($lib.globals.get(inittestcore))'))
|
|
@@ -48,6 +48,7 @@ class HiveLoadTest(s_test.SynTest):
|
|
|
48
48
|
with mock.patch('synapse.telepath.Proxy._getSynVers', _getOldSynVers):
|
|
49
49
|
outp = self.getTestOutp()
|
|
50
50
|
retn = await s_hiveload.main(argv, outp=outp)
|
|
51
|
+
outp.expect('WARNING: "synapse.tools.hive.load" is deprecated in 2.167.0 and will be removed in 3.0.0')
|
|
51
52
|
outp.expect('Hive version 0.0.0 is outside of the hive.load supported range')
|
|
52
53
|
self.eq(1, retn)
|
|
53
54
|
|
|
@@ -28,6 +28,7 @@ class HiveSaveTest(s_test.SynTest):
|
|
|
28
28
|
with mock.patch('synapse.telepath.Proxy._getSynVers', _getOldSynVers):
|
|
29
29
|
outp = self.getTestOutp()
|
|
30
30
|
retn = await s_hivesave.main(argv, outp=outp)
|
|
31
|
+
outp.expect('WARNING: "synapse.tools.hive.save" is deprecated in 2.167.0 and will be removed in 3.0.0')
|
|
31
32
|
outp.expect('Hive version 0.0.0 is outside of the hive.save supported range')
|
|
32
33
|
self.eq(1, retn)
|
|
33
34
|
|
|
@@ -2,6 +2,26 @@ import synapse.lib.output as s_output
|
|
|
2
2
|
import synapse.tests.utils as s_test
|
|
3
3
|
import synapse.tools.modrole as s_t_modrole
|
|
4
4
|
|
|
5
|
+
rolelist = s_test.deguidify('''
|
|
6
|
+
Roles:
|
|
7
|
+
ce6928dfe88cace918c405bbef51e72f - all
|
|
8
|
+
0f316b3f3e6ec970fcdb9a085fcd5b77 - visi
|
|
9
|
+
'''.strip())
|
|
10
|
+
|
|
11
|
+
roleinfo = s_test.deguidify('''
|
|
12
|
+
Role: visi (145c3321a0cd0cd06de19174415a7aeb)
|
|
13
|
+
|
|
14
|
+
Rules:
|
|
15
|
+
[0 ] - !foo.bar.baz
|
|
16
|
+
[1 ] - foo.bar
|
|
17
|
+
|
|
18
|
+
Gates:
|
|
19
|
+
3ad191c63a201df3246c6d6ff81763ad
|
|
20
|
+
Admin: False
|
|
21
|
+
[0 ] - !bar.baz.faz
|
|
22
|
+
[1 ] - bar.baz
|
|
23
|
+
'''.strip())
|
|
24
|
+
|
|
5
25
|
class ModRoleTest(s_test.SynTest):
|
|
6
26
|
|
|
7
27
|
async def test_tools_modrole(self):
|
|
@@ -40,6 +60,60 @@ class ModRoleTest(s_test.SynTest):
|
|
|
40
60
|
self.true(bool(visi.allowed('foo.bar.gaz'.split('.'))))
|
|
41
61
|
self.false(bool(visi.allowed('foo.bar.baz'.split('.'))))
|
|
42
62
|
|
|
63
|
+
gateiden = core.getLayer().iden
|
|
64
|
+
argv = (
|
|
65
|
+
'--svcurl', svcurl,
|
|
66
|
+
'visi',
|
|
67
|
+
'--allow', 'bar.baz',
|
|
68
|
+
'--deny', 'bar.baz.faz',
|
|
69
|
+
'--gate', gateiden,
|
|
70
|
+
)
|
|
71
|
+
outp = s_output.OutPutStr()
|
|
72
|
+
self.eq(0, await s_t_modrole.main(argv, outp=outp))
|
|
73
|
+
self.isin(f'...adding allow rule: bar.baz on gate {gateiden}', str(outp))
|
|
74
|
+
self.isin(f'...adding deny rule: bar.baz.faz on gate {gateiden}', str(outp))
|
|
75
|
+
|
|
76
|
+
gate = await core.getAuthGate(gateiden)
|
|
77
|
+
for role in gate['roles']:
|
|
78
|
+
if role['iden'] == visi.iden:
|
|
79
|
+
self.isin((True, ('bar', 'baz')), role['rules'])
|
|
80
|
+
self.isin((False, ('bar', 'baz', 'faz')), role['rules'])
|
|
81
|
+
|
|
82
|
+
argv = (
|
|
83
|
+
'--svcurl', svcurl,
|
|
84
|
+
'--list',
|
|
85
|
+
)
|
|
86
|
+
outp = s_output.OutPutStr()
|
|
87
|
+
self.eq(0, await s_t_modrole.main(argv, outp=outp))
|
|
88
|
+
self.isin(rolelist, s_test.deguidify(str(outp)))
|
|
89
|
+
|
|
90
|
+
argv = (
|
|
91
|
+
'--svcurl', svcurl,
|
|
92
|
+
'--list',
|
|
93
|
+
'visi',
|
|
94
|
+
)
|
|
95
|
+
outp = s_output.OutPutStr()
|
|
96
|
+
self.eq(0, await s_t_modrole.main(argv, outp=outp))
|
|
97
|
+
self.isin(roleinfo, s_test.deguidify(str(outp)))
|
|
98
|
+
|
|
99
|
+
argv = (
|
|
100
|
+
'--svcurl', svcurl,
|
|
101
|
+
'--list',
|
|
102
|
+
'newprole',
|
|
103
|
+
)
|
|
104
|
+
outp = s_output.OutPutStr()
|
|
105
|
+
self.eq(1, await s_t_modrole.main(argv, outp=outp))
|
|
106
|
+
self.isin('ERROR: Role not found: newprole', str(outp))
|
|
107
|
+
|
|
108
|
+
argv = (
|
|
109
|
+
'--svcurl', svcurl,
|
|
110
|
+
'visi',
|
|
111
|
+
'--gate', 'newp',
|
|
112
|
+
)
|
|
113
|
+
outp = s_output.OutPutStr()
|
|
114
|
+
self.eq(1, await s_t_modrole.main(argv, outp=outp))
|
|
115
|
+
self.isin('ERROR: No auth gate found with iden: newp', str(outp))
|
|
116
|
+
|
|
43
117
|
argv = (
|
|
44
118
|
'--svcurl', svcurl,
|
|
45
119
|
'--add',
|
|
@@ -59,3 +133,10 @@ class ModRoleTest(s_test.SynTest):
|
|
|
59
133
|
self.eq(0, await s_t_modrole.main(argv, outp=outp))
|
|
60
134
|
self.isin('...deleting role: visi', str(outp))
|
|
61
135
|
self.none(await core.auth.getRoleByName('visi'))
|
|
136
|
+
|
|
137
|
+
argv = (
|
|
138
|
+
'--svcurl', svcurl,
|
|
139
|
+
)
|
|
140
|
+
outp = s_output.OutPutStr()
|
|
141
|
+
self.eq(1, await s_t_modrole.main(argv, outp=outp))
|
|
142
|
+
self.isin('ERROR: A rolename argument is required when --list is not specified.', str(outp))
|
|
@@ -2,6 +2,32 @@ import synapse.lib.output as s_output
|
|
|
2
2
|
import synapse.tests.utils as s_test
|
|
3
3
|
import synapse.tools.moduser as s_t_moduser
|
|
4
4
|
|
|
5
|
+
userlist = '''
|
|
6
|
+
Users:
|
|
7
|
+
root
|
|
8
|
+
visi
|
|
9
|
+
'''.strip()
|
|
10
|
+
|
|
11
|
+
userinfo = s_test.deguidify('''
|
|
12
|
+
User: visi (04dddd4ff39e4ce00b36c7d526b9eac7)
|
|
13
|
+
|
|
14
|
+
Locked: False
|
|
15
|
+
Admin: False
|
|
16
|
+
Email: visi@test.com
|
|
17
|
+
Rules:
|
|
18
|
+
[0 ] - !foo.bar.baz
|
|
19
|
+
[1 ] - foo.bar
|
|
20
|
+
|
|
21
|
+
Roles:
|
|
22
|
+
576a948f9944c58d3953f0d36bc2da81 - all
|
|
23
|
+
|
|
24
|
+
Gates:
|
|
25
|
+
c7b276154c0c799430668cb3c4cd259d
|
|
26
|
+
Admin: False
|
|
27
|
+
[0 ] - !bar.baz.faz
|
|
28
|
+
[1 ] - bar.baz
|
|
29
|
+
'''.strip())
|
|
30
|
+
|
|
5
31
|
class ModUserTest(s_test.SynTest):
|
|
6
32
|
|
|
7
33
|
async def test_tools_moduser(self):
|
|
@@ -124,6 +150,78 @@ class ModUserTest(s_test.SynTest):
|
|
|
124
150
|
self.true(bool(visi.allowed('foo.bar.gaz'.split('.'))))
|
|
125
151
|
self.false(bool(visi.allowed('foo.bar.baz'.split('.'))))
|
|
126
152
|
|
|
153
|
+
gateiden = core.getLayer().iden
|
|
154
|
+
argv = (
|
|
155
|
+
'--svcurl', svcurl,
|
|
156
|
+
'visi',
|
|
157
|
+
'--admin', 'true',
|
|
158
|
+
'--gate', gateiden,
|
|
159
|
+
)
|
|
160
|
+
outp = s_output.OutPutStr()
|
|
161
|
+
self.eq(0, await s_t_moduser.main(argv, outp=outp))
|
|
162
|
+
self.isin(f'...setting admin: true on gate {gateiden}', str(outp))
|
|
163
|
+
|
|
164
|
+
gate = await core.getAuthGate(gateiden)
|
|
165
|
+
for user in gate['users']:
|
|
166
|
+
if user['iden'] == visi.iden:
|
|
167
|
+
self.true(user['admin'])
|
|
168
|
+
|
|
169
|
+
gateiden = core.getLayer().iden
|
|
170
|
+
argv = (
|
|
171
|
+
'--svcurl', svcurl,
|
|
172
|
+
'visi',
|
|
173
|
+
'--admin', 'false',
|
|
174
|
+
'--allow', 'bar.baz',
|
|
175
|
+
'--deny', 'bar.baz.faz',
|
|
176
|
+
'--gate', gateiden,
|
|
177
|
+
)
|
|
178
|
+
outp = s_output.OutPutStr()
|
|
179
|
+
self.eq(0, await s_t_moduser.main(argv, outp=outp))
|
|
180
|
+
self.isin(f'...setting admin: false on gate {gateiden}', str(outp))
|
|
181
|
+
self.isin(f'...adding allow rule: bar.baz on gate {gateiden}', str(outp))
|
|
182
|
+
self.isin(f'...adding deny rule: bar.baz.faz on gate {gateiden}', str(outp))
|
|
183
|
+
|
|
184
|
+
gate = await core.getAuthGate(gateiden)
|
|
185
|
+
for user in gate['users']:
|
|
186
|
+
if user['iden'] == visi.iden:
|
|
187
|
+
self.isin((True, ('bar', 'baz')), user['rules'])
|
|
188
|
+
self.isin((False, ('bar', 'baz', 'faz')), user['rules'])
|
|
189
|
+
|
|
190
|
+
argv = (
|
|
191
|
+
'--svcurl', svcurl,
|
|
192
|
+
'--list',
|
|
193
|
+
)
|
|
194
|
+
outp = s_output.OutPutStr()
|
|
195
|
+
self.eq(0, await s_t_moduser.main(argv, outp=outp))
|
|
196
|
+
self.isin(userlist, str(outp))
|
|
197
|
+
|
|
198
|
+
argv = (
|
|
199
|
+
'--svcurl', svcurl,
|
|
200
|
+
'--list',
|
|
201
|
+
'visi',
|
|
202
|
+
)
|
|
203
|
+
outp = s_output.OutPutStr()
|
|
204
|
+
self.eq(0, await s_t_moduser.main(argv, outp=outp))
|
|
205
|
+
self.isin(userinfo, s_test.deguidify(str(outp)))
|
|
206
|
+
|
|
207
|
+
argv = (
|
|
208
|
+
'--svcurl', svcurl,
|
|
209
|
+
'--list',
|
|
210
|
+
'newpuser',
|
|
211
|
+
)
|
|
212
|
+
outp = s_output.OutPutStr()
|
|
213
|
+
self.eq(1, await s_t_moduser.main(argv, outp=outp))
|
|
214
|
+
self.isin('ERROR: User not found: newpuser', str(outp))
|
|
215
|
+
|
|
216
|
+
argv = (
|
|
217
|
+
'--svcurl', svcurl,
|
|
218
|
+
'visi',
|
|
219
|
+
'--gate', 'newp',
|
|
220
|
+
)
|
|
221
|
+
outp = s_output.OutPutStr()
|
|
222
|
+
self.eq(1, await s_t_moduser.main(argv, outp=outp))
|
|
223
|
+
self.isin('ERROR: No auth gate found with iden: newp', str(outp))
|
|
224
|
+
|
|
127
225
|
argv = (
|
|
128
226
|
'--svcurl', svcurl,
|
|
129
227
|
'visi',
|
|
@@ -151,3 +249,10 @@ class ModUserTest(s_test.SynTest):
|
|
|
151
249
|
outp = s_output.OutPutStr()
|
|
152
250
|
self.eq(1, await s_t_moduser.main(argv, outp=outp))
|
|
153
251
|
self.isin('ERROR: User not found (need --add?): visi', str(outp))
|
|
252
|
+
|
|
253
|
+
argv = (
|
|
254
|
+
'--svcurl', svcurl,
|
|
255
|
+
)
|
|
256
|
+
outp = s_output.OutPutStr()
|
|
257
|
+
self.eq(1, await s_t_moduser.main(argv, outp=outp))
|
|
258
|
+
self.isin('ERROR: A username argument is required when --list is not specified.', str(outp))
|
synapse/tests/utils.py
CHANGED
|
@@ -1444,7 +1444,7 @@ class SynTest(unittest.TestCase):
|
|
|
1444
1444
|
Get an Aha cell that is configured for provisioning on aha.loop.vertex.link.
|
|
1445
1445
|
|
|
1446
1446
|
Args:
|
|
1447
|
-
conf: Optional
|
|
1447
|
+
conf: Optional configuration information for the Aha cell.
|
|
1448
1448
|
dirn: Optional path to create the Aha cell in.
|
|
1449
1449
|
|
|
1450
1450
|
Returns:
|
|
@@ -2344,6 +2344,8 @@ class SynTest(unittest.TestCase):
|
|
|
2344
2344
|
return await core.nodes(query, opts)
|
|
2345
2345
|
return await core.schedCoro(coro())
|
|
2346
2346
|
|
|
2347
|
+
ONLOAD_TIMEOUT = int(os.getenv('SYNDEV_PKG_LOAD_TIMEOUT', 30)) # seconds
|
|
2348
|
+
|
|
2347
2349
|
class StormPkgTest(SynTest):
|
|
2348
2350
|
|
|
2349
2351
|
vcr = None
|
|
@@ -2351,12 +2353,26 @@ class StormPkgTest(SynTest):
|
|
|
2351
2353
|
pkgprotos = ()
|
|
2352
2354
|
|
|
2353
2355
|
@contextlib.asynccontextmanager
|
|
2354
|
-
async def getTestCore(self, conf=None, dirn=None):
|
|
2356
|
+
async def getTestCore(self, conf=None, dirn=None, prepkghook=None):
|
|
2355
2357
|
|
|
2356
2358
|
async with SynTest.getTestCore(self, conf=None, dirn=None) as core:
|
|
2357
2359
|
|
|
2360
|
+
if prepkghook is not None:
|
|
2361
|
+
await prepkghook(core)
|
|
2362
|
+
|
|
2358
2363
|
for pkgproto in self.pkgprotos:
|
|
2359
|
-
|
|
2364
|
+
|
|
2365
|
+
pkgdef = s_genpkg.loadPkgProto(pkgproto, no_docs=True, readonly=True)
|
|
2366
|
+
|
|
2367
|
+
waiter = None
|
|
2368
|
+
if pkgdef.get('onload') is not None:
|
|
2369
|
+
waiter = core.waiter(1, 'core:pkg:onload:complete')
|
|
2370
|
+
|
|
2371
|
+
await core.addStormPkg(pkgdef)
|
|
2372
|
+
|
|
2373
|
+
if waiter is not None:
|
|
2374
|
+
self.nn(await waiter.wait(timeout=ONLOAD_TIMEOUT),
|
|
2375
|
+
f'Package onload failed to run for {pkgdef.get("name")}')
|
|
2360
2376
|
|
|
2361
2377
|
if self.assetdir is not None:
|
|
2362
2378
|
|
|
@@ -2372,4 +2388,7 @@ class StormPkgTest(SynTest):
|
|
|
2372
2388
|
yield core
|
|
2373
2389
|
|
|
2374
2390
|
async def initTestCore(self, core):
|
|
2391
|
+
'''
|
|
2392
|
+
This is executed after the package has been loaded and a VCR context has been entered.
|
|
2393
|
+
'''
|
|
2375
2394
|
pass
|
synapse/tools/autodoc.py
CHANGED
|
@@ -717,7 +717,7 @@ async def docModel(outp,
|
|
|
717
717
|
raise s_exc.SynErr(mesg='Invalid example', form=form, example=example, info=mnfo)
|
|
718
718
|
if mtyp == 'node':
|
|
719
719
|
node = True
|
|
720
|
-
if not node: #
|
|
720
|
+
if not node: # pragma: no cover
|
|
721
721
|
raise s_exc.SynErr(mesg='Unable to make a node from example.', form=form, example=example)
|
|
722
722
|
|
|
723
723
|
rst = s_autodoc.RstHelp()
|
synapse/tools/hive/load.py
CHANGED
|
@@ -14,6 +14,9 @@ reqver = '>=0.2.0,<3.0.0'
|
|
|
14
14
|
|
|
15
15
|
async def main(argv, outp=s_output.stdout):
|
|
16
16
|
|
|
17
|
+
mesg = s_common.deprecated('synapse.tools.hive.load', curv='2.167.0')
|
|
18
|
+
outp.printf(f'WARNING: {mesg}')
|
|
19
|
+
|
|
17
20
|
pars = argparse.ArgumentParser(prog='synapse.tools.hive.load',
|
|
18
21
|
description='Load data into a remote hive from a previous hivesave.')
|
|
19
22
|
|
synapse/tools/hive/save.py
CHANGED
|
@@ -14,6 +14,9 @@ reqver = '>=0.2.0,<3.0.0'
|
|
|
14
14
|
|
|
15
15
|
async def main(argv, outp=s_output.stdout):
|
|
16
16
|
|
|
17
|
+
mesg = s_common.deprecated('synapse.tools.hive.save', curv='2.167.0')
|
|
18
|
+
outp.printf(f'WARNING: {mesg}')
|
|
19
|
+
|
|
17
20
|
pars = argparse.ArgumentParser(prog='synapse.tools.hive.save',
|
|
18
21
|
description='Save tree data from a remote hive to file.')
|
|
19
22
|
|