synapse 2.161.0__py311-none-any.whl → 2.163.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 +48 -40
- synapse/cortex.py +4 -0
- synapse/daemon.py +7 -2
- synapse/lib/cell.py +70 -3
- synapse/lib/layer.py +20 -1
- synapse/lib/oauth.py +1 -7
- synapse/lib/rstorm.py +16 -0
- synapse/lib/schemas.py +10 -0
- synapse/lib/storm.py +17 -1
- synapse/lib/stormhttp.py +52 -28
- synapse/lib/stormlib/stix.py +6 -3
- synapse/lib/stormtypes.py +336 -26
- synapse/lib/version.py +2 -2
- synapse/lib/view.py +15 -2
- synapse/models/inet.py +9 -0
- synapse/models/infotech.py +28 -26
- synapse/models/orgs.py +3 -0
- synapse/models/proj.py +9 -2
- synapse/models/risk.py +32 -0
- synapse/telepath.py +2 -0
- synapse/tests/files/rstorm/testsvc.py +8 -1
- synapse/tests/files/stormpkg/testpkg.yaml +4 -0
- synapse/tests/test_axon.py +4 -4
- synapse/tests/test_cortex.py +8 -8
- synapse/tests/test_daemon.py +19 -0
- synapse/tests/test_lib_ast.py +17 -17
- synapse/tests/test_lib_grammar.py +4 -4
- synapse/tests/test_lib_rstorm.py +38 -2
- synapse/tests/test_lib_storm.py +15 -15
- synapse/tests/test_lib_stormhttp.py +182 -19
- synapse/tests/test_lib_stormlib_auth.py +3 -3
- synapse/tests/test_lib_stormlib_cell.py +1 -1
- synapse/tests/test_lib_stormlib_cortex.py +50 -2
- synapse/tests/test_lib_stormlib_json.py +2 -2
- synapse/tests/test_lib_stormlib_macro.py +1 -1
- synapse/tests/test_lib_stormlib_modelext.py +37 -37
- synapse/tests/test_lib_stormlib_oauth.py +20 -20
- synapse/tests/test_lib_stormlib_stix.py +3 -1
- synapse/tests/test_lib_stormtypes.py +159 -52
- synapse/tests/test_lib_stormwhois.py +1 -1
- synapse/tests/test_lib_trigger.py +11 -11
- synapse/tests/test_lib_view.py +23 -1
- synapse/tests/test_model_crypto.py +1 -1
- synapse/tests/test_model_inet.py +6 -0
- synapse/tests/test_model_orgs.py +2 -1
- synapse/tests/test_model_proj.py +6 -0
- synapse/tests/test_model_risk.py +10 -0
- synapse/tests/test_tools_storm.py +1 -1
- {synapse-2.161.0.dist-info → synapse-2.163.0.dist-info}/METADATA +3 -1
- {synapse-2.161.0.dist-info → synapse-2.163.0.dist-info}/RECORD +53 -53
- {synapse-2.161.0.dist-info → synapse-2.163.0.dist-info}/LICENSE +0 -0
- {synapse-2.161.0.dist-info → synapse-2.163.0.dist-info}/WHEEL +0 -0
- {synapse-2.161.0.dist-info → synapse-2.163.0.dist-info}/top_level.txt +0 -0
|
@@ -139,7 +139,7 @@ class StormTypesTest(s_test.SynTest):
|
|
|
139
139
|
''')
|
|
140
140
|
self.stormNotInPrint(f'{visi.iden} says heya', msgs)
|
|
141
141
|
|
|
142
|
-
indx = await core.callStorm('return($lib.auth.users.byname(root).notify(hehe,
|
|
142
|
+
indx = await core.callStorm('return($lib.auth.users.byname(root).notify(hehe, ({"haha": "hoho"})))')
|
|
143
143
|
opts = {'vars': {'indx': indx}}
|
|
144
144
|
mesg = await core.callStorm('return($lib.notifications.get($indx))', opts=opts)
|
|
145
145
|
self.eq(mesg[0], core.auth.rootuser.iden)
|
|
@@ -147,11 +147,11 @@ class StormTypesTest(s_test.SynTest):
|
|
|
147
147
|
self.eq(mesg[3], {'haha': 'hoho'})
|
|
148
148
|
|
|
149
149
|
opts = {'user': visi.iden}
|
|
150
|
-
q = 'return($lib.auth.users.byname(root).notify(newp,
|
|
150
|
+
q = 'return($lib.auth.users.byname(root).notify(newp, ({"key": "valu"})))'
|
|
151
151
|
with self.raises(s_exc.AuthDeny):
|
|
152
152
|
await core.callStorm(q, opts=opts)
|
|
153
153
|
|
|
154
|
-
q = 'return($lib.auth.users.byname(root).notify(newp,
|
|
154
|
+
q = 'return($lib.auth.users.byname(root).notify(newp, ({"key": "valu"})))'
|
|
155
155
|
with self.raises(s_exc.AuthDeny):
|
|
156
156
|
await core.callStorm(q, opts=opts)
|
|
157
157
|
|
|
@@ -189,8 +189,8 @@ class StormTypesTest(s_test.SynTest):
|
|
|
189
189
|
self.none(await core.callStorm('return($lib.jsonstor.get(foo))'))
|
|
190
190
|
self.false(await core.callStorm('return($lib.jsonstor.has(foo))'))
|
|
191
191
|
self.none(await core.callStorm('return($lib.jsonstor.get(foo, prop=bar))'))
|
|
192
|
-
self.true(await core.callStorm('return($lib.jsonstor.set(hi,
|
|
193
|
-
self.true(await core.callStorm('return($lib.jsonstor.set(bye/bye,
|
|
192
|
+
self.true(await core.callStorm('return($lib.jsonstor.set(hi, ({"foo": "bar", "baz": "faz"})))'))
|
|
193
|
+
self.true(await core.callStorm('return($lib.jsonstor.set(bye/bye, ({"zip": "zop", "bip": "bop"})))'))
|
|
194
194
|
self.true(await core.callStorm('return($lib.jsonstor.has(bye/bye))'))
|
|
195
195
|
self.eq('bar', await core.callStorm('return($lib.jsonstor.get(hi, prop=foo))'))
|
|
196
196
|
self.eq({'foo': 'bar', 'baz': 'faz'}, await core.callStorm('return($lib.jsonstor.get(hi))'))
|
|
@@ -587,6 +587,15 @@ class StormTypesTest(s_test.SynTest):
|
|
|
587
587
|
self.true(s_common.isguid(nodes[1].ndef[1]))
|
|
588
588
|
self.eq(nodes[0].ndef[1], nodes[1].ndef[1])
|
|
589
589
|
|
|
590
|
+
self.ne(s_common.guid('foo'), await core.callStorm('return($lib.guid(foo))'))
|
|
591
|
+
self.eq(s_common.guid('foo'), await core.callStorm('return($lib.guid(valu=foo))'))
|
|
592
|
+
|
|
593
|
+
with self.raises(s_exc.BadArg) as ectx:
|
|
594
|
+
await core.callStorm('return($lib.guid(foo, valu=bar))')
|
|
595
|
+
self.eq('Valu cannot be specified if positional arguments are provided', ectx.exception.errinfo['mesg'])
|
|
596
|
+
|
|
597
|
+
await self.asyncraises(s_exc.NoSuchType, core.callStorm('return($lib.guid(valu=$lib))'))
|
|
598
|
+
|
|
590
599
|
async with core.getLocalProxy() as prox:
|
|
591
600
|
mesgs = [m async for m in prox.storm('$lib.print("hi there")') if m[0] == 'print']
|
|
592
601
|
self.len(1, mesgs)
|
|
@@ -680,12 +689,12 @@ class StormTypesTest(s_test.SynTest):
|
|
|
680
689
|
self.stormIsInPrint("'2'", mesgs)
|
|
681
690
|
self.stormIsInPrint("'3'", mesgs)
|
|
682
691
|
|
|
683
|
-
mesgs = await core.stormlist('$lib.print(
|
|
692
|
+
mesgs = await core.stormlist('$lib.print(({"foo": "1", "bar": "2"}))')
|
|
684
693
|
self.stormIsInPrint("'foo': '1'", mesgs)
|
|
685
694
|
self.stormIsInPrint("'bar': '2'", mesgs)
|
|
686
695
|
|
|
687
696
|
mesgs = await core.stormlist('$lib.print($lib.dict)')
|
|
688
|
-
self.stormIsInPrint("
|
|
697
|
+
self.stormIsInPrint("Library $lib.dict", mesgs)
|
|
689
698
|
|
|
690
699
|
mesgs = await core.stormlist('$lib.print($lib)')
|
|
691
700
|
self.stormIsInPrint("Library $lib", mesgs)
|
|
@@ -696,13 +705,10 @@ class StormTypesTest(s_test.SynTest):
|
|
|
696
705
|
mesgs = await core.stormlist('$lib.pprint($lib.list(1,2,3))')
|
|
697
706
|
self.stormIsInPrint("('1', '2', '3')", mesgs)
|
|
698
707
|
|
|
699
|
-
mesgs = await core.stormlist('$lib.pprint(
|
|
708
|
+
mesgs = await core.stormlist('$lib.pprint(({"foo": "1", "bar": "2"}))')
|
|
700
709
|
self.stormIsInPrint("'foo': '1'", mesgs)
|
|
701
710
|
self.stormIsInPrint("'bar': '2'", mesgs)
|
|
702
711
|
|
|
703
|
-
mesgs = await core.stormlist('$lib.pprint($lib.dict)')
|
|
704
|
-
self.stormIsInPrint("bound method LibBase._dict", mesgs)
|
|
705
|
-
|
|
706
712
|
mesgs = await core.stormlist('$lib.pprint($lib)')
|
|
707
713
|
self.stormIsInPrint("LibBase object", mesgs)
|
|
708
714
|
|
|
@@ -716,7 +722,7 @@ class StormTypesTest(s_test.SynTest):
|
|
|
716
722
|
# lib.guid()
|
|
717
723
|
opts = {'vars': {'x': {'foo': 'bar'}, 'y': ['foo']}}
|
|
718
724
|
guid00 = await core.callStorm('return($lib.guid($x, $y))', opts=opts)
|
|
719
|
-
guid01 = await core.callStorm('$x
|
|
725
|
+
guid01 = await core.callStorm('$x=({"foo": "bar"}) $y=$lib.list(foo) return($lib.guid($x, $y))')
|
|
720
726
|
self.eq(guid00, guid01)
|
|
721
727
|
|
|
722
728
|
guid00 = await core.callStorm('return($lib.guid(foo))')
|
|
@@ -729,7 +735,7 @@ class StormTypesTest(s_test.SynTest):
|
|
|
729
735
|
guid = await core.callStorm('return($lib.guid(($lib.undef,)))')
|
|
730
736
|
self.eq(s_common.guid(((),)), guid)
|
|
731
737
|
|
|
732
|
-
guid = await core.callStorm('
|
|
738
|
+
guid = await core.callStorm('$foo = ($lib.undef,) return($lib.guid(({"foo": $foo})))')
|
|
733
739
|
self.eq(s_common.guid(({'foo': ()},)), guid)
|
|
734
740
|
|
|
735
741
|
mesgs = await core.stormlist('function foo() { test:str } $lib.guid($foo())')
|
|
@@ -1143,11 +1149,59 @@ class StormTypesTest(s_test.SynTest):
|
|
|
1143
1149
|
|
|
1144
1150
|
async def test_storm_lib_dict(self):
|
|
1145
1151
|
async with self.getTestCore() as core:
|
|
1146
|
-
nodes = await core.nodes('$blah =
|
|
1152
|
+
nodes = await core.nodes('$blah = ({"foo": "vertex.link"}) [ inet:fqdn=$blah.foo ]')
|
|
1147
1153
|
self.len(1, nodes)
|
|
1148
1154
|
self.eq('vertex.link', nodes[0].ndef[1])
|
|
1149
1155
|
|
|
1150
|
-
self.eq(2, await core.callStorm('$d
|
|
1156
|
+
self.eq(2, await core.callStorm('$d=({"k1": "1", "k2": "2"}) return($lib.len($d))'))
|
|
1157
|
+
|
|
1158
|
+
d = {'key1': 'val1', 'key2': None}
|
|
1159
|
+
opts = {'vars': {'d': d}}
|
|
1160
|
+
has = await core.callStorm('return($lib.dict.has($d, "key1"))', opts=opts)
|
|
1161
|
+
self.true(has)
|
|
1162
|
+
|
|
1163
|
+
has = await core.callStorm('return($lib.dict.has($d, "key2"))', opts=opts)
|
|
1164
|
+
self.true(has)
|
|
1165
|
+
|
|
1166
|
+
has = await core.callStorm('return($lib.dict.has($d, "key3"))', opts=opts)
|
|
1167
|
+
self.false(has)
|
|
1168
|
+
|
|
1169
|
+
d = {'key1': 'val1', 'key2': 'val2'}
|
|
1170
|
+
opts = {'vars': {'d': d}}
|
|
1171
|
+
keys = await core.callStorm('return($lib.dict.keys($d))', opts=opts)
|
|
1172
|
+
self.eq(keys, ['key1', 'key2'])
|
|
1173
|
+
|
|
1174
|
+
vals = await core.callStorm('return($lib.dict.values($d))', opts=opts)
|
|
1175
|
+
self.eq(vals, ['val1', 'val2'])
|
|
1176
|
+
|
|
1177
|
+
val = await core.callStorm('return($lib.dict.pop($d, "key2"))', opts=opts)
|
|
1178
|
+
self.eq(val, 'val2')
|
|
1179
|
+
self.eq(d, {'key1': 'val1'})
|
|
1180
|
+
|
|
1181
|
+
val = await core.callStorm('return($lib.dict.pop($d, "newp", "w00t"))', opts=opts)
|
|
1182
|
+
self.eq(val, 'w00t')
|
|
1183
|
+
self.eq(d, {'key1': 'val1'})
|
|
1184
|
+
|
|
1185
|
+
with self.raises(s_exc.BadArg):
|
|
1186
|
+
await core.callStorm('return($lib.dict.pop($d, "newp"))', opts=opts)
|
|
1187
|
+
|
|
1188
|
+
await core.callStorm('$lib.dict.update($d, ({"foo": "bar"}))', opts=opts)
|
|
1189
|
+
self.eq(d, {'key1': 'val1', 'foo': 'bar'})
|
|
1190
|
+
|
|
1191
|
+
msgs = await core.stormlist('$d = $lib.dict(foo=bar, baz=woot)')
|
|
1192
|
+
self.stormIsInWarn('$lib.dict() is deprecated. Use ({}) instead.', msgs)
|
|
1193
|
+
|
|
1194
|
+
msgs = await core.stormlist('$lib.dict.keys(([]))')
|
|
1195
|
+
self.stormIsInErr('valu argument must be a dict, not list.', msgs)
|
|
1196
|
+
|
|
1197
|
+
msgs = await core.stormlist('$lib.dict.keys(1)')
|
|
1198
|
+
self.stormIsInErr('valu argument must be a dict, not str.', msgs)
|
|
1199
|
+
|
|
1200
|
+
msgs = await core.stormlist('$lib.dict.keys((1))')
|
|
1201
|
+
self.stormIsInErr('valu argument must be a dict, not int.', msgs)
|
|
1202
|
+
|
|
1203
|
+
msgs = await core.stormlist('$lib.dict.keys($lib.undef)')
|
|
1204
|
+
self.stormIsInErr('valu argument must be a dict, not undef.', msgs)
|
|
1151
1205
|
|
|
1152
1206
|
async def test_storm_lib_str(self):
|
|
1153
1207
|
async with self.getTestCore() as core:
|
|
@@ -1269,6 +1323,11 @@ class StormTypesTest(s_test.SynTest):
|
|
|
1269
1323
|
|
|
1270
1324
|
self.eq('foo bar baz faz', await core.callStorm('return($lib.regex.replace("[ ]{2,}", " ", "foo bar baz faz"))'))
|
|
1271
1325
|
|
|
1326
|
+
self.eq(((1, 2, 3)), await core.callStorm('return(("[1, 2, 3]").json())'))
|
|
1327
|
+
|
|
1328
|
+
with self.raises(s_exc.BadJsonText):
|
|
1329
|
+
await core.callStorm('return(("foo").json())')
|
|
1330
|
+
|
|
1272
1331
|
async def test_storm_lib_bytes_gzip(self):
|
|
1273
1332
|
async with self.getTestCore() as core:
|
|
1274
1333
|
hstr = 'ohhai'
|
|
@@ -1943,20 +2002,20 @@ class StormTypesTest(s_test.SynTest):
|
|
|
1943
2002
|
|
|
1944
2003
|
# Dict
|
|
1945
2004
|
q = '''
|
|
1946
|
-
$dict =
|
|
1947
|
-
"foo"
|
|
1948
|
-
"biz"
|
|
1949
|
-
)
|
|
2005
|
+
$dict = ({
|
|
2006
|
+
"foo": "bar",
|
|
2007
|
+
"biz": "baz",
|
|
2008
|
+
})
|
|
1950
2009
|
$set = $lib.set($dict)
|
|
1951
2010
|
'''
|
|
1952
2011
|
msgs = await core.stormlist(q)
|
|
1953
2012
|
self.stormIsInErr('is mutable and cannot be used in a set', msgs)
|
|
1954
2013
|
|
|
1955
2014
|
q = '''
|
|
1956
|
-
$dict =
|
|
1957
|
-
"foo"
|
|
1958
|
-
"biz"
|
|
1959
|
-
)
|
|
2015
|
+
$dict = ({
|
|
2016
|
+
"foo": "bar",
|
|
2017
|
+
"biz": "baz",
|
|
2018
|
+
})
|
|
1960
2019
|
$set = $lib.set()
|
|
1961
2020
|
$set.adds($dict)
|
|
1962
2021
|
$lib.print('There are {count} items in the set', count=$lib.len($set))
|
|
@@ -2162,7 +2221,7 @@ class StormTypesTest(s_test.SynTest):
|
|
|
2162
2221
|
|
|
2163
2222
|
q = '''
|
|
2164
2223
|
inet:fqdn=vertex.link
|
|
2165
|
-
$path.meta.wat =
|
|
2224
|
+
$path.meta.wat = ({"foo": "bar", "biz": "baz", "thing": ({"1": "2", "2": ["a", "b", "c"], "five": "nine"}) })
|
|
2166
2225
|
$path.meta.neato = (awesome, burrito)
|
|
2167
2226
|
'''
|
|
2168
2227
|
msgs = [mesg async for mesg in proxy.storm(q)]
|
|
@@ -2189,7 +2248,7 @@ class StormTypesTest(s_test.SynTest):
|
|
|
2189
2248
|
|
|
2190
2249
|
q = '''
|
|
2191
2250
|
inet:fqdn=vertex.link
|
|
2192
|
-
$test =
|
|
2251
|
+
$test = ({"foo": "bar"})
|
|
2193
2252
|
$path.meta.data = $test
|
|
2194
2253
|
$test.biz = baz
|
|
2195
2254
|
'''
|
|
@@ -2251,7 +2310,7 @@ class StormTypesTest(s_test.SynTest):
|
|
|
2251
2310
|
mesgs = await s_test.alist(prox.storm(popq))
|
|
2252
2311
|
self.stormIsInPrint('pop valu is beep', mesgs)
|
|
2253
2312
|
|
|
2254
|
-
q = '''$x
|
|
2313
|
+
q = '''$x=({"foo": "1"})
|
|
2255
2314
|
$lib.globals.set(bar, $x)
|
|
2256
2315
|
$y=$lib.globals.get(bar)
|
|
2257
2316
|
$lib.print("valu={v}", v=$y.foo)
|
|
@@ -2958,11 +3017,16 @@ class StormTypesTest(s_test.SynTest):
|
|
|
2958
3017
|
|
|
2959
3018
|
async with self.getTestCore() as core:
|
|
2960
3019
|
|
|
3020
|
+
opts = {'vars': {'bytes': 10}}
|
|
3021
|
+
|
|
2961
3022
|
with self.raises(s_exc.BadArg):
|
|
2962
|
-
opts = {'vars': {'bytes': 10}}
|
|
2963
3023
|
text = '($size, $sha2) = $lib.bytes.put($bytes)'
|
|
2964
3024
|
nodes = await core.nodes(text, opts=opts)
|
|
2965
3025
|
|
|
3026
|
+
with self.raises(s_exc.BadArg):
|
|
3027
|
+
text = '($size, $sha2) = $lib.axon.put($bytes)'
|
|
3028
|
+
nodes = await core.nodes(text, opts=opts)
|
|
3029
|
+
|
|
2966
3030
|
asdf = b'asdfasdf'
|
|
2967
3031
|
asdfset = s_hashset.HashSet()
|
|
2968
3032
|
asdfset.update(asdf)
|
|
@@ -2974,6 +3038,7 @@ class StormTypesTest(s_test.SynTest):
|
|
|
2974
3038
|
ret = await core.callStorm('return($lib.bytes.has($hash))', {'vars': {'hash': asdfhash_h}})
|
|
2975
3039
|
self.false(ret)
|
|
2976
3040
|
self.false(await core.callStorm('return($lib.bytes.has($lib.null))'))
|
|
3041
|
+
self.false(await core.callStorm('return($lib.axon.has($lib.null))'))
|
|
2977
3042
|
|
|
2978
3043
|
opts = {'vars': {'bytes': asdf}}
|
|
2979
3044
|
text = '($size, $sha2) = $lib.bytes.put($bytes) [ test:int=$size test:str=$sha2 ]'
|
|
@@ -2983,10 +3048,14 @@ class StormTypesTest(s_test.SynTest):
|
|
|
2983
3048
|
|
|
2984
3049
|
opts = {'vars': {'sha256': asdfhash_h}}
|
|
2985
3050
|
self.eq(8, await core.callStorm('return($lib.bytes.size($sha256))', opts=opts))
|
|
3051
|
+
self.eq(8, await core.callStorm('return($lib.axon.size($sha256))', opts=opts))
|
|
2986
3052
|
|
|
2987
3053
|
hashset = await core.callStorm('return($lib.bytes.hashset($sha256))', opts=opts)
|
|
2988
3054
|
self.eq(hashset, hashes)
|
|
2989
3055
|
|
|
3056
|
+
hashset = await core.callStorm('return($lib.axon.hashset($sha256))', opts=opts)
|
|
3057
|
+
self.eq(hashset, hashes)
|
|
3058
|
+
|
|
2990
3059
|
self.eq(nodes[0].ndef, ('test:int', 8))
|
|
2991
3060
|
self.eq(nodes[1].ndef, ('test:str', asdfhash_h))
|
|
2992
3061
|
|
|
@@ -2997,6 +3066,9 @@ class StormTypesTest(s_test.SynTest):
|
|
|
2997
3066
|
ret = await core.callStorm('return($lib.bytes.has($hash))', {'vars': {'hash': asdfhash_h}})
|
|
2998
3067
|
self.true(ret)
|
|
2999
3068
|
|
|
3069
|
+
ret = await core.callStorm('return($lib.axon.has($hash))', {'vars': {'hash': asdfhash_h}})
|
|
3070
|
+
self.true(ret)
|
|
3071
|
+
|
|
3000
3072
|
# Allow bytes to be directly decoded as a string
|
|
3001
3073
|
opts = {'vars': {'buf': 'hehe'.encode()}}
|
|
3002
3074
|
nodes = await core.nodes('$valu=$buf.decode() [test:str=$valu]', opts)
|
|
@@ -3046,6 +3118,32 @@ class StormTypesTest(s_test.SynTest):
|
|
|
3046
3118
|
retn = await core.callStorm('return($lib.bytes.upload($chunks))', opts=opts)
|
|
3047
3119
|
self.eq((8, '9ed8ffd0a11e337e6e461358195ebf8ea2e12a82db44561ae5d9e638f6f922c4'), retn)
|
|
3048
3120
|
|
|
3121
|
+
retn = await core.callStorm('return($lib.axon.upload($chunks))', opts=opts)
|
|
3122
|
+
self.eq((8, '9ed8ffd0a11e337e6e461358195ebf8ea2e12a82db44561ae5d9e638f6f922c4'), retn)
|
|
3123
|
+
|
|
3124
|
+
visi = await core.auth.addUser('visi')
|
|
3125
|
+
await visi.addRule((False, ('axon', 'has')))
|
|
3126
|
+
|
|
3127
|
+
opts = {'user': visi.iden, 'vars': {'hash': asdfhash_h}}
|
|
3128
|
+
with self.raises(s_exc.AuthDeny):
|
|
3129
|
+
await core.callStorm('return($lib.bytes.has($hash))', opts=opts)
|
|
3130
|
+
|
|
3131
|
+
with self.raises(s_exc.AuthDeny):
|
|
3132
|
+
await core.callStorm('return($lib.bytes.size($hash))', opts=opts)
|
|
3133
|
+
|
|
3134
|
+
with self.raises(s_exc.AuthDeny):
|
|
3135
|
+
await core.callStorm('return($lib.bytes.hashset($hash))', opts=opts)
|
|
3136
|
+
|
|
3137
|
+
await visi.addRule((False, ('axon', 'upload')))
|
|
3138
|
+
|
|
3139
|
+
opts = {'user': visi.iden, 'vars': {'byts': b'foo'}}
|
|
3140
|
+
with self.raises(s_exc.AuthDeny):
|
|
3141
|
+
await core.callStorm('return($lib.bytes.put($byts))', opts=opts)
|
|
3142
|
+
|
|
3143
|
+
opts = {'user': visi.iden, 'vars': {'chunks': (b'visi', b'kewl')}}
|
|
3144
|
+
with self.raises(s_exc.AuthDeny):
|
|
3145
|
+
await core.callStorm('return($lib.bytes.upload($chunks))', opts=opts)
|
|
3146
|
+
|
|
3049
3147
|
async def test_storm_lib_base64(self):
|
|
3050
3148
|
|
|
3051
3149
|
async with self.getTestCore() as core:
|
|
@@ -3060,7 +3158,7 @@ class StormTypesTest(s_test.SynTest):
|
|
|
3060
3158
|
self.eq(nodes[0].ndef, ('test:str', 'Zm9vYmE_'))
|
|
3061
3159
|
|
|
3062
3160
|
opts = {'vars': {'bytes': nodes[0].ndef[1]}}
|
|
3063
|
-
text = '$lib.
|
|
3161
|
+
text = '$lib.axon.put($lib.base64.decode($bytes))'
|
|
3064
3162
|
nodes = await core.nodes(text, opts)
|
|
3065
3163
|
key = binascii.unhexlify(hashlib.sha256(base64.urlsafe_b64decode(opts['vars']['bytes'])).hexdigest())
|
|
3066
3164
|
byts = b''.join([b async for b in core.axon.get(key)])
|
|
@@ -3074,7 +3172,7 @@ class StormTypesTest(s_test.SynTest):
|
|
|
3074
3172
|
self.eq(nodes[0].ndef, ('test:str', 'Zm9vYmE/'))
|
|
3075
3173
|
|
|
3076
3174
|
opts = {'vars': {'bytes': nodes[0].ndef[1]}}
|
|
3077
|
-
text = '$lib.
|
|
3175
|
+
text = '$lib.axon.put($lib.base64.decode($bytes, $(0)))'
|
|
3078
3176
|
nodes = await core.nodes(text, opts)
|
|
3079
3177
|
key = binascii.unhexlify(hashlib.sha256(base64.urlsafe_b64decode(opts['vars']['bytes'])).hexdigest())
|
|
3080
3178
|
byts = b''.join([b async for b in core.axon.get(key)])
|
|
@@ -3317,7 +3415,7 @@ class StormTypesTest(s_test.SynTest):
|
|
|
3317
3415
|
self.sorteq(idens, core.layers)
|
|
3318
3416
|
|
|
3319
3417
|
# Create a new layer with a name
|
|
3320
|
-
q = f'$lib.print($lib.layer.add(
|
|
3418
|
+
q = f'$lib.print($lib.layer.add(({{"name": "foo"}})).iden)'
|
|
3321
3419
|
for mesg in await core.stormlist(q):
|
|
3322
3420
|
if mesg[0] == 'print':
|
|
3323
3421
|
namedlayer = mesg[1]['mesg']
|
|
@@ -4157,12 +4255,12 @@ class StormTypesTest(s_test.SynTest):
|
|
|
4157
4255
|
|
|
4158
4256
|
# Move a trigger to a different view
|
|
4159
4257
|
q = '''
|
|
4160
|
-
$tdef =
|
|
4161
|
-
condition
|
|
4162
|
-
form
|
|
4163
|
-
storm
|
|
4164
|
-
doc
|
|
4165
|
-
)
|
|
4258
|
+
$tdef = ({
|
|
4259
|
+
"condition": 'node:add',
|
|
4260
|
+
"form": 'test:str',
|
|
4261
|
+
"storm": '{[ +#tagged ]}',
|
|
4262
|
+
"doc": 'some trigger'
|
|
4263
|
+
})
|
|
4166
4264
|
$trig = $lib.trigger.add($tdef)
|
|
4167
4265
|
return($trig.pack())
|
|
4168
4266
|
'''
|
|
@@ -4249,12 +4347,12 @@ class StormTypesTest(s_test.SynTest):
|
|
|
4249
4347
|
await core.nodes(f'$lib.trigger.get({trig}).move(newp)')
|
|
4250
4348
|
|
|
4251
4349
|
q = '''
|
|
4252
|
-
$tdef =
|
|
4253
|
-
condition
|
|
4254
|
-
form
|
|
4255
|
-
storm
|
|
4256
|
-
iden
|
|
4257
|
-
)
|
|
4350
|
+
$tdef = ({
|
|
4351
|
+
"condition": 'node:add',
|
|
4352
|
+
"form": 'test:str',
|
|
4353
|
+
"storm": '{[ +#tagged ]}',
|
|
4354
|
+
"iden": $trig
|
|
4355
|
+
})
|
|
4258
4356
|
$trig = $lib.trigger.add($tdef)
|
|
4259
4357
|
return($trig.iden)
|
|
4260
4358
|
'''
|
|
@@ -5062,7 +5160,7 @@ class StormTypesTest(s_test.SynTest):
|
|
|
5062
5160
|
nodes = await core.nodes('[test:guid=(beep,)] $node.props.".seen"=2020')
|
|
5063
5161
|
self.eq((1577836800000, 1577836800001), nodes[0].get('.seen'))
|
|
5064
5162
|
|
|
5065
|
-
text = '$d
|
|
5163
|
+
text = '$d=({}) test:guid=(beep,) { for ($name, $valu) in $node.props { $d.$name=$valu } } return ($d)'
|
|
5066
5164
|
props = await core.callStorm(text)
|
|
5067
5165
|
self.eq(12, props.get('size'))
|
|
5068
5166
|
self.eq((1577836800000, 1577836800001), props.get('.seen'))
|
|
@@ -5104,7 +5202,7 @@ class StormTypesTest(s_test.SynTest):
|
|
|
5104
5202
|
|
|
5105
5203
|
q = '$list = $lib.list() $list.append(foo) $list.append(bar) return($list)'
|
|
5106
5204
|
self.eq(('foo', 'bar'), await core.callStorm(q))
|
|
5107
|
-
self.eq({'foo': 'bar'}, await core.callStorm('$dict =
|
|
5205
|
+
self.eq({'foo': 'bar'}, await core.callStorm('$dict = ({}) $dict.foo = bar return($dict)'))
|
|
5108
5206
|
q = '$tally = $lib.stats.tally() $tally.inc(foo) $tally.inc(foo) return($tally)'
|
|
5109
5207
|
self.eq({'foo': 2}, await core.callStorm(q))
|
|
5110
5208
|
|
|
@@ -5526,7 +5624,7 @@ class StormTypesTest(s_test.SynTest):
|
|
|
5526
5624
|
ret = await core.callStorm('$x=$lib.set() $y=$lib.list(1,2,3) $x.adds($y) return($x)')
|
|
5527
5625
|
self.eq({'1', '2', '3'}, ret)
|
|
5528
5626
|
|
|
5529
|
-
ret = await core.callStorm('$x=$lib.set() $y
|
|
5627
|
+
ret = await core.callStorm('$x=$lib.set() $y=({"foo": "1", "bar": "2"}) $x.adds($y) return($x)')
|
|
5530
5628
|
self.eq({('foo', '1'), ('bar', '2')}, ret)
|
|
5531
5629
|
|
|
5532
5630
|
ret = await core.nodes('$x=$lib.set() $x.adds(${inet:ipv4}) for $n in $x { yield $n.iden() }')
|
|
@@ -5544,16 +5642,16 @@ class StormTypesTest(s_test.SynTest):
|
|
|
5544
5642
|
|
|
5545
5643
|
scmd = '''
|
|
5546
5644
|
$x=$lib.set()
|
|
5547
|
-
$y
|
|
5645
|
+
$y=({"foo": "1", "bar": "2"})
|
|
5548
5646
|
$x.adds($y)
|
|
5549
|
-
$z
|
|
5647
|
+
$z=({"foo": "1"})
|
|
5550
5648
|
$x.rems($z)
|
|
5551
5649
|
return($x)
|
|
5552
5650
|
'''
|
|
5553
5651
|
ret = await core.callStorm(scmd)
|
|
5554
5652
|
self.eq({('bar', '2')}, ret)
|
|
5555
5653
|
|
|
5556
|
-
ret = await core.callStorm('$x=$lib.set() $y
|
|
5654
|
+
ret = await core.callStorm('$x=$lib.set() $y=({"foo": "1", "bar": "2"}) $x.adds($y) return($x)')
|
|
5557
5655
|
self.eq({('foo', '1'), ('bar', '2')}, ret)
|
|
5558
5656
|
|
|
5559
5657
|
ret = await core.callStorm('$x=$lib.set(1,2,3) $x.rems((1,2)) return($x)')
|
|
@@ -5636,7 +5734,7 @@ class StormTypesTest(s_test.SynTest):
|
|
|
5636
5734
|
|
|
5637
5735
|
self.len(1, await core.callStorm('$x=$lib.list() for $i in $lib.axon.list() { $x.append($i) } return($x)'))
|
|
5638
5736
|
|
|
5639
|
-
size, sha256 = await core.callStorm('return($lib.
|
|
5737
|
+
size, sha256 = await core.callStorm('return($lib.axon.put($buf))', opts={'vars': {'buf': b'foo'}})
|
|
5640
5738
|
|
|
5641
5739
|
items = await core.callStorm('$x=$lib.list() for $i in $lib.axon.list() { $x.append($i) } return($x)')
|
|
5642
5740
|
self.len(2, items)
|
|
@@ -5658,9 +5756,9 @@ class StormTypesTest(s_test.SynTest):
|
|
|
5658
5756
|
self.true(resp['ok'])
|
|
5659
5757
|
|
|
5660
5758
|
opts = {'vars': {'linesbuf': linesbuf, 'jsonsbuf': jsonsbuf, 'asdfbuf': b'asdf'}}
|
|
5661
|
-
asdfitem = await core.callStorm('return($lib.
|
|
5662
|
-
linesitem = await core.callStorm('return($lib.
|
|
5663
|
-
jsonsitem = await core.callStorm('return($lib.
|
|
5759
|
+
asdfitem = await core.callStorm('return($lib.axon.put($asdfbuf))', opts=opts)
|
|
5760
|
+
linesitem = await core.callStorm('return($lib.axon.put($linesbuf))', opts=opts)
|
|
5761
|
+
jsonsitem = await core.callStorm('return($lib.axon.put($jsonsbuf))', opts=opts)
|
|
5664
5762
|
|
|
5665
5763
|
opts = {'vars': {'sha256': asdfitem[1]}}
|
|
5666
5764
|
self.eq(('asdf',), await core.callStorm('''
|
|
@@ -6343,6 +6441,9 @@ words\tword\twrd'''
|
|
|
6343
6441
|
with self.raises(s_exc.SynErr):
|
|
6344
6442
|
await core.callStorm('$lib.view.get().merge()', opts={'view': fork00})
|
|
6345
6443
|
|
|
6444
|
+
with self.raises(s_exc.BadState):
|
|
6445
|
+
core.getView(fork00).reqValidVoter(visi.iden)
|
|
6446
|
+
|
|
6346
6447
|
with self.raises(s_exc.AuthDeny):
|
|
6347
6448
|
await core.callStorm('$lib.view.get().setMergeRequest()', opts={'user': visi.iden, 'view': fork00})
|
|
6348
6449
|
|
|
@@ -6352,12 +6453,18 @@ words\tword\twrd'''
|
|
|
6352
6453
|
self.eq(merge['comment'], 'woot')
|
|
6353
6454
|
self.eq(merge['creator'], core.auth.rootuser.iden)
|
|
6354
6455
|
|
|
6456
|
+
with self.raises(s_exc.AuthDeny):
|
|
6457
|
+
core.getView(fork00).reqValidVoter(root.iden)
|
|
6458
|
+
|
|
6355
6459
|
merge = await core.callStorm('return($lib.view.get().getMergeRequest())', opts={'view': fork00})
|
|
6356
6460
|
self.nn(merge['iden'])
|
|
6357
6461
|
self.nn(merge['created'])
|
|
6358
6462
|
self.eq(merge['comment'], 'woot')
|
|
6359
6463
|
self.eq(merge['creator'], core.auth.rootuser.iden)
|
|
6360
6464
|
|
|
6465
|
+
with self.raises(s_exc.AuthDeny):
|
|
6466
|
+
await core.callStorm('$lib.view.get().setMergeVote()', opts={'view': fork00})
|
|
6467
|
+
|
|
6361
6468
|
with self.raises(s_exc.AuthDeny):
|
|
6362
6469
|
await core.callStorm('$lib.view.get().setMergeVote()', opts={'user': visi.iden, 'view': fork00})
|
|
6363
6470
|
|
|
@@ -26,7 +26,7 @@ class StormWhoisTest(s_test.SynTest):
|
|
|
26
26
|
guid_exp = s_common.guid(sorted((props['net4'], str(props['asof']), props['id'])))
|
|
27
27
|
self.len(1, await core.nodes(f'inet:whois:iprec={guid_exp}'))
|
|
28
28
|
|
|
29
|
-
stormcmd = '''$props
|
|
29
|
+
stormcmd = '''$props=({'net4':'10.0.0.0/28', 'asof':(2554869000000), 'id':'NET-10-0-0-0-1', 'status':'validated'})
|
|
30
30
|
return ($lib.inet.whois.guid($props, 'iprec'))
|
|
31
31
|
'''
|
|
32
32
|
guid = await core.callStorm(stormcmd)
|
|
@@ -558,21 +558,21 @@ class TrigTest(s_t_utils.SynTest):
|
|
|
558
558
|
view = await core.callStorm('return ($lib.view.get().fork().iden)')
|
|
559
559
|
|
|
560
560
|
await self.asyncraises(s_exc.SchemaViolation, core.nodes('''
|
|
561
|
-
$tdef =
|
|
562
|
-
cond
|
|
563
|
-
form
|
|
564
|
-
storm
|
|
565
|
-
)
|
|
561
|
+
$tdef = ({
|
|
562
|
+
'cond':'edge:add',
|
|
563
|
+
'form':'test:int',
|
|
564
|
+
'storm':'[+#asdfasdf]'
|
|
565
|
+
})
|
|
566
566
|
$lib.trigger.add($tdef)
|
|
567
567
|
'''))
|
|
568
568
|
|
|
569
569
|
await self.asyncraises(s_exc.SchemaViolation, core.nodes('''
|
|
570
|
-
$tdef =
|
|
571
|
-
cond
|
|
572
|
-
form
|
|
573
|
-
storm
|
|
574
|
-
verb
|
|
575
|
-
)
|
|
570
|
+
$tdef = ({
|
|
571
|
+
'cond':'edge:add',
|
|
572
|
+
'form':'test:int',
|
|
573
|
+
'storm':'[+#asdfasdf]',
|
|
574
|
+
'verb':$lib.null
|
|
575
|
+
})
|
|
576
576
|
$lib.trigger.add($tdef)
|
|
577
577
|
'''))
|
|
578
578
|
|
synapse/tests/test_lib_view.py
CHANGED
|
@@ -670,7 +670,7 @@ class ViewTest(s_t_utils.SynTest):
|
|
|
670
670
|
|
|
671
671
|
mirror_catchup = await core2.getNexsIndx() - 1 + 2 + layr.nodeeditlog.size
|
|
672
672
|
mirror_view, mirror_layr = await core2.callStorm('''
|
|
673
|
-
$ldef =
|
|
673
|
+
$ldef = ({'mirror':$lib.str.concat($baseurl, "/", $baseiden)})
|
|
674
674
|
$lyr = $lib.layer.add(ldef=$ldef)
|
|
675
675
|
$view = $lib.view.add(($lyr.iden,))
|
|
676
676
|
return(($view.iden, $lyr.iden))
|
|
@@ -759,3 +759,25 @@ class ViewTest(s_t_utils.SynTest):
|
|
|
759
759
|
self.nn(nodes[0].tagprops.get('seen'))
|
|
760
760
|
self.nn(nodes[0].tagprops['seen'].get('score'))
|
|
761
761
|
self.nn(nodes[0].nodedata.get('foo'))
|
|
762
|
+
|
|
763
|
+
await core.delUserRule(useriden, (True, ('node', 'tag', 'add')), gateiden=baselayr)
|
|
764
|
+
|
|
765
|
+
await core.addUserRule(useriden, (True, ('node', 'tag', 'add', 'rep', 'foo')), gateiden=baselayr)
|
|
766
|
+
|
|
767
|
+
await core.nodes('test:str=foo [ -#seen +#rep.foo ]', opts=viewopts)
|
|
768
|
+
|
|
769
|
+
await core.nodes('$lib.view.get().merge()', opts=viewopts)
|
|
770
|
+
nodes = await core.nodes('test:str=foo')
|
|
771
|
+
self.nn(nodes[0].get('#rep.foo'))
|
|
772
|
+
|
|
773
|
+
await core.nodes('test:str=foo [ -#rep ]')
|
|
774
|
+
|
|
775
|
+
await core.nodes('test:str=foo | merge --apply', opts=viewopts)
|
|
776
|
+
nodes = await core.nodes('test:str=foo')
|
|
777
|
+
self.nn(nodes[0].get('#rep.foo'))
|
|
778
|
+
|
|
779
|
+
await core.nodes('test:str=foo [ -#rep ]')
|
|
780
|
+
await core.nodes('test:str=foo [ +#rep=now ]', opts=viewopts)
|
|
781
|
+
|
|
782
|
+
with self.raises(s_exc.AuthDeny) as cm:
|
|
783
|
+
await core.nodes('$lib.view.get().merge()', opts=viewopts)
|
|
@@ -344,7 +344,7 @@ class CryptoModelTest(s_t_utils.SynTest):
|
|
|
344
344
|
crypto:smart:token=(2bdea834252a220b61aadf592cc0de66, 30)
|
|
345
345
|
:owner=eth/aaaa
|
|
346
346
|
:nft:url = https://coin.vertex.link/nfts/30
|
|
347
|
-
:nft:meta =
|
|
347
|
+
:nft:meta = ({'name':'WootWoot'})
|
|
348
348
|
:nft:meta:name = WootWoot
|
|
349
349
|
:nft:meta:description = LoLoL
|
|
350
350
|
:nft:meta:image = https://vertex.link/favicon.ico
|
synapse/tests/test_model_inet.py
CHANGED
|
@@ -2662,6 +2662,9 @@ class InetModelTest(s_t_utils.SynTest):
|
|
|
2662
2662
|
:headers=(('to', 'Visi Stark <visi@vertex.link>'),)
|
|
2663
2663
|
:cc=(baz@faz.org, foo@bar.com, baz@faz.org)
|
|
2664
2664
|
:bytes="*"
|
|
2665
|
+
:received:from:ipv4=1.2.3.4
|
|
2666
|
+
:received:from:ipv6="::1"
|
|
2667
|
+
:received:from:fqdn=smtp.vertex.link
|
|
2665
2668
|
]
|
|
2666
2669
|
|
|
2667
2670
|
{[( inet:email:message:link=($node, https://www.vertex.link) :text=Vertex )]}
|
|
@@ -2671,6 +2674,9 @@ class InetModelTest(s_t_utils.SynTest):
|
|
|
2671
2674
|
self.len(1, nodes)
|
|
2672
2675
|
|
|
2673
2676
|
self.eq(nodes[0].get('cc'), ('baz@faz.org', 'foo@bar.com'))
|
|
2677
|
+
self.eq(nodes[0].get('received:from:ipv6'), '::1')
|
|
2678
|
+
self.eq(nodes[0].get('received:from:ipv4'), 0x01020304)
|
|
2679
|
+
self.eq(nodes[0].get('received:from:fqdn'), 'smtp.vertex.link')
|
|
2674
2680
|
|
|
2675
2681
|
self.len(1, await core.nodes('inet:email:message:to=woot@woot.com'))
|
|
2676
2682
|
self.len(1, await core.nodes('inet:email:message:date=2015'))
|
synapse/tests/test_model_orgs.py
CHANGED
|
@@ -450,10 +450,11 @@ class OuModelTest(s_t_utils.SynTest):
|
|
|
450
450
|
self.eq(node.get('departed'), 1519945200000)
|
|
451
451
|
self.eq(node.get('roles'), ('speaker', 'staff'))
|
|
452
452
|
|
|
453
|
-
nodes = await core.nodes('[ ou:id:type=* :org=* :name=foobar ]')
|
|
453
|
+
nodes = await core.nodes('[ ou:id:type=* :org=* :name=foobar :url="http://foobar.com/ids"]')
|
|
454
454
|
self.len(1, nodes)
|
|
455
455
|
self.nn(nodes[0].get('org'))
|
|
456
456
|
self.eq('foobar', nodes[0].get('name'))
|
|
457
|
+
self.eq('http://foobar.com/ids', nodes[0].get('url'))
|
|
457
458
|
|
|
458
459
|
iden = await core.callStorm('ou:id:type return($node.value())')
|
|
459
460
|
|
synapse/tests/test_model_proj.py
CHANGED
|
@@ -19,6 +19,12 @@ class ProjModelTest(s_test.SynTest):
|
|
|
19
19
|
self.nn(proj)
|
|
20
20
|
self.len(1, await core.nodes('proj:project:desc=bar'))
|
|
21
21
|
|
|
22
|
+
nodes = await core.nodes('proj:project [ :type=foo.bar ]')
|
|
23
|
+
self.len(1, nodes)
|
|
24
|
+
self.eq('foo.bar.', nodes[0].get('type'))
|
|
25
|
+
|
|
26
|
+
self.len(1, await core.nodes('proj:project -> proj:project:type:taxonomy'))
|
|
27
|
+
|
|
22
28
|
opts = {'user': visi.iden, 'vars': {'proj': proj}}
|
|
23
29
|
with self.raises(s_exc.AuthDeny):
|
|
24
30
|
await core.callStorm('return($lib.projects.get($proj).epics.add(bar))', opts=opts)
|
synapse/tests/test_model_risk.py
CHANGED
|
@@ -285,6 +285,9 @@ class RiskModelTest(s_t_utils.SynTest):
|
|
|
285
285
|
:detected=20501217
|
|
286
286
|
:attack=*
|
|
287
287
|
:vuln=*
|
|
288
|
+
:status=todo
|
|
289
|
+
:assignee=$lib.user.iden
|
|
290
|
+
:ext:assignee = {[ ps:contact=* :email=visi@vertex.link ]}
|
|
288
291
|
:url=https://vertex.link/alerts/WOOT-20
|
|
289
292
|
:ext:id=WOOT-20
|
|
290
293
|
:engine={[ it:prod:softver=* :name=visiware ]}
|
|
@@ -294,6 +297,7 @@ class RiskModelTest(s_t_utils.SynTest):
|
|
|
294
297
|
]
|
|
295
298
|
''')
|
|
296
299
|
self.len(1, nodes)
|
|
300
|
+
self.eq(20, nodes[0].get('status'))
|
|
297
301
|
self.eq(40, nodes[0].get('priority'))
|
|
298
302
|
self.eq(50, nodes[0].get('severity'))
|
|
299
303
|
self.eq('bazfaz.', nodes[0].get('type'))
|
|
@@ -302,7 +306,9 @@ class RiskModelTest(s_t_utils.SynTest):
|
|
|
302
306
|
self.eq(2554848000000, nodes[0].get('detected'))
|
|
303
307
|
self.eq('WOOT-20', nodes[0].get('ext:id'))
|
|
304
308
|
self.eq('https://vertex.link/alerts/WOOT-20', nodes[0].get('url'))
|
|
309
|
+
self.eq(core.auth.rootuser.iden, nodes[0].get('assignee'))
|
|
305
310
|
self.nn(nodes[0].get('host'))
|
|
311
|
+
self.nn(nodes[0].get('ext:assignee'))
|
|
306
312
|
self.len(1, await core.nodes('risk:alert -> it:host'))
|
|
307
313
|
self.len(1, await core.nodes('risk:alert -> risk:vuln'))
|
|
308
314
|
self.len(1, await core.nodes('risk:alert -> risk:attack'))
|
|
@@ -504,9 +510,13 @@ class RiskModelTest(s_t_utils.SynTest):
|
|
|
504
510
|
:desc=BazFaz
|
|
505
511
|
:hardware=*
|
|
506
512
|
:software=*
|
|
513
|
+
:reporter:name=vertex
|
|
514
|
+
:reporter = { gen.ou.org vertex }
|
|
507
515
|
]''')
|
|
508
516
|
self.eq('FooBar', nodes[0].props['name'])
|
|
509
517
|
self.eq('BazFaz', nodes[0].props['desc'])
|
|
518
|
+
self.eq('vertex', nodes[0].get('reporter:name'))
|
|
519
|
+
self.nn(nodes[0].get('reporter'))
|
|
510
520
|
self.len(1, await core.nodes('risk:mitigation -> risk:vuln'))
|
|
511
521
|
self.len(1, await core.nodes('risk:mitigation -> it:prod:softver'))
|
|
512
522
|
self.len(1, await core.nodes('risk:mitigation -> it:prod:hardware'))
|