synapse 2.165.0__py311-none-any.whl → 2.166.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/cmds/cortex.py +1 -6
- synapse/common.py +6 -0
- synapse/cortex.py +73 -56
- synapse/datamodel.py +32 -0
- synapse/lib/agenda.py +81 -51
- synapse/lib/ast.py +21 -23
- synapse/lib/base.py +0 -6
- synapse/lib/cell.py +13 -22
- synapse/lib/httpapi.py +1 -0
- synapse/lib/nexus.py +3 -2
- synapse/lib/schemas.py +2 -0
- synapse/lib/snap.py +50 -0
- synapse/lib/storm.py +19 -17
- synapse/lib/stormlib/aha.py +4 -1
- synapse/lib/stormlib/auth.py +11 -4
- synapse/lib/stormlib/cache.py +202 -0
- synapse/lib/stormlib/cortex.py +69 -7
- synapse/lib/stormlib/spooled.py +109 -0
- synapse/lib/stormtypes.py +43 -15
- synapse/lib/trigger.py +10 -12
- synapse/lib/types.py +1 -1
- synapse/lib/version.py +2 -2
- synapse/lib/view.py +12 -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 +114 -32
- synapse/tests/test_cortex.py +40 -6
- synapse/tests/test_datamodel.py +22 -0
- synapse/tests/test_lib_agenda.py +8 -1
- synapse/tests/test_lib_aha.py +18 -4
- synapse/tests/test_lib_storm.py +95 -4
- synapse/tests/test_lib_stormlib_cache.py +272 -0
- synapse/tests/test_lib_stormlib_cortex.py +71 -0
- synapse/tests/test_lib_stormlib_spooled.py +190 -0
- synapse/tests/test_lib_stormtypes.py +27 -4
- 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_modrole.py +81 -0
- synapse/tests/test_tools_moduser.py +105 -0
- synapse/tools/modrole.py +59 -7
- synapse/tools/moduser.py +78 -10
- {synapse-2.165.0.dist-info → synapse-2.166.0.dist-info}/METADATA +2 -2
- {synapse-2.165.0.dist-info → synapse-2.166.0.dist-info}/RECORD +49 -47
- synapse/lib/provenance.py +0 -111
- synapse/tests/test_lib_provenance.py +0 -37
- {synapse-2.165.0.dist-info → synapse-2.166.0.dist-info}/LICENSE +0 -0
- {synapse-2.165.0.dist-info → synapse-2.166.0.dist-info}/WHEEL +0 -0
- {synapse-2.165.0.dist-info → synapse-2.166.0.dist-info}/top_level.txt +0 -0
synapse/tests/test_lib_agenda.py
CHANGED
|
@@ -361,10 +361,13 @@ class AgendaTest(s_t_utils.SynTest):
|
|
|
361
361
|
|
|
362
362
|
# schedule a query to run every Wednesday and Friday at 10:15am
|
|
363
363
|
cdef = {'creator': visi.iden, 'iden': s_common.guid(), 'storm': '$lib.queue.gen(visi).put(bar)',
|
|
364
|
+
'pool': True,
|
|
364
365
|
'reqs': {s_tu.HOUR: 10, s_tu.MINUTE: 15},
|
|
365
366
|
'incunit': s_agenda.TimeUnit.DAYOFWEEK,
|
|
366
367
|
'incvals': (2, 4)}
|
|
367
368
|
adef = await agenda.add(cdef)
|
|
369
|
+
|
|
370
|
+
self.true(adef['pool'])
|
|
368
371
|
guid = adef.get('iden')
|
|
369
372
|
|
|
370
373
|
self.len(1, agenda.apptheap)
|
|
@@ -634,7 +637,7 @@ class AgendaTest(s_t_utils.SynTest):
|
|
|
634
637
|
nodes = await core.nodes('test:int=97', opts={'view': newview})
|
|
635
638
|
self.len(0, nodes)
|
|
636
639
|
|
|
637
|
-
async def
|
|
640
|
+
async def test_agenda_edit(self):
|
|
638
641
|
|
|
639
642
|
async with self.getTestCore() as core:
|
|
640
643
|
|
|
@@ -645,8 +648,12 @@ class AgendaTest(s_t_utils.SynTest):
|
|
|
645
648
|
self.stormHasNoWarnErr(msgs)
|
|
646
649
|
|
|
647
650
|
cdef = await core.callStorm('for $cron in $lib.cron.list() { return($cron) }')
|
|
651
|
+
self.false(cdef['pool'])
|
|
648
652
|
self.eq(cdef['creator'], core.auth.rootuser.iden)
|
|
649
653
|
|
|
654
|
+
cdef = await core.callStorm('for $cron in $lib.cron.list() { $cron.set(pool, (true)) return($cron) }')
|
|
655
|
+
self.true(cdef['pool'])
|
|
656
|
+
|
|
650
657
|
opts = {'vars': {'lowuser': lowuser}}
|
|
651
658
|
cdef = await core.callStorm('for $cron in $lib.cron.list() { return($cron.set(creator, $lowuser)) }',
|
|
652
659
|
opts=opts)
|
synapse/tests/test_lib_aha.py
CHANGED
|
@@ -186,8 +186,8 @@ class AhaTest(s_test.SynTest):
|
|
|
186
186
|
self.nn(await proxy.getCellIden())
|
|
187
187
|
|
|
188
188
|
with self.raises(s_exc.BadArg):
|
|
189
|
-
await cryo.ahaclient.
|
|
190
|
-
await
|
|
189
|
+
_proxy = await cryo.ahaclient.proxy(timeout=2)
|
|
190
|
+
await _proxy.modAhaSvcInfo('cryo.mynet', {'newp': 'newp'})
|
|
191
191
|
|
|
192
192
|
async with await s_telepath.openurl('aha://root:secret@0.cryo.mynet') as proxy:
|
|
193
193
|
self.nn(await proxy.getCellIden())
|
|
@@ -1169,13 +1169,24 @@ class AhaTest(s_test.SynTest):
|
|
|
1169
1169
|
self.stormHasNoWarnErr(msgs)
|
|
1170
1170
|
self.stormIsInPrint('Created AHA service pool: pool00.loop.vertex.link', msgs)
|
|
1171
1171
|
|
|
1172
|
-
|
|
1173
|
-
|
|
1172
|
+
# Pool has no members....
|
|
1173
|
+
pool = await s_telepath.open('aha://pool00...')
|
|
1174
|
+
self.eq(0, pool.size())
|
|
1175
|
+
waiter = pool.waiter(0, 'svc:add')
|
|
1174
1176
|
|
|
1175
1177
|
msgs = await core00.stormlist('aha.pool.svc.add pool00... 00...')
|
|
1176
1178
|
self.stormHasNoWarnErr(msgs)
|
|
1177
1179
|
self.stormIsInPrint('AHA service (00...) added to service pool (pool00.loop.vertex.link)', msgs)
|
|
1178
1180
|
|
|
1181
|
+
self.len(1, await waiter.wait(timeout=12))
|
|
1182
|
+
prox = await pool.proxy(timeout=12)
|
|
1183
|
+
info = await prox.getCellInfo()
|
|
1184
|
+
self.eq('00', info.get('cell').get('aha').get('name'))
|
|
1185
|
+
self.eq(1, pool.size())
|
|
1186
|
+
await pool.fini()
|
|
1187
|
+
self.eq(0, pool.size())
|
|
1188
|
+
self.true(prox.isfini)
|
|
1189
|
+
|
|
1179
1190
|
poolinfo = await aha.getAhaPool('pool00...')
|
|
1180
1191
|
self.len(1, poolinfo['services'])
|
|
1181
1192
|
|
|
@@ -1184,6 +1195,9 @@ class AhaTest(s_test.SynTest):
|
|
|
1184
1195
|
self.stormIsInPrint(' 00.loop.vertex.link', msgs)
|
|
1185
1196
|
self.stormIsInPrint('1 pools', msgs)
|
|
1186
1197
|
|
|
1198
|
+
msgs = await core00.stormlist('$lib.print($lib.aha.pool.get(pool00.loop.vertex.link))')
|
|
1199
|
+
self.stormIsInPrint('aha:pool: pool00.loop.vertex.link', msgs)
|
|
1200
|
+
|
|
1187
1201
|
async with await s_telepath.open('aha://pool00...') as pool:
|
|
1188
1202
|
|
|
1189
1203
|
replay = s_common.envbool('SYNDEV_NEXUS_REPLAY')
|
synapse/tests/test_lib_storm.py
CHANGED
|
@@ -1262,7 +1262,7 @@ class StormTest(s_t_utils.SynTest):
|
|
|
1262
1262
|
query = await core.getStormQuery('')
|
|
1263
1263
|
async with snap.getStormRuntime(query) as runt:
|
|
1264
1264
|
with self.raises(s_exc.AuthDeny):
|
|
1265
|
-
runt.reqAdmin(gateiden=
|
|
1265
|
+
runt.reqAdmin(gateiden=layr)
|
|
1266
1266
|
|
|
1267
1267
|
await core.stormlist('[ inet:fqdn=vertex.link ]')
|
|
1268
1268
|
fork = await core.callStorm('return($lib.view.get().fork().iden)')
|
|
@@ -1772,13 +1772,92 @@ class StormTest(s_t_utils.SynTest):
|
|
|
1772
1772
|
self.eq('796d67b92a6ffe9b88fa19d115b46ab6712d673a06ae602d41de84b1464782f2', node[1]['embeds']['asn']['*'])
|
|
1773
1773
|
|
|
1774
1774
|
opts = {'embeds': {'ou:org': {'hq::email': ('user',)}}}
|
|
1775
|
-
msgs = await core.stormlist('[ ou:org=* :hq=* ] { -> ps:contact [ :email=visi@vertex.link ] }', opts=opts)
|
|
1775
|
+
msgs = await core.stormlist('[ ou:org=* :country=* :hq=* ] { -> ps:contact [ :email=visi@vertex.link ] }', opts=opts)
|
|
1776
1776
|
nodes = [m[1] for m in msgs if m[0] == 'node']
|
|
1777
|
-
|
|
1778
1777
|
node = nodes[0]
|
|
1778
|
+
|
|
1779
1779
|
self.eq('visi', node[1]['embeds']['hq::email']['user'])
|
|
1780
1780
|
self.eq('2346d7bed4b0fae05e00a413bbf8716c9e08857eb71a1ecf303b8972823f2899', node[1]['embeds']['hq::email']['*'])
|
|
1781
1781
|
|
|
1782
|
+
fork = await core.callStorm('return($lib.view.get().fork().iden)')
|
|
1783
|
+
|
|
1784
|
+
opts['vars'] = {
|
|
1785
|
+
'md5': '12345a5758eea935f817dd1490a322a5',
|
|
1786
|
+
'sha1': '40b8e76cff472e593bd0ba148c09fec66ae72362'
|
|
1787
|
+
}
|
|
1788
|
+
opts['view'] = fork
|
|
1789
|
+
opts['show:storage'] = True
|
|
1790
|
+
opts['embeds']['ou:org']['lol::nope'] = ('notreal',)
|
|
1791
|
+
opts['embeds']['ou:org']['country::flag'] = ('md5', 'sha1')
|
|
1792
|
+
opts['embeds']['ou:org']['country::tld'] = ('domain',)
|
|
1793
|
+
|
|
1794
|
+
await core.stormlist('pol:country [ :flag={[ file:bytes=* :md5=fa818a259cbed7ce8bc2a22d35a464fc ]} ]')
|
|
1795
|
+
|
|
1796
|
+
msgs = await core.stormlist('''
|
|
1797
|
+
ou:org {
|
|
1798
|
+
-> pol:country
|
|
1799
|
+
[ :tld=co.uk ]
|
|
1800
|
+
{
|
|
1801
|
+
:flag -> file:bytes [ :md5=$md5 :sha1=$sha1 ]
|
|
1802
|
+
}
|
|
1803
|
+
}
|
|
1804
|
+
''', opts=opts)
|
|
1805
|
+
nodes = [m[1] for m in msgs if m[0] == 'node']
|
|
1806
|
+
node = nodes[0]
|
|
1807
|
+
|
|
1808
|
+
storage = node[1]['storage']
|
|
1809
|
+
self.len(2, storage)
|
|
1810
|
+
top = storage[0].get('embeds')
|
|
1811
|
+
bot = storage[1].get('embeds')
|
|
1812
|
+
self.nn(top)
|
|
1813
|
+
self.nn(bot)
|
|
1814
|
+
|
|
1815
|
+
self.nn(top.get('country::flag::md5'))
|
|
1816
|
+
self.eq(top['country::flag::md5'][0], '12345a5758eea935f817dd1490a322a5')
|
|
1817
|
+
|
|
1818
|
+
self.nn(top.get('country::flag::sha1'))
|
|
1819
|
+
self.eq(top['country::flag::sha1'][0], '40b8e76cff472e593bd0ba148c09fec66ae72362')
|
|
1820
|
+
|
|
1821
|
+
self.nn(top.get('country::tld::domain'))
|
|
1822
|
+
self.eq(top['country::tld::domain'][0], 'uk')
|
|
1823
|
+
|
|
1824
|
+
self.nn(bot.get('hq::email::user'))
|
|
1825
|
+
self.eq(bot['hq::email::user'][0], 'visi')
|
|
1826
|
+
|
|
1827
|
+
self.nn(bot.get('country::flag::md5'))
|
|
1828
|
+
self.eq(bot['country::flag::md5'][0], 'fa818a259cbed7ce8bc2a22d35a464fc')
|
|
1829
|
+
|
|
1830
|
+
empty = await core.callStorm('return($lib.view.get().fork().iden)', opts=opts)
|
|
1831
|
+
opts['view'] = empty
|
|
1832
|
+
|
|
1833
|
+
msgs = await core.stormlist('ou:org', opts=opts)
|
|
1834
|
+
nodes = [m[1] for m in msgs if m[0] == 'node']
|
|
1835
|
+
node = nodes[0]
|
|
1836
|
+
storage = node[1]['storage']
|
|
1837
|
+
self.len(3, storage)
|
|
1838
|
+
top = storage[0].get('embeds')
|
|
1839
|
+
mid = storage[1].get('embeds')
|
|
1840
|
+
bot = storage[2].get('embeds')
|
|
1841
|
+
self.none(top)
|
|
1842
|
+
|
|
1843
|
+
self.nn(mid)
|
|
1844
|
+
self.nn(bot)
|
|
1845
|
+
|
|
1846
|
+
self.nn(mid.get('country::flag::md5'))
|
|
1847
|
+
self.eq(mid['country::flag::md5'][0], '12345a5758eea935f817dd1490a322a5')
|
|
1848
|
+
|
|
1849
|
+
self.nn(mid.get('country::flag::sha1'))
|
|
1850
|
+
self.eq(mid['country::flag::sha1'][0], '40b8e76cff472e593bd0ba148c09fec66ae72362')
|
|
1851
|
+
|
|
1852
|
+
self.nn(mid.get('country::tld::domain'))
|
|
1853
|
+
self.eq(mid['country::tld::domain'][0], 'uk')
|
|
1854
|
+
|
|
1855
|
+
self.nn(bot.get('hq::email::user'))
|
|
1856
|
+
self.eq(bot['hq::email::user'][0], 'visi')
|
|
1857
|
+
|
|
1858
|
+
self.nn(bot.get('country::flag::md5'))
|
|
1859
|
+
self.eq(bot['country::flag::md5'][0], 'fa818a259cbed7ce8bc2a22d35a464fc')
|
|
1860
|
+
|
|
1782
1861
|
async def test_storm_wget(self):
|
|
1783
1862
|
|
|
1784
1863
|
async def _getRespFromSha(core, mesgs):
|
|
@@ -2151,7 +2230,7 @@ class StormTest(s_t_utils.SynTest):
|
|
|
2151
2230
|
|
|
2152
2231
|
# Max recursion fail
|
|
2153
2232
|
q = '[ inet:fqdn=www.vertex.link ] | tree { inet:fqdn=www.vertex.link }'
|
|
2154
|
-
await self.asyncraises(s_exc.
|
|
2233
|
+
await self.asyncraises(s_exc.RecursionLimitHit, core.nodes(q))
|
|
2155
2234
|
|
|
2156
2235
|
# Runtsafety test
|
|
2157
2236
|
q = '[ inet:fqdn=www.vertex.link ] $q=:domain | tree $q'
|
|
@@ -2359,6 +2438,18 @@ class StormTest(s_t_utils.SynTest):
|
|
|
2359
2438
|
with self.raises(s_exc.BadOperArg):
|
|
2360
2439
|
await core.nodes('movetag this is')
|
|
2361
2440
|
|
|
2441
|
+
async with self.getTestCore() as core:
|
|
2442
|
+
await core.nodes('[ syn:tag=hehe :isnow=haha ]')
|
|
2443
|
+
nodes = await core.nodes('[ ou:org=* +#hehe.qwer ]')
|
|
2444
|
+
self.len(1, nodes)
|
|
2445
|
+
self.nn(nodes[0].getTag('haha.qwer'))
|
|
2446
|
+
self.none(nodes[0].getTag('hehe.qwer'))
|
|
2447
|
+
self.len(1, await core.nodes('syn:tag=haha.qwer'))
|
|
2448
|
+
|
|
2449
|
+
# this should hit the already existing redirected tag now...
|
|
2450
|
+
nodes = await core.nodes('[ ou:org=* +#hehe.qwer ]')
|
|
2451
|
+
self.len(1, nodes)
|
|
2452
|
+
|
|
2362
2453
|
# Sad path
|
|
2363
2454
|
async with self.getTestCore() as core:
|
|
2364
2455
|
# Test moving a tag to itself
|
|
@@ -0,0 +1,272 @@
|
|
|
1
|
+
import synapse.exc as s_exc
|
|
2
|
+
|
|
3
|
+
import synapse.tests.utils as s_test
|
|
4
|
+
|
|
5
|
+
class StormlibCacheTest(s_test.SynTest):
|
|
6
|
+
|
|
7
|
+
async def test_storm_lib_cache_fixed(self):
|
|
8
|
+
|
|
9
|
+
async with self.getTestCore() as core:
|
|
10
|
+
|
|
11
|
+
# basics
|
|
12
|
+
|
|
13
|
+
rets = await core.callStorm('''
|
|
14
|
+
$rets = ([])
|
|
15
|
+
$cache = $lib.cache.fixed("return(`{$cache_key}-ret`)")
|
|
16
|
+
|
|
17
|
+
$cache.clear()
|
|
18
|
+
|
|
19
|
+
$rets.append($lib.len($cache))
|
|
20
|
+
|
|
21
|
+
$rets.append($cache.get(key))
|
|
22
|
+
$rets.append($lib.len($cache))
|
|
23
|
+
|
|
24
|
+
$cache.put(key, key-put)
|
|
25
|
+
$rets.append($cache.get(key))
|
|
26
|
+
|
|
27
|
+
$cache.clear()
|
|
28
|
+
$rets.append($cache.get(key))
|
|
29
|
+
|
|
30
|
+
$cache.put(key, key-put)
|
|
31
|
+
$rets.append($cache.get(key))
|
|
32
|
+
$rets.append($cache.pop(key))
|
|
33
|
+
$rets.append($cache.get(key))
|
|
34
|
+
|
|
35
|
+
$rets.append($cache.pop(newp))
|
|
36
|
+
|
|
37
|
+
$rets.append($cache.query)
|
|
38
|
+
|
|
39
|
+
return($rets)
|
|
40
|
+
''')
|
|
41
|
+
self.eq([
|
|
42
|
+
0,
|
|
43
|
+
'key-ret', 1,
|
|
44
|
+
'key-put',
|
|
45
|
+
'key-ret',
|
|
46
|
+
'key-put', 'key-put', 'key-ret',
|
|
47
|
+
None,
|
|
48
|
+
'return(`{$cache_key}-ret`)'
|
|
49
|
+
], rets)
|
|
50
|
+
|
|
51
|
+
# exhaust size
|
|
52
|
+
|
|
53
|
+
rets = await core.callStorm('''
|
|
54
|
+
$rets = ([])
|
|
55
|
+
$cache = $lib.cache.fixed("return(`{$cache_key}-ret`)", size=2)
|
|
56
|
+
|
|
57
|
+
$cache.put(one, one-put)
|
|
58
|
+
$cache.put(two, two-put)
|
|
59
|
+
$rets.append($cache.get(one))
|
|
60
|
+
$rets.append($cache.get(two))
|
|
61
|
+
|
|
62
|
+
$rets.append($cache.get(three))
|
|
63
|
+
$rets.append($cache.get(one))
|
|
64
|
+
|
|
65
|
+
return($rets)
|
|
66
|
+
''')
|
|
67
|
+
self.eq(['one-put', 'two-put', 'three-ret', 'one-ret'], rets)
|
|
68
|
+
|
|
69
|
+
# also accept a storm query object
|
|
70
|
+
|
|
71
|
+
ret = await core.callStorm('''
|
|
72
|
+
$cache = $lib.cache.fixed(${ $suf=ret return(`{$cache_key}-{$suf}`)})
|
|
73
|
+
return($cache.get(foo))
|
|
74
|
+
''')
|
|
75
|
+
self.eq('foo-ret', ret)
|
|
76
|
+
|
|
77
|
+
# callback runtime scoping
|
|
78
|
+
|
|
79
|
+
## a function still has the outer scope as its root
|
|
80
|
+
rets = await core.callStorm('''
|
|
81
|
+
$val = zero
|
|
82
|
+
$sent = $lib.null
|
|
83
|
+
|
|
84
|
+
function cb(key) {
|
|
85
|
+
$sent = $val
|
|
86
|
+
return(`{$key}-{$val}`)
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
$cache = $lib.cache.fixed("return($cb($cache_key))")
|
|
90
|
+
|
|
91
|
+
$rets = ([])
|
|
92
|
+
|
|
93
|
+
$rets.append($cache.get(foo))
|
|
94
|
+
$rets.append($sent)
|
|
95
|
+
|
|
96
|
+
$val = one
|
|
97
|
+
$rets.append($cache.get(bar))
|
|
98
|
+
$rets.append($sent)
|
|
99
|
+
|
|
100
|
+
return($rets)
|
|
101
|
+
''')
|
|
102
|
+
self.eq([
|
|
103
|
+
'foo-zero', 'zero',
|
|
104
|
+
'bar-one', 'one'
|
|
105
|
+
], rets)
|
|
106
|
+
|
|
107
|
+
## runtime also can modify refs to the outer scope
|
|
108
|
+
rets = await core.callStorm('''
|
|
109
|
+
$val = zero
|
|
110
|
+
$vals = ([])
|
|
111
|
+
$sent = $lib.null
|
|
112
|
+
|
|
113
|
+
$cache = $lib.cache.fixed(${
|
|
114
|
+
$sent = $val
|
|
115
|
+
$vals.append($cache_key)
|
|
116
|
+
return(`{$cache_key}-{$val}`)
|
|
117
|
+
})
|
|
118
|
+
|
|
119
|
+
$rets = ([])
|
|
120
|
+
|
|
121
|
+
$rets.append($cache.get(foo))
|
|
122
|
+
$rets.append($sent)
|
|
123
|
+
$rets.append($lib.str.join(",", $vals))
|
|
124
|
+
|
|
125
|
+
$val = one
|
|
126
|
+
$rets.append($cache.get(bar))
|
|
127
|
+
$rets.append($sent)
|
|
128
|
+
$rets.append($lib.str.join(",", $vals))
|
|
129
|
+
|
|
130
|
+
return($rets)
|
|
131
|
+
''')
|
|
132
|
+
self.eq([
|
|
133
|
+
'foo-zero', None, 'foo',
|
|
134
|
+
'bar-one', None, 'foo,bar',
|
|
135
|
+
], rets)
|
|
136
|
+
|
|
137
|
+
## default to null w/o a return
|
|
138
|
+
self.none(await core.callStorm('return($lib.cache.fixed("if (0) { return(yup) }").get(foo))'))
|
|
139
|
+
|
|
140
|
+
## control flow exceptions don't propagate up
|
|
141
|
+
rets = await core.callStorm('''
|
|
142
|
+
$cache = $lib.cache.fixed( ${ if ($cache_key < (2)) { return (`key={$cache_key}`) } else { break } } )
|
|
143
|
+
|
|
144
|
+
$rets = ([])
|
|
145
|
+
|
|
146
|
+
for $i in $lib.range(4) {
|
|
147
|
+
$rets.append($cache.get($i))
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
$rets.append(`i={$i}`)
|
|
151
|
+
return($rets)
|
|
152
|
+
''')
|
|
153
|
+
self.eq(['key=0', 'key=1', None, None, 'i=3'], rets)
|
|
154
|
+
|
|
155
|
+
## control flow scoped inside the callback
|
|
156
|
+
rets = await core.callStorm("""
|
|
157
|
+
$cache = $lib.cache.fixed('''
|
|
158
|
+
$vals = ([])
|
|
159
|
+
for $i in $lib.range(3) {
|
|
160
|
+
$vals.append(`key={$cache_key} i={$i}`)
|
|
161
|
+
break
|
|
162
|
+
}
|
|
163
|
+
return($vals)
|
|
164
|
+
''')
|
|
165
|
+
|
|
166
|
+
$rets = ([])
|
|
167
|
+
|
|
168
|
+
for $k in (foo, bar, baz) {
|
|
169
|
+
$rets.append($cache.get($k))
|
|
170
|
+
}
|
|
171
|
+
|
|
172
|
+
return($rets)
|
|
173
|
+
""")
|
|
174
|
+
self.eq([('key=foo i=0',), ('key=bar i=0',), ('key=baz i=0',),], rets)
|
|
175
|
+
|
|
176
|
+
## coverage for the cb runtime emiting nodes
|
|
177
|
+
rets = await core.callStorm('''
|
|
178
|
+
$rets = ([])
|
|
179
|
+
$cache = $lib.cache.fixed(${ if (0) { return(yup) } [ inet:ipv4=$cache_key ] })
|
|
180
|
+
|
|
181
|
+
for $i in (0, 1) {
|
|
182
|
+
$rets.append($cache.get($i))
|
|
183
|
+
}
|
|
184
|
+
return($rets)
|
|
185
|
+
''')
|
|
186
|
+
self.eq([None, None], rets)
|
|
187
|
+
|
|
188
|
+
# stormrepr
|
|
189
|
+
|
|
190
|
+
msgs = await core.stormlist('''
|
|
191
|
+
$lib.print($lib.cache.fixed(${return(cool)}))
|
|
192
|
+
$lib.print($lib.cache.fixed($longq))
|
|
193
|
+
''', opts={'vars': {'longq': f'return({"a" * 150})'}})
|
|
194
|
+
self.stormIsInPrint('cache:fixed: size=10000 query="return(cool)"', msgs)
|
|
195
|
+
self.stormIsInPrint('aaaaa...', msgs)
|
|
196
|
+
|
|
197
|
+
# sad
|
|
198
|
+
|
|
199
|
+
## bad storm query
|
|
200
|
+
|
|
201
|
+
with self.raises(s_exc.BadArg) as ectx:
|
|
202
|
+
await core.nodes('$lib.cache.fixed("function x -> newp")')
|
|
203
|
+
self.isin('Invalid callback query', ectx.exception.errinfo.get('mesg'))
|
|
204
|
+
|
|
205
|
+
## no return
|
|
206
|
+
|
|
207
|
+
with self.raises(s_exc.BadArg) as ectx:
|
|
208
|
+
await core.nodes('$lib.cache.fixed("$x=1")')
|
|
209
|
+
self.eq('Callback query must return a value', ectx.exception.errinfo.get('mesg'))
|
|
210
|
+
|
|
211
|
+
## bad size
|
|
212
|
+
|
|
213
|
+
with self.raises(s_exc.BadArg) as ectx:
|
|
214
|
+
await core.nodes('$lib.cache.fixed("return()", size=(-1))')
|
|
215
|
+
self.eq('Cache size must be between 1-10000', ectx.exception.errinfo.get('mesg'))
|
|
216
|
+
|
|
217
|
+
with self.raises(s_exc.BadArg) as ectx:
|
|
218
|
+
await core.nodes('$lib.cache.fixed("return()", size=(1000000))')
|
|
219
|
+
self.eq('Cache size must be between 1-10000', ectx.exception.errinfo.get('mesg'))
|
|
220
|
+
|
|
221
|
+
## callback raises an exception
|
|
222
|
+
|
|
223
|
+
rets = await core.callStorm('''
|
|
224
|
+
function cb(key) {
|
|
225
|
+
if ($key = "sad") {
|
|
226
|
+
$lib.raise(Bad, Time)
|
|
227
|
+
}
|
|
228
|
+
return(`{$key}-happy`)
|
|
229
|
+
}
|
|
230
|
+
$cache = $lib.cache.fixed("return($cb($cache_key))")
|
|
231
|
+
|
|
232
|
+
$rets = ([])
|
|
233
|
+
|
|
234
|
+
try {
|
|
235
|
+
$rets.append($cache.get(sad))
|
|
236
|
+
} catch Bad as e {
|
|
237
|
+
$rets.append(badtime)
|
|
238
|
+
}
|
|
239
|
+
|
|
240
|
+
$rets.append($cache.get(foo))
|
|
241
|
+
|
|
242
|
+
return($rets)
|
|
243
|
+
''')
|
|
244
|
+
self.eq(['badtime', 'foo-happy'], rets)
|
|
245
|
+
|
|
246
|
+
with self.raises(s_exc.BadCast) as ectx:
|
|
247
|
+
await core.nodes('$lib.cache.fixed(${ return(($cache_key * 3)) }).get(foo)')
|
|
248
|
+
self.eq('Failed to make an integer from \'foo\'.', ectx.exception.errinfo.get('mesg'))
|
|
249
|
+
|
|
250
|
+
## mutable key
|
|
251
|
+
|
|
252
|
+
with self.raises(s_exc.BadArg) as ectx:
|
|
253
|
+
await core.nodes('$lib.cache.fixed("return()").get((foo,))')
|
|
254
|
+
self.eq('Mutable values are not allowed as cache keys', ectx.exception.errinfo.get('mesg'))
|
|
255
|
+
|
|
256
|
+
with self.raises(s_exc.BadArg) as ectx:
|
|
257
|
+
await core.nodes('$lib.cache.fixed("return()").put((foo,), bar)')
|
|
258
|
+
self.eq('Mutable values are not allowed as cache keys', ectx.exception.errinfo.get('mesg'))
|
|
259
|
+
|
|
260
|
+
with self.raises(s_exc.BadArg) as ectx:
|
|
261
|
+
await core.nodes('$lib.cache.fixed("return()").pop((foo,))')
|
|
262
|
+
self.eq('Mutable values are not allowed as cache keys', ectx.exception.errinfo.get('mesg'))
|
|
263
|
+
|
|
264
|
+
## non-primable key
|
|
265
|
+
|
|
266
|
+
with self.raises(s_exc.NoSuchType) as ectx:
|
|
267
|
+
await core.nodes('$cache = $lib.cache.fixed("return()") $cache.get($cache)')
|
|
268
|
+
self.eq('Unable to convert object to Storm primitive.', ectx.exception.errinfo.get('mesg'))
|
|
269
|
+
|
|
270
|
+
## missing use of $cache_key - no error
|
|
271
|
+
|
|
272
|
+
self.eq('newp', await core.callStorm('return($lib.cache.fixed("return(newp)").get(foo))'))
|
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
import json
|
|
2
2
|
|
|
3
|
+
import unittest.mock as mock
|
|
4
|
+
|
|
3
5
|
import aiohttp
|
|
4
6
|
|
|
5
7
|
import synapse.common as s_common
|
|
@@ -393,6 +395,9 @@ $request.reply(206, headers=$headers, body=({"no":"body"}))
|
|
|
393
395
|
return ( $api.iden )
|
|
394
396
|
'''
|
|
395
397
|
iden0 = await core.callStorm(q)
|
|
398
|
+
msgs = await core.stormlist('$lib.print($lib.cortex.httpapi.get($iden))', opts={'vars': {'iden': iden0}})
|
|
399
|
+
mesg = 'http:api: the hehe wildcard handler (********************************), path=hehe/([a-z0-9]*)'
|
|
400
|
+
self.stormIsInPrint(mesg, msgs, deguid=True)
|
|
396
401
|
|
|
397
402
|
q = '''
|
|
398
403
|
$api = $lib.cortex.httpapi.add('hehe/haha')
|
|
@@ -401,6 +406,7 @@ $request.reply(206, headers=$headers, body=({"no":"body"}))
|
|
|
401
406
|
$api.name = 'the hehe/haha handler'
|
|
402
407
|
$api.desc = 'beep boop zoop robot captain'
|
|
403
408
|
$api.runas = user
|
|
409
|
+
$api.pool = (true)
|
|
404
410
|
$api.perms = (
|
|
405
411
|
({"perm": ["hehe", "haha"]}),
|
|
406
412
|
({"perm": ["some", "thing"], "default": $lib.true}),
|
|
@@ -428,6 +434,9 @@ $request.reply(206, headers=$headers, body=({"no":"body"}))
|
|
|
428
434
|
return ( $api.iden )
|
|
429
435
|
'''
|
|
430
436
|
iden3 = await core.callStorm(q)
|
|
437
|
+
msgs = await core.stormlist('$lib.print($lib.cortex.httpapi.get($iden))', opts={'vars': {'iden': iden3}})
|
|
438
|
+
mesg = 'http:api: <no name> (********************************), path=wow'
|
|
439
|
+
self.stormIsInPrint(mesg, msgs, deguid=True)
|
|
431
440
|
|
|
432
441
|
# $lib.dict accessor methods
|
|
433
442
|
q = '$api=$lib.cortex.httpapi.get($iden) return ($lib.dict.keys($api.vars))'
|
|
@@ -473,6 +482,15 @@ $request.reply(206, headers=$headers, body=({"no":"body"}))
|
|
|
473
482
|
self.stormIsInPrint(f'2 {iden2}', msgs)
|
|
474
483
|
self.stormIsInPrint(f'3 {iden3}', msgs)
|
|
475
484
|
|
|
485
|
+
q = '''
|
|
486
|
+
$ret = $lib.null $api = $lib.cortex.httpapi.getByPath($path)
|
|
487
|
+
if $api { $ret = $api.iden}
|
|
488
|
+
return ( $ret )
|
|
489
|
+
'''
|
|
490
|
+
self.eq(iden0, await core.callStorm(q, opts={'vars': {'path': 'hehe/haha'}}))
|
|
491
|
+
self.eq(iden0, await core.callStorm(q, opts={'vars': {'path': 'hehe/ohmy'}}))
|
|
492
|
+
self.none(await core.callStorm(q, opts={'vars': {'path': 'newpnewpnewp'}}))
|
|
493
|
+
|
|
476
494
|
# Order matters. The hehe/haha path occurs after the wildcard.
|
|
477
495
|
async with self.getHttpSess(auth=('root', 'root'), port=hport) as sess:
|
|
478
496
|
resp = await sess.get(f'https://localhost:{hport}/api/ext/hehe/haha')
|
|
@@ -494,6 +512,9 @@ $request.reply(206, headers=$headers, body=({"no":"body"}))
|
|
|
494
512
|
msgs = await core.stormlist('cortex.httpapi.index $iden 1', opts={'vars': {'iden': iden0}})
|
|
495
513
|
self.stormIsInPrint(f'Set HTTP API {iden0} to index 1', msgs)
|
|
496
514
|
|
|
515
|
+
self.eq(iden1, await core.callStorm(q, opts={'vars': {'path': 'hehe/haha'}}))
|
|
516
|
+
self.eq(iden0, await core.callStorm(q, opts={'vars': {'path': 'hehe/ohmy'}}))
|
|
517
|
+
|
|
497
518
|
msgs = await core.stormlist('cortex.httpapi.list')
|
|
498
519
|
self.stormIsInPrint(f'0 {iden1}', msgs)
|
|
499
520
|
self.stormIsInPrint(f'1 {iden0}', msgs)
|
|
@@ -562,6 +583,7 @@ $request.reply(206, headers=$headers, body=({"no":"body"}))
|
|
|
562
583
|
self.stormIsInPrint('Owner: root', msgs)
|
|
563
584
|
self.stormIsInPrint('Runas: owner', msgs)
|
|
564
585
|
self.stormIsInPrint('Readonly: false', msgs)
|
|
586
|
+
self.stormIsInPrint('Pool enabled: false', msgs)
|
|
565
587
|
self.stormIsInPrint('Authenticated: true', msgs)
|
|
566
588
|
self.stormIsInPrint('Name: the hehe wildcard handler', msgs)
|
|
567
589
|
self.stormIsInPrint('Description: wildcard words', msgs)
|
|
@@ -596,6 +618,7 @@ $request.reply(206, headers=$headers, body=({"no":"body"}))
|
|
|
596
618
|
self.stormIsInPrint('Owner: root', msgs)
|
|
597
619
|
self.stormIsInPrint('Runas: user', msgs)
|
|
598
620
|
self.stormIsInPrint('Readonly: false', msgs)
|
|
621
|
+
self.stormIsInPrint('Pool enabled: true', msgs)
|
|
599
622
|
self.stormIsInPrint('Authenticated: true', msgs)
|
|
600
623
|
self.stormIsInPrint('Name: the hehe/haha handler', msgs)
|
|
601
624
|
self.stormIsInPrint('Description: beep boop zoop robot captain', msgs)
|
|
@@ -1373,3 +1396,51 @@ for $i in $values {
|
|
|
1373
1396
|
self.none(resp.headers.get('X-Content-Type-Options'))
|
|
1374
1397
|
# Server is still omitted though
|
|
1375
1398
|
self.none(resp.headers.get('Server'))
|
|
1399
|
+
|
|
1400
|
+
async def test_cortex_httpapi_pool(self):
|
|
1401
|
+
|
|
1402
|
+
# Test if we pass the mirror value in opts or not.
|
|
1403
|
+
async with self.getTestCore(conf={'https:headers': {'Key1': 'Valu1'}}) as core:
|
|
1404
|
+
await core.setUserPasswd(core.auth.rootuser.iden, 'root')
|
|
1405
|
+
addr, hport = await core.addHttpsPort(0)
|
|
1406
|
+
|
|
1407
|
+
q = '''$api = $lib.cortex.httpapi.add(stuff)
|
|
1408
|
+
$api.methods.get = ${
|
|
1409
|
+
$request.reply(200, headers=({"Weee": "valu"}) )
|
|
1410
|
+
}
|
|
1411
|
+
return ( ($api.iden) )'''
|
|
1412
|
+
iden00 = await core.callStorm(q)
|
|
1413
|
+
opts_iden00 = {'vars': {'iden': iden00}}
|
|
1414
|
+
|
|
1415
|
+
data = {}
|
|
1416
|
+
|
|
1417
|
+
oldstorm = core.storm
|
|
1418
|
+
async def storm(self, text, opts=None):
|
|
1419
|
+
data['opts'] = opts
|
|
1420
|
+
async for mesg in oldstorm(text, opts=opts):
|
|
1421
|
+
yield mesg
|
|
1422
|
+
|
|
1423
|
+
with mock.patch('synapse.cortex.Cortex.storm', new=storm) as patch:
|
|
1424
|
+
async with self.getHttpSess(auth=('root', 'root'), port=hport) as sess:
|
|
1425
|
+
resp = await sess.get(f'https://localhost:{hport}/api/ext/stuff') # type: aiohttp.ClientResponse
|
|
1426
|
+
self.eq(resp.status, 200)
|
|
1427
|
+
self.false(data['opts'].get('mirror'))
|
|
1428
|
+
data.clear()
|
|
1429
|
+
|
|
1430
|
+
q = '$api=$lib.cortex.httpapi.get($iden) $api.pool = (true) return ( $api.pack() ) '
|
|
1431
|
+
adef = await core.callStorm(q, opts=opts_iden00)
|
|
1432
|
+
self.true(adef.get('pool'))
|
|
1433
|
+
|
|
1434
|
+
resp = await sess.get(f'https://localhost:{hport}/api/ext/stuff') # type: aiohttp.ClientResponse
|
|
1435
|
+
self.eq(resp.status, 200)
|
|
1436
|
+
self.true(data['opts'].get('mirror'))
|
|
1437
|
+
data.clear()
|
|
1438
|
+
|
|
1439
|
+
q = '$api=$lib.cortex.httpapi.get($iden) $api.pool = (false) return ( $api.pack() ) '
|
|
1440
|
+
adef = await core.callStorm(q, opts=opts_iden00)
|
|
1441
|
+
self.false(adef.get('pool'))
|
|
1442
|
+
|
|
1443
|
+
resp = await sess.get(f'https://localhost:{hport}/api/ext/stuff') # type: aiohttp.ClientResponse
|
|
1444
|
+
self.eq(resp.status, 200)
|
|
1445
|
+
self.false(data['opts'].get('mirror'))
|
|
1446
|
+
data.clear()
|