synapse 2.152.0__py311-none-any.whl → 2.154.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 +19 -16
- synapse/cortex.py +203 -15
- synapse/exc.py +0 -2
- synapse/lib/ast.py +42 -23
- synapse/lib/autodoc.py +2 -2
- synapse/lib/cache.py +16 -1
- synapse/lib/cell.py +5 -5
- synapse/lib/httpapi.py +198 -2
- synapse/lib/layer.py +5 -2
- synapse/lib/modelrev.py +36 -3
- synapse/lib/node.py +2 -5
- synapse/lib/parser.py +1 -1
- synapse/lib/schemas.py +51 -0
- synapse/lib/snap.py +10 -0
- synapse/lib/storm.lark +24 -4
- synapse/lib/storm.py +98 -19
- synapse/lib/storm_format.py +1 -1
- synapse/lib/stormhttp.py +11 -4
- synapse/lib/stormlib/auth.py +16 -2
- synapse/lib/stormlib/backup.py +1 -0
- synapse/lib/stormlib/basex.py +2 -0
- synapse/lib/stormlib/cell.py +7 -0
- synapse/lib/stormlib/compression.py +3 -0
- synapse/lib/stormlib/cortex.py +1168 -0
- synapse/lib/stormlib/ethereum.py +1 -0
- synapse/lib/stormlib/graph.py +2 -0
- synapse/lib/stormlib/hashes.py +5 -0
- synapse/lib/stormlib/hex.py +6 -0
- synapse/lib/stormlib/infosec.py +6 -1
- synapse/lib/stormlib/ipv6.py +1 -0
- synapse/lib/stormlib/iters.py +58 -1
- synapse/lib/stormlib/json.py +5 -0
- synapse/lib/stormlib/mime.py +1 -0
- synapse/lib/stormlib/model.py +19 -3
- synapse/lib/stormlib/modelext.py +1 -0
- synapse/lib/stormlib/notifications.py +2 -0
- synapse/lib/stormlib/pack.py +2 -0
- synapse/lib/stormlib/random.py +1 -0
- synapse/lib/stormlib/smtp.py +0 -7
- synapse/lib/stormlib/stats.py +223 -0
- synapse/lib/stormlib/stix.py +8 -0
- synapse/lib/stormlib/storm.py +1 -0
- synapse/lib/stormlib/version.py +3 -0
- synapse/lib/stormlib/xml.py +3 -0
- synapse/lib/stormlib/yaml.py +2 -0
- synapse/lib/stormtypes.py +250 -170
- synapse/lib/trigger.py +180 -4
- synapse/lib/types.py +1 -1
- synapse/lib/version.py +2 -2
- synapse/lib/view.py +55 -6
- synapse/models/inet.py +21 -6
- synapse/models/orgs.py +48 -2
- synapse/models/risk.py +126 -2
- synapse/models/syn.py +6 -0
- synapse/tests/files/stormpkg/badapidef.yaml +13 -0
- synapse/tests/files/stormpkg/storm/modules/apimod +10 -0
- synapse/tests/files/stormpkg/testpkg.yaml +23 -0
- synapse/tests/test_axon.py +7 -2
- synapse/tests/test_cortex.py +231 -35
- synapse/tests/test_lib_ast.py +138 -43
- synapse/tests/test_lib_autodoc.py +1 -1
- synapse/tests/test_lib_modelrev.py +9 -0
- synapse/tests/test_lib_node.py +55 -0
- synapse/tests/test_lib_storm.py +14 -1
- synapse/tests/test_lib_stormhttp.py +65 -6
- synapse/tests/test_lib_stormlib_auth.py +12 -3
- synapse/tests/test_lib_stormlib_cortex.py +1327 -0
- synapse/tests/test_lib_stormlib_iters.py +116 -0
- synapse/tests/test_lib_stormlib_stats.py +187 -0
- synapse/tests/test_lib_stormlib_storm.py +8 -0
- synapse/tests/test_lib_stormsvc.py +24 -1
- synapse/tests/test_lib_stormtypes.py +124 -69
- synapse/tests/test_lib_trigger.py +315 -0
- synapse/tests/test_lib_view.py +1 -2
- synapse/tests/test_model_base.py +26 -0
- synapse/tests/test_model_inet.py +22 -0
- synapse/tests/test_model_orgs.py +28 -0
- synapse/tests/test_model_risk.py +73 -0
- synapse/tests/test_tools_autodoc.py +25 -0
- synapse/tests/test_tools_genpkg.py +9 -3
- synapse/tests/utils.py +39 -0
- synapse/tools/autodoc.py +42 -2
- {synapse-2.152.0.dist-info → synapse-2.154.0.dist-info}/METADATA +2 -2
- {synapse-2.152.0.dist-info → synapse-2.154.0.dist-info}/RECORD +87 -79
- {synapse-2.152.0.dist-info → synapse-2.154.0.dist-info}/WHEEL +1 -1
- {synapse-2.152.0.dist-info → synapse-2.154.0.dist-info}/LICENSE +0 -0
- {synapse-2.152.0.dist-info → synapse-2.154.0.dist-info}/top_level.txt +0 -0
synapse/tests/test_lib_ast.py
CHANGED
|
@@ -1,17 +1,13 @@
|
|
|
1
1
|
import json
|
|
2
2
|
import math
|
|
3
3
|
import asyncio
|
|
4
|
-
import contextlib
|
|
5
|
-
import collections
|
|
6
4
|
|
|
7
5
|
from unittest import mock
|
|
8
6
|
|
|
9
7
|
import synapse.exc as s_exc
|
|
10
8
|
import synapse.common as s_common
|
|
11
|
-
import synapse.cortex as s_cortex
|
|
12
9
|
|
|
13
10
|
import synapse.lib.ast as s_ast
|
|
14
|
-
import synapse.lib.base as s_base
|
|
15
11
|
import synapse.lib.snap as s_snap
|
|
16
12
|
|
|
17
13
|
import synapse.tests.utils as s_test
|
|
@@ -125,44 +121,6 @@ foo_stormpkg = {
|
|
|
125
121
|
],
|
|
126
122
|
}
|
|
127
123
|
|
|
128
|
-
@contextlib.asynccontextmanager
|
|
129
|
-
async def matchContexts(testself):
|
|
130
|
-
origenter = s_base.Base.__aenter__
|
|
131
|
-
origexit = s_base.Base.__aexit__
|
|
132
|
-
origstorm = s_cortex.Cortex.storm
|
|
133
|
-
orignodes = s_cortex.Cortex.nodes
|
|
134
|
-
|
|
135
|
-
contexts = collections.defaultdict(int)
|
|
136
|
-
|
|
137
|
-
async def enter(self):
|
|
138
|
-
contexts[type(self)] += 1
|
|
139
|
-
return await origenter(self)
|
|
140
|
-
|
|
141
|
-
async def exit(self, exc, cls, tb):
|
|
142
|
-
contexts[type(self)] -= 1
|
|
143
|
-
await origexit(self, exc, cls, tb)
|
|
144
|
-
|
|
145
|
-
async def storm(self, text, opts=None):
|
|
146
|
-
async for mesg in origstorm(self, text, opts=opts):
|
|
147
|
-
yield mesg
|
|
148
|
-
|
|
149
|
-
for cont, refs in contexts.items():
|
|
150
|
-
testself.eq(0, refs)
|
|
151
|
-
|
|
152
|
-
async def nodes(self, text, opts=None):
|
|
153
|
-
nodes = await orignodes(self, text, opts=opts)
|
|
154
|
-
|
|
155
|
-
for cont, refs in contexts.items():
|
|
156
|
-
testself.eq(0, refs)
|
|
157
|
-
|
|
158
|
-
return nodes
|
|
159
|
-
|
|
160
|
-
with mock.patch('synapse.lib.base.Base.__aenter__', enter):
|
|
161
|
-
with mock.patch('synapse.lib.base.Base.__aexit__', exit):
|
|
162
|
-
with mock.patch('synapse.cortex.Cortex.nodes', nodes):
|
|
163
|
-
with mock.patch('synapse.cortex.Cortex.storm', storm):
|
|
164
|
-
yield
|
|
165
|
-
|
|
166
124
|
class AstTest(s_test.SynTest):
|
|
167
125
|
|
|
168
126
|
async def test_mode_search(self):
|
|
@@ -2099,6 +2057,13 @@ class AstTest(s_test.SynTest):
|
|
|
2099
2057
|
else { $lib.print(no) }
|
|
2100
2058
|
'''
|
|
2101
2059
|
msgs = await core.stormlist(q)
|
|
2060
|
+
self.stormIsInPrint('yes', msgs)
|
|
2061
|
+
|
|
2062
|
+
q = '''test:str $data=$node.value()
|
|
2063
|
+
if ($data ~= "(?-i:brown)") { $lib.print(yes) }
|
|
2064
|
+
else { $lib.print(no) }
|
|
2065
|
+
'''
|
|
2066
|
+
msgs = await core.stormlist(q)
|
|
2102
2067
|
self.stormIsInPrint('no', msgs)
|
|
2103
2068
|
|
|
2104
2069
|
q = '''test:str $data=$node.value()
|
|
@@ -2320,7 +2285,7 @@ class AstTest(s_test.SynTest):
|
|
|
2320
2285
|
|
|
2321
2286
|
await core.nodes('[ inet:fqdn=vertex.link ]')
|
|
2322
2287
|
|
|
2323
|
-
async with matchContexts(self):
|
|
2288
|
+
async with s_test.matchContexts(self):
|
|
2324
2289
|
|
|
2325
2290
|
await core.nodes("inet:fqdn -> { inet:fqdn=vertex.link } | limit 1")
|
|
2326
2291
|
await core.nodes("function x() { inet:fqdn=vertex.link } yield $x() | limit 1")
|
|
@@ -2561,3 +2526,133 @@ class AstTest(s_test.SynTest):
|
|
|
2561
2526
|
self.len(0, nodes[0][1]['path']['edges'])
|
|
2562
2527
|
# one for the refs edge (via doedges) and one for the rule..
|
|
2563
2528
|
self.len(2, nodes[1][1]['path']['edges'])
|
|
2529
|
+
|
|
2530
|
+
async def test_ast_double_init_fini(self):
|
|
2531
|
+
async with self.getTestCore() as core:
|
|
2532
|
+
q = '''
|
|
2533
|
+
init {$foo = bar $lib.print(`{$foo} {$wow}`) }
|
|
2534
|
+
init {$baz = hehe $lib.print('second init!') }
|
|
2535
|
+
$lib.print($baz)
|
|
2536
|
+
'''
|
|
2537
|
+
msgs = await core.stormlist(q, opts={'vars': {'wow': 'hehe'}})
|
|
2538
|
+
pmesgs = [m[1].get('mesg') for m in msgs if m[0] == 'print']
|
|
2539
|
+
self.eq(pmesgs, ['bar hehe', 'second init!', 'hehe'])
|
|
2540
|
+
|
|
2541
|
+
q = '''
|
|
2542
|
+
init {$foo = bar $lib.print(`{$foo} {$wow}`) }
|
|
2543
|
+
init {$baz = hehe $lib.print('second init!') }
|
|
2544
|
+
$lib.print($baz)
|
|
2545
|
+
[test:str=stuff]
|
|
2546
|
+
$stuff = $node.value()
|
|
2547
|
+
fini { $lib.print(fini1) }
|
|
2548
|
+
fini { $lib.print(`fini {$stuff}`) }
|
|
2549
|
+
'''
|
|
2550
|
+
msgs = await core.stormlist(q, opts={'vars': {'wow': 'hehe', 'stuff': None}})
|
|
2551
|
+
pmesgs = [m[1].get('mesg') for m in msgs if m[0] == 'print']
|
|
2552
|
+
self.eq(pmesgs, ['bar hehe', 'second init!', 'hehe', 'fini1', 'fini stuff'])
|
|
2553
|
+
|
|
2554
|
+
q = '''
|
|
2555
|
+
init { $foo = bar }
|
|
2556
|
+
init { $baz = $lib.str.format('foo={foo}', foo=$foo) }
|
|
2557
|
+
$lib.print($baz)
|
|
2558
|
+
'''
|
|
2559
|
+
msgs = await core.stormlist(q)
|
|
2560
|
+
self.stormIsInPrint('foo=bar', msgs)
|
|
2561
|
+
|
|
2562
|
+
async def test_ast_tagfilters(self):
|
|
2563
|
+
|
|
2564
|
+
async with self.getTestCore() as core:
|
|
2565
|
+
|
|
2566
|
+
await core.addTagProp('score', ('int', {}), {})
|
|
2567
|
+
|
|
2568
|
+
await core.nodes('[ test:str=foo +#tagaa=2023 +#tagaa:score=5 <(foo)+ { test:str=foo } ]')
|
|
2569
|
+
await core.nodes('[ test:str=bar +#tagab=2024 +#tagab:score=6 ]')
|
|
2570
|
+
await core.nodes('[ test:str=baz +#tagba=2023 +#tagba:score=7 ]')
|
|
2571
|
+
await core.nodes('[ test:str=faz +#tagbb=2024 +#tagbb:score=8 ]')
|
|
2572
|
+
|
|
2573
|
+
self.len(2, await core.nodes('test:str +#taga*'))
|
|
2574
|
+
self.len(1, await core.nodes('test:str +#tagaa=2023'))
|
|
2575
|
+
self.len(1, await core.nodes('test:str +#taga* <(*)- *'))
|
|
2576
|
+
self.len(2, await core.nodes('$tag=taga* test:str +#$tag'))
|
|
2577
|
+
self.len(1, await core.nodes('$tag=tagaa test:str +#$tag=2023'))
|
|
2578
|
+
|
|
2579
|
+
with self.raises(s_exc.BadSyntax):
|
|
2580
|
+
await core.nodes('test:str +#taga*=2023')
|
|
2581
|
+
|
|
2582
|
+
with self.raises(s_exc.BadSyntax):
|
|
2583
|
+
await core.nodes('test:str +#taga*@=2023')
|
|
2584
|
+
|
|
2585
|
+
with self.raises(s_exc.BadSyntax):
|
|
2586
|
+
await core.nodes('test:str +#taga*>2023')
|
|
2587
|
+
|
|
2588
|
+
with self.raises(s_exc.BadSyntax):
|
|
2589
|
+
await core.nodes('test:str +#taga*<(3+5)')
|
|
2590
|
+
|
|
2591
|
+
with self.raises(s_exc.NoSuchCmpr):
|
|
2592
|
+
await core.nodes('test:str +#taga<(3+5)')
|
|
2593
|
+
|
|
2594
|
+
with self.raises(s_exc.NoSuchCmpr):
|
|
2595
|
+
await core.nodes('test:str +#taga*min>=2023')
|
|
2596
|
+
|
|
2597
|
+
with self.raises(s_exc.StormRuntimeError):
|
|
2598
|
+
await core.nodes('$tag=taga* test:str +#$tag=2023')
|
|
2599
|
+
|
|
2600
|
+
with self.raises(s_exc.StormRuntimeError):
|
|
2601
|
+
await core.nodes('$tag=taga* test:str +#$"tag"=2023')
|
|
2602
|
+
|
|
2603
|
+
with self.raises(s_exc.StormRuntimeError):
|
|
2604
|
+
await core.nodes('$tag=taga* test:str +#foo.$"tag"=2023')
|
|
2605
|
+
|
|
2606
|
+
with self.raises(s_exc.BadSyntax):
|
|
2607
|
+
await core.nodes('$tag=taga* test:str +#foo*.$"tag"=2023')
|
|
2608
|
+
|
|
2609
|
+
with self.raises(s_exc.BadSyntax):
|
|
2610
|
+
await core.nodes('$tag=taga test:str +#foo.$"tag".*=2023')
|
|
2611
|
+
|
|
2612
|
+
with self.raises(s_exc.BadSyntax):
|
|
2613
|
+
await core.nodes('$tag=taga test:str +#foo.$"tag".*=2023')
|
|
2614
|
+
|
|
2615
|
+
with self.raises(s_exc.BadSyntax):
|
|
2616
|
+
await core.nodes('$tag=taga test:str +#foo.$"tag".$"tag".*=2023')
|
|
2617
|
+
|
|
2618
|
+
self.len(2, await core.nodes('test:str +#taga*:score'))
|
|
2619
|
+
self.len(1, await core.nodes('test:str +#tagaa:score=5'))
|
|
2620
|
+
self.len(1, await core.nodes('test:str +#tagaa:score<(2+4)'))
|
|
2621
|
+
self.len(1, await core.nodes('test:str +#tagaa:score*range=(4,6)'))
|
|
2622
|
+
self.len(1, await core.nodes('test:str +#taga*:score <(*)- *'))
|
|
2623
|
+
self.len(2, await core.nodes('$tag=taga* test:str +#$tag:score'))
|
|
2624
|
+
self.len(1, await core.nodes('$tag=tagaa test:str +#$tag:score=5'))
|
|
2625
|
+
self.len(1, await core.nodes('$tag=tagaa test:str +#$tag:score*range=(4,6)'))
|
|
2626
|
+
|
|
2627
|
+
with self.raises(s_exc.BadSyntax):
|
|
2628
|
+
await core.nodes('test:str +#taga*:score=2023')
|
|
2629
|
+
|
|
2630
|
+
with self.raises(s_exc.BadSyntax):
|
|
2631
|
+
await core.nodes('test:str +#taga*:score@=2023')
|
|
2632
|
+
|
|
2633
|
+
with self.raises(s_exc.BadSyntax):
|
|
2634
|
+
await core.nodes('test:str +#taga*:score>2023')
|
|
2635
|
+
|
|
2636
|
+
with self.raises(s_exc.BadSyntax):
|
|
2637
|
+
await core.nodes('test:str +#taga*:score<(3+5)')
|
|
2638
|
+
|
|
2639
|
+
with self.raises(s_exc.BadSyntax):
|
|
2640
|
+
await core.nodes('test:str +#taga*:score*min>=2023')
|
|
2641
|
+
|
|
2642
|
+
with self.raises(s_exc.NoSuchCmpr):
|
|
2643
|
+
await core.nodes('test:str +#taga:score*min>=2023')
|
|
2644
|
+
|
|
2645
|
+
with self.raises(s_exc.StormRuntimeError):
|
|
2646
|
+
await core.nodes('$tag=taga* test:str +#$tag:score=2023')
|
|
2647
|
+
|
|
2648
|
+
with self.raises(s_exc.StormRuntimeError):
|
|
2649
|
+
await core.nodes('$tag=taga* test:str +#foo.$"tag":score=2023')
|
|
2650
|
+
|
|
2651
|
+
with self.raises(s_exc.BadSyntax):
|
|
2652
|
+
await core.nodes('$tag=taga* test:str +#foo*.$"tag":score=2023')
|
|
2653
|
+
|
|
2654
|
+
with self.raises(s_exc.BadSyntax):
|
|
2655
|
+
await core.nodes('$tag=taga test:str +#foo.$"tag".*:score=2023')
|
|
2656
|
+
|
|
2657
|
+
with self.raises(s_exc.BadSyntax):
|
|
2658
|
+
await core.nodes('$tag=taga test:str +#foo.$"tag".$"tag".*:score=2023')
|
|
@@ -62,7 +62,7 @@ shave'''
|
|
|
62
62
|
self.eq(s_autodoc.getArgLines({}), [])
|
|
63
63
|
lines = s_autodoc.getArgLines(rtype)
|
|
64
64
|
self.eq(lines, ['\n', 'Args:', ' foo (str): The foos!', '\n',
|
|
65
|
-
' bar: The bar. The input type may
|
|
65
|
+
' bar: The bar. The input type may be one of the following: ``str``, ``int``.',
|
|
66
66
|
'\n', ' \\*\\*kwargs (any): Extra foobars.', '\n'])
|
|
67
67
|
|
|
68
68
|
lines = s_autodoc.getArgLines({'args': [{'name': 'cmplx', 'type': {}, 'desc': 'unsupported'}]})
|
|
@@ -419,3 +419,12 @@ class ModelRevTest(s_tests.SynTest):
|
|
|
419
419
|
|
|
420
420
|
self.len(1, await core.nodes('risk:vulnname="woot woot"'))
|
|
421
421
|
self.len(1, await core.nodes('risk:vuln:name="woot woot"'))
|
|
422
|
+
|
|
423
|
+
async def test_modelrev_0_2_22(self):
|
|
424
|
+
|
|
425
|
+
async with self.getRegrCore('model-0.2.22') as core:
|
|
426
|
+
nodes = await core.nodes('inet:ipv4=100.64.0.0/10')
|
|
427
|
+
self.len(257, nodes)
|
|
428
|
+
|
|
429
|
+
for node in nodes:
|
|
430
|
+
self.eq(node.props.get('type'), 'shared')
|
synapse/tests/test_lib_node.py
CHANGED
|
@@ -517,3 +517,58 @@ class NodeTest(s_t_utils.SynTest):
|
|
|
517
517
|
|
|
518
518
|
msgs = await core.stormlist(edgeq)
|
|
519
519
|
self.len(1, [m for m in msgs if m[0] == 'print'])
|
|
520
|
+
|
|
521
|
+
async def test_node_remove_missing_basetag(self):
|
|
522
|
+
|
|
523
|
+
async with self.getTestCore() as core:
|
|
524
|
+
|
|
525
|
+
base = await core.callStorm('return($lib.view.get().iden)')
|
|
526
|
+
fork = await core.callStorm('return($lib.view.get().fork().iden)')
|
|
527
|
+
|
|
528
|
+
await core.nodes('[test:str=neato +#foo.one]', opts={'view': base})
|
|
529
|
+
await core.nodes('test:str=neato | [ +#foo.two ]', opts={'view': fork})
|
|
530
|
+
|
|
531
|
+
await core.nodes('test:str=neato | [ -#foo ]', opts={'view': base})
|
|
532
|
+
|
|
533
|
+
othr = await core.nodes('test:str=neato', opts={'view': fork})
|
|
534
|
+
self.len(1, othr)
|
|
535
|
+
self.isin('foo.two', othr[0].tags)
|
|
536
|
+
self.notin('foo', othr[0].tags)
|
|
537
|
+
|
|
538
|
+
msgs = await core.stormlist('test:str=neato | [ -#foo ]', opts={'view': fork})
|
|
539
|
+
edits = [m[1] for m in msgs if m[0] == 'node:edits']
|
|
540
|
+
nodes = [m[1] for m in msgs if m[0] == 'node']
|
|
541
|
+
self.len(1, edits)
|
|
542
|
+
self.len(1, edits[0]['edits'][0][2])
|
|
543
|
+
|
|
544
|
+
self.len(1, nodes)
|
|
545
|
+
self.len(0, nodes[0][1]['tags'])
|
|
546
|
+
|
|
547
|
+
await core.nodes('[test:int=12 +#ping.pong.neato.burrito]', opts={'view': base})
|
|
548
|
+
await core.nodes('test:int=12 | [ +#ping.pong.awesome.possum ]', opts={'view': fork})
|
|
549
|
+
|
|
550
|
+
await core.nodes('test:int=12 | [ -#ping.pong]', opts={'view': base})
|
|
551
|
+
|
|
552
|
+
othr = await core.nodes('test:int=12', opts={'view': fork})
|
|
553
|
+
self.len(1, othr)
|
|
554
|
+
self.isin('ping', othr[0].tags)
|
|
555
|
+
self.isin('ping.pong.awesome', othr[0].tags)
|
|
556
|
+
self.isin('ping.pong.awesome.possum', othr[0].tags)
|
|
557
|
+
|
|
558
|
+
self.notin('ping.pong', othr[0].tags)
|
|
559
|
+
|
|
560
|
+
msgs = await core.stormlist('test:int=12 | [ -#ping.pong ]', opts={'view': fork})
|
|
561
|
+
edits = [m[1] for m in msgs if m[0] == 'node:edits']
|
|
562
|
+
nodes = [m[1] for m in msgs if m[0] == 'node']
|
|
563
|
+
|
|
564
|
+
self.len(1, edits)
|
|
565
|
+
self.len(2, edits[0]['edits'][0][2])
|
|
566
|
+
|
|
567
|
+
self.len(1, nodes)
|
|
568
|
+
self.len(1, nodes[0][1]['tags'])
|
|
569
|
+
self.isin('ping', nodes[0][1]['tags'])
|
|
570
|
+
|
|
571
|
+
nodes = await core.nodes('test:int=12 | [ -#p ]')
|
|
572
|
+
self.len(1, nodes)
|
|
573
|
+
self.len(1, nodes[0].tags)
|
|
574
|
+
self.isin('ping', nodes[0].tags)
|
synapse/tests/test_lib_storm.py
CHANGED
|
@@ -1213,6 +1213,19 @@ class StormTest(s_t_utils.SynTest):
|
|
|
1213
1213
|
self.len(1, nodes)
|
|
1214
1214
|
self.eq(nodes[0].ndef, ('test:str', 'pluto\udcbaneptune'))
|
|
1215
1215
|
|
|
1216
|
+
nodes = await core.nodes('[ media:news=* :publisher:name=woot ] $name=:publisher:name [ :publisher={ gen.ou.org $name } ]')
|
|
1217
|
+
self.len(1, nodes)
|
|
1218
|
+
self.nn(nodes[0].get('publisher'))
|
|
1219
|
+
|
|
1220
|
+
# test regular expressions are case insensitive by default
|
|
1221
|
+
self.len(1, await core.nodes('test:str~=Pluto'))
|
|
1222
|
+
self.len(1, await core.nodes('test:str +test:str~=Pluto'))
|
|
1223
|
+
self.true(await core.callStorm('return(("Foo" ~= "foo"))'))
|
|
1224
|
+
self.len(0, await core.nodes('test:str~="(?-i:Pluto)"'))
|
|
1225
|
+
self.len(0, await core.nodes('test:str +test:str~="(?-i:Pluto)"'))
|
|
1226
|
+
self.false(await core.callStorm('return(("Foo" ~= "(?-i:foo)"))'))
|
|
1227
|
+
self.true(await core.callStorm('return(("Foo" ~= "(?-i:Foo)"))'))
|
|
1228
|
+
|
|
1216
1229
|
async def test_storm_diff_merge(self):
|
|
1217
1230
|
|
|
1218
1231
|
async with self.getTestCore() as core:
|
|
@@ -3641,7 +3654,7 @@ class StormTest(s_t_utils.SynTest):
|
|
|
3641
3654
|
msgs = await core.stormlist('help list')
|
|
3642
3655
|
self.stormIsInPrint('***\nlist\n****\nImplements the Storm API for a List instance.', msgs)
|
|
3643
3656
|
self.stormIsInPrint('append(valu)\nAppend a value to the list.', msgs)
|
|
3644
|
-
self.stormIsInPrint('auth.user.list
|
|
3657
|
+
self.stormIsInPrint('auth.user.list : List all users.', msgs)
|
|
3645
3658
|
|
|
3646
3659
|
# email stor / gettr has a multi value return type
|
|
3647
3660
|
msgs = await core.stormlist('help -v auth:user')
|
|
@@ -509,13 +509,15 @@ class StormHttpTest(s_test.SynTest):
|
|
|
509
509
|
await visi.addRule((True, ('storm', 'lib', 'axon', 'wget')))
|
|
510
510
|
await visi.addRule((True, ('storm', 'lib', 'axon', 'wput')))
|
|
511
511
|
|
|
512
|
+
errmsg = f'User {visi.name!r} ({visi.iden}) must have permission {{perm}}'
|
|
513
|
+
|
|
512
514
|
asvisi = {'user': visi.iden}
|
|
513
515
|
msgs = await core.stormlist('$lib.inet.http.get(http://vertex.link, proxy=$lib.false)', opts=asvisi)
|
|
514
|
-
self.stormIsInErr(
|
|
516
|
+
self.stormIsInErr(errmsg.format(perm='storm.lib.inet.http.proxy'), msgs)
|
|
515
517
|
|
|
516
518
|
asvisi = {'user': visi.iden}
|
|
517
519
|
msgs = await core.stormlist('$lib.inet.http.get(http://vertex.link, proxy=socks5://user:pass@127.0.0.1:1)', opts=asvisi)
|
|
518
|
-
self.stormIsInErr(
|
|
520
|
+
self.stormIsInErr(errmsg.format(perm='storm.lib.inet.http.proxy'), msgs)
|
|
519
521
|
|
|
520
522
|
resp = await core.callStorm('return($lib.inet.http.get(http://vertex.link, proxy=socks5://user:pass@127.0.0.1:1))')
|
|
521
523
|
self.eq('ProxyConnectionError', resp['err'][0])
|
|
@@ -523,15 +525,15 @@ class StormHttpTest(s_test.SynTest):
|
|
|
523
525
|
# test $lib.axon proxy API
|
|
524
526
|
asvisi = {'user': visi.iden}
|
|
525
527
|
msgs = await core.stormlist('$lib.axon.wget(http://vertex.link, proxy=$lib.false)', opts=asvisi)
|
|
526
|
-
self.stormIsInErr(
|
|
528
|
+
self.stormIsInErr(errmsg.format(perm='storm.lib.inet.http.proxy'), msgs)
|
|
527
529
|
|
|
528
530
|
asvisi = {'user': visi.iden}
|
|
529
531
|
msgs = await core.stormlist('$lib.axon.wget(http://vertex.link, proxy=socks5://user:pass@127.0.0.1:1)', opts=asvisi)
|
|
530
|
-
self.stormIsInErr(
|
|
532
|
+
self.stormIsInErr(errmsg.format(perm='storm.lib.inet.http.proxy'), msgs)
|
|
531
533
|
|
|
532
534
|
asvisi = {'user': visi.iden}
|
|
533
535
|
msgs = await core.stormlist('$lib.axon.wput(asdf, http://vertex.link, proxy=socks5://user:pass@127.0.0.1:1)', opts=asvisi)
|
|
534
|
-
self.stormIsInErr(
|
|
536
|
+
self.stormIsInErr(errmsg.format(perm='storm.lib.inet.http.proxy'), msgs)
|
|
535
537
|
|
|
536
538
|
resp = await core.callStorm('return($lib.axon.wget(http://vertex.link, proxy=socks5://user:pass@127.0.0.1:1))')
|
|
537
539
|
self.false(resp.get('ok'))
|
|
@@ -544,6 +546,63 @@ class StormHttpTest(s_test.SynTest):
|
|
|
544
546
|
self.false(resp.get('ok'))
|
|
545
547
|
self.isin('connect to proxy 127.0.0.1:1', resp['mesg'])
|
|
546
548
|
|
|
549
|
+
async with self.getTestCore(conf=conf) as core:
|
|
550
|
+
# Proxy permission tests in this section
|
|
551
|
+
|
|
552
|
+
visi = await core.auth.addUser('visi')
|
|
553
|
+
|
|
554
|
+
await visi.addRule((True, ('storm', 'lib', 'axon', 'wget')))
|
|
555
|
+
await visi.addRule((True, ('storm', 'lib', 'axon', 'wput')))
|
|
556
|
+
|
|
557
|
+
_, sha256 = await core.axon.put(b'asdf')
|
|
558
|
+
sha256 = s_common.ehex(sha256)
|
|
559
|
+
|
|
560
|
+
host, port = await core.addHttpsPort(0)
|
|
561
|
+
|
|
562
|
+
q1 = f'return($lib.inet.http.get(https://loop.vertex.link:{port}, ssl_verify=$lib.false, proxy=$proxy))'
|
|
563
|
+
q2 = f'return($lib.axon.wget(https://loop.vertex.link:{port}, ssl=$lib.false, proxy=$proxy))'
|
|
564
|
+
q3 = f'return($lib.axon.wput({sha256}, https://loop.vertex.link:{port}, ssl=$lib.false, proxy=$proxy))'
|
|
565
|
+
|
|
566
|
+
for proxy in ('socks5://user:pass@127.0.0.1:1', False):
|
|
567
|
+
opts = {'vars': {'proxy': proxy}, 'user': visi.iden}
|
|
568
|
+
|
|
569
|
+
with self.raises(s_exc.AuthDeny):
|
|
570
|
+
await core.callStorm(q1, opts=opts)
|
|
571
|
+
|
|
572
|
+
with self.raises(s_exc.AuthDeny):
|
|
573
|
+
await core.callStorm(q2, opts=opts)
|
|
574
|
+
|
|
575
|
+
with self.raises(s_exc.AuthDeny):
|
|
576
|
+
await core.callStorm(q3, opts=opts)
|
|
577
|
+
|
|
578
|
+
# Add permissions to use a proxy
|
|
579
|
+
await visi.addRule((True, ('storm', 'lib', 'inet', 'http', 'proxy')))
|
|
580
|
+
|
|
581
|
+
opts = {'vars': {'proxy': 'socks5://user:pass@127.0.0.1:1'}, 'user': visi.iden}
|
|
582
|
+
|
|
583
|
+
resp = await core.callStorm(q1, opts=opts)
|
|
584
|
+
self.eq('ProxyConnectionError', resp['err'][0])
|
|
585
|
+
|
|
586
|
+
resp = await core.callStorm(q2, opts=opts)
|
|
587
|
+
self.eq('ProxyConnectionError', resp['err'][0])
|
|
588
|
+
|
|
589
|
+
resp = await core.callStorm(q3, opts=opts)
|
|
590
|
+
self.eq('ProxyConnectionError', resp['err'][0])
|
|
591
|
+
|
|
592
|
+
opts = {'vars': {'proxy': False}, 'user': visi.iden}
|
|
593
|
+
|
|
594
|
+
resp = await core.callStorm(q1, opts=opts)
|
|
595
|
+
self.eq(resp['code'], 404)
|
|
596
|
+
self.eq(resp['reason'], 'Not Found')
|
|
597
|
+
|
|
598
|
+
resp = await core.callStorm(q2, opts=opts)
|
|
599
|
+
self.eq(resp['code'], 404)
|
|
600
|
+
self.eq(resp['reason'], 'Not Found')
|
|
601
|
+
|
|
602
|
+
resp = await core.callStorm(q3, opts=opts)
|
|
603
|
+
self.eq(resp['code'], 404)
|
|
604
|
+
self.eq(resp['reason'], 'Not Found')
|
|
605
|
+
|
|
547
606
|
async def test_storm_http_connect(self):
|
|
548
607
|
|
|
549
608
|
async with self.getTestCore() as core:
|
|
@@ -604,7 +663,7 @@ class StormHttpTest(s_test.SynTest):
|
|
|
604
663
|
opts = {'user': visi.iden, 'vars': {'port': port, 'proxy': False}}
|
|
605
664
|
with self.raises(s_exc.AuthDeny) as cm:
|
|
606
665
|
await core.callStorm(query, opts=opts)
|
|
607
|
-
self.eq(cm.exception.get('mesg'),
|
|
666
|
+
self.eq(cm.exception.get('mesg'), f'User {visi.name!r} ({visi.iden}) must have permission storm.lib.inet.http.proxy')
|
|
608
667
|
|
|
609
668
|
await visi.setAdmin(True)
|
|
610
669
|
|
|
@@ -178,12 +178,21 @@ class StormLibAuthTest(s_test.SynTest):
|
|
|
178
178
|
self.stormIsInPrint('allowed: true - Matched user rule (node) on gate 741529fa80e3fb42f63c5320e4bf348f.',
|
|
179
179
|
msgs, deguid=True)
|
|
180
180
|
|
|
181
|
-
|
|
182
|
-
|
|
181
|
+
msgs = await core.stormlist('auth.user.mod visi --gate $lib.view.get().layers.0.iden')
|
|
182
|
+
self.stormIsInWarn('Granting/revoking admin status on an auth gate, requires the use of `--admin <true|false>` also.', msgs)
|
|
183
|
+
|
|
184
|
+
msgs = await core.stormlist('auth.user.mod visi --admin $lib.true --gate $lib.view.get().layers.0.iden')
|
|
185
|
+
self.stormIsInPrint('User (visi) admin status set to true for auth gate 741529fa80e3fb42f63c5320e4bf348f.',
|
|
186
|
+
msgs, deguid=True)
|
|
183
187
|
msgs = await core.stormlist('auth.user.allowed visi node.tag.del --gate $lib.view.get().layers.0.iden')
|
|
184
188
|
self.stormIsInPrint('allowed: true - The user is an admin of auth gate 741529fa80e3fb42f63c5320e4bf348f',
|
|
185
189
|
msgs, deguid=True)
|
|
186
|
-
await core.
|
|
190
|
+
msgs = await core.stormlist('auth.user.mod visi --admin $lib.false --gate $lib.view.get().layers.0.iden')
|
|
191
|
+
self.stormIsInPrint('User (visi) admin status set to false for auth gate 741529fa80e3fb42f63c5320e4bf348f.',
|
|
192
|
+
msgs, deguid=True)
|
|
193
|
+
msgs = await core.stormlist('auth.user.allowed visi node.tag.del --gate $lib.view.get().layers.0.iden')
|
|
194
|
+
self.stormIsInPrint('allowed: true - Matched user rule (node) on gate 741529fa80e3fb42f63c5320e4bf348f',
|
|
195
|
+
msgs, deguid=True)
|
|
187
196
|
|
|
188
197
|
await core.nodes('auth.role.addrule ninjas beep.sys --gate $lib.view.get().layers.0.iden')
|
|
189
198
|
msgs = await core.stormlist('auth.user.allowed visi beep.sys --gate $lib.view.get().layers.0.iden')
|