synapse 2.160.0__py311-none-any.whl → 2.162.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.

Files changed (71) hide show
  1. synapse/cortex.py +12 -7
  2. synapse/daemon.py +7 -2
  3. synapse/lib/agenda.py +8 -2
  4. synapse/lib/aha.py +4 -4
  5. synapse/lib/ast.py +3 -3
  6. synapse/lib/cell.py +20 -1
  7. synapse/lib/hiveauth.py +1 -1
  8. synapse/lib/httpapi.py +5 -0
  9. synapse/lib/layer.py +21 -1
  10. synapse/lib/nexus.py +9 -5
  11. synapse/lib/node.py +3 -4
  12. synapse/lib/rstorm.py +16 -0
  13. synapse/lib/schemas.py +2 -1
  14. synapse/lib/snap.py +20 -11
  15. synapse/lib/storm.py +19 -3
  16. synapse/lib/stormhttp.py +14 -2
  17. synapse/lib/stormlib/easyperm.py +5 -2
  18. synapse/lib/stormlib/gen.py +119 -44
  19. synapse/lib/stormlib/stix.py +6 -3
  20. synapse/lib/stormlib/vault.py +32 -15
  21. synapse/lib/stormtypes.py +187 -21
  22. synapse/lib/trigger.py +2 -0
  23. synapse/lib/version.py +2 -2
  24. synapse/lib/view.py +42 -10
  25. synapse/models/inet.py +9 -0
  26. synapse/models/infotech.py +28 -26
  27. synapse/models/orgs.py +3 -0
  28. synapse/models/proj.py +9 -2
  29. synapse/models/risk.py +32 -0
  30. synapse/telepath.py +6 -2
  31. synapse/tests/files/rstorm/testsvc.py +8 -1
  32. synapse/tests/files/stormpkg/testpkg.yaml +4 -0
  33. synapse/tests/test_axon.py +4 -4
  34. synapse/tests/test_cortex.py +66 -8
  35. synapse/tests/test_daemon.py +19 -0
  36. synapse/tests/test_lib_agenda.py +8 -0
  37. synapse/tests/test_lib_aha.py +18 -3
  38. synapse/tests/test_lib_ast.py +38 -16
  39. synapse/tests/test_lib_cell.py +3 -0
  40. synapse/tests/test_lib_grammar.py +4 -4
  41. synapse/tests/test_lib_httpapi.py +59 -0
  42. synapse/tests/test_lib_nexus.py +63 -0
  43. synapse/tests/test_lib_rstorm.py +38 -2
  44. synapse/tests/test_lib_snap.py +10 -0
  45. synapse/tests/test_lib_storm.py +61 -20
  46. synapse/tests/test_lib_stormhttp.py +21 -21
  47. synapse/tests/test_lib_stormlib_auth.py +3 -3
  48. synapse/tests/test_lib_stormlib_cell.py +1 -1
  49. synapse/tests/test_lib_stormlib_cortex.py +50 -2
  50. synapse/tests/test_lib_stormlib_gen.py +77 -0
  51. synapse/tests/test_lib_stormlib_json.py +2 -2
  52. synapse/tests/test_lib_stormlib_macro.py +1 -1
  53. synapse/tests/test_lib_stormlib_modelext.py +37 -37
  54. synapse/tests/test_lib_stormlib_oauth.py +20 -20
  55. synapse/tests/test_lib_stormlib_stix.py +3 -1
  56. synapse/tests/test_lib_stormlib_vault.py +1 -1
  57. synapse/tests/test_lib_stormtypes.py +159 -47
  58. synapse/tests/test_lib_stormwhois.py +1 -1
  59. synapse/tests/test_lib_trigger.py +11 -11
  60. synapse/tests/test_lib_view.py +23 -1
  61. synapse/tests/test_model_crypto.py +1 -1
  62. synapse/tests/test_model_inet.py +6 -0
  63. synapse/tests/test_model_orgs.py +2 -1
  64. synapse/tests/test_model_proj.py +6 -0
  65. synapse/tests/test_model_risk.py +10 -0
  66. synapse/tests/test_tools_storm.py +1 -1
  67. {synapse-2.160.0.dist-info → synapse-2.162.0.dist-info}/METADATA +5 -3
  68. {synapse-2.160.0.dist-info → synapse-2.162.0.dist-info}/RECORD +71 -71
  69. {synapse-2.160.0.dist-info → synapse-2.162.0.dist-info}/LICENSE +0 -0
  70. {synapse-2.160.0.dist-info → synapse-2.162.0.dist-info}/WHEEL +0 -0
  71. {synapse-2.160.0.dist-info → synapse-2.162.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, $lib.dict(haha=hoho)))')
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, $lib.dict(key=valu)))'
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, $lib.dict(key=valu)))'
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, $lib.dict(foo=bar, baz=faz)))'))
193
- self.true(await core.callStorm('return($lib.jsonstor.set(bye/bye, $lib.dict(zip=zop, bip=bop)))'))
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))'))
@@ -680,12 +680,12 @@ class StormTypesTest(s_test.SynTest):
680
680
  self.stormIsInPrint("'2'", mesgs)
681
681
  self.stormIsInPrint("'3'", mesgs)
682
682
 
683
- mesgs = await core.stormlist('$lib.print($lib.dict(foo=1, bar=2))')
683
+ mesgs = await core.stormlist('$lib.print(({"foo": "1", "bar": "2"}))')
684
684
  self.stormIsInPrint("'foo': '1'", mesgs)
685
685
  self.stormIsInPrint("'bar': '2'", mesgs)
686
686
 
687
687
  mesgs = await core.stormlist('$lib.print($lib.dict)')
688
- self.stormIsInPrint("bound method LibBase._dict", mesgs)
688
+ self.stormIsInPrint("Library $lib.dict", mesgs)
689
689
 
690
690
  mesgs = await core.stormlist('$lib.print($lib)')
691
691
  self.stormIsInPrint("Library $lib", mesgs)
@@ -696,13 +696,10 @@ class StormTypesTest(s_test.SynTest):
696
696
  mesgs = await core.stormlist('$lib.pprint($lib.list(1,2,3))')
697
697
  self.stormIsInPrint("('1', '2', '3')", mesgs)
698
698
 
699
- mesgs = await core.stormlist('$lib.pprint($lib.dict(foo=1, bar=2))')
699
+ mesgs = await core.stormlist('$lib.pprint(({"foo": "1", "bar": "2"}))')
700
700
  self.stormIsInPrint("'foo': '1'", mesgs)
701
701
  self.stormIsInPrint("'bar': '2'", mesgs)
702
702
 
703
- mesgs = await core.stormlist('$lib.pprint($lib.dict)')
704
- self.stormIsInPrint("bound method LibBase._dict", mesgs)
705
-
706
703
  mesgs = await core.stormlist('$lib.pprint($lib)')
707
704
  self.stormIsInPrint("LibBase object", mesgs)
708
705
 
@@ -716,7 +713,7 @@ class StormTypesTest(s_test.SynTest):
716
713
  # lib.guid()
717
714
  opts = {'vars': {'x': {'foo': 'bar'}, 'y': ['foo']}}
718
715
  guid00 = await core.callStorm('return($lib.guid($x, $y))', opts=opts)
719
- guid01 = await core.callStorm('$x=$lib.dict(foo=bar) $y=$lib.list(foo) return($lib.guid($x, $y))')
716
+ guid01 = await core.callStorm('$x=({"foo": "bar"}) $y=$lib.list(foo) return($lib.guid($x, $y))')
720
717
  self.eq(guid00, guid01)
721
718
 
722
719
  guid00 = await core.callStorm('return($lib.guid(foo))')
@@ -729,7 +726,7 @@ class StormTypesTest(s_test.SynTest):
729
726
  guid = await core.callStorm('return($lib.guid(($lib.undef,)))')
730
727
  self.eq(s_common.guid(((),)), guid)
731
728
 
732
- guid = await core.callStorm('return($lib.guid($lib.dict(foo=($lib.undef,))))')
729
+ guid = await core.callStorm('$foo = ($lib.undef,) return($lib.guid(({"foo": $foo})))')
733
730
  self.eq(s_common.guid(({'foo': ()},)), guid)
734
731
 
735
732
  mesgs = await core.stormlist('function foo() { test:str } $lib.guid($foo())')
@@ -1143,11 +1140,59 @@ class StormTypesTest(s_test.SynTest):
1143
1140
 
1144
1141
  async def test_storm_lib_dict(self):
1145
1142
  async with self.getTestCore() as core:
1146
- nodes = await core.nodes('$blah = $lib.dict(foo=vertex.link) [ inet:fqdn=$blah.foo ]')
1143
+ nodes = await core.nodes('$blah = ({"foo": "vertex.link"}) [ inet:fqdn=$blah.foo ]')
1147
1144
  self.len(1, nodes)
1148
1145
  self.eq('vertex.link', nodes[0].ndef[1])
1149
1146
 
1150
- self.eq(2, await core.callStorm('$d=$lib.dict(k1=1, k2=2) return($lib.len($d))'))
1147
+ self.eq(2, await core.callStorm('$d=({"k1": "1", "k2": "2"}) return($lib.len($d))'))
1148
+
1149
+ d = {'key1': 'val1', 'key2': None}
1150
+ opts = {'vars': {'d': d}}
1151
+ has = await core.callStorm('return($lib.dict.has($d, "key1"))', opts=opts)
1152
+ self.true(has)
1153
+
1154
+ has = await core.callStorm('return($lib.dict.has($d, "key2"))', opts=opts)
1155
+ self.true(has)
1156
+
1157
+ has = await core.callStorm('return($lib.dict.has($d, "key3"))', opts=opts)
1158
+ self.false(has)
1159
+
1160
+ d = {'key1': 'val1', 'key2': 'val2'}
1161
+ opts = {'vars': {'d': d}}
1162
+ keys = await core.callStorm('return($lib.dict.keys($d))', opts=opts)
1163
+ self.eq(keys, ['key1', 'key2'])
1164
+
1165
+ vals = await core.callStorm('return($lib.dict.values($d))', opts=opts)
1166
+ self.eq(vals, ['val1', 'val2'])
1167
+
1168
+ val = await core.callStorm('return($lib.dict.pop($d, "key2"))', opts=opts)
1169
+ self.eq(val, 'val2')
1170
+ self.eq(d, {'key1': 'val1'})
1171
+
1172
+ val = await core.callStorm('return($lib.dict.pop($d, "newp", "w00t"))', opts=opts)
1173
+ self.eq(val, 'w00t')
1174
+ self.eq(d, {'key1': 'val1'})
1175
+
1176
+ with self.raises(s_exc.BadArg):
1177
+ await core.callStorm('return($lib.dict.pop($d, "newp"))', opts=opts)
1178
+
1179
+ await core.callStorm('$lib.dict.update($d, ({"foo": "bar"}))', opts=opts)
1180
+ self.eq(d, {'key1': 'val1', 'foo': 'bar'})
1181
+
1182
+ msgs = await core.stormlist('$d = $lib.dict(foo=bar, baz=woot)')
1183
+ self.stormIsInWarn('$lib.dict() is deprecated. Use ({}) instead.', msgs)
1184
+
1185
+ msgs = await core.stormlist('$lib.dict.keys(([]))')
1186
+ self.stormIsInErr('valu argument must be a dict, not list.', msgs)
1187
+
1188
+ msgs = await core.stormlist('$lib.dict.keys(1)')
1189
+ self.stormIsInErr('valu argument must be a dict, not str.', msgs)
1190
+
1191
+ msgs = await core.stormlist('$lib.dict.keys((1))')
1192
+ self.stormIsInErr('valu argument must be a dict, not int.', msgs)
1193
+
1194
+ msgs = await core.stormlist('$lib.dict.keys($lib.undef)')
1195
+ self.stormIsInErr('valu argument must be a dict, not undef.', msgs)
1151
1196
 
1152
1197
  async def test_storm_lib_str(self):
1153
1198
  async with self.getTestCore() as core:
@@ -1269,6 +1314,11 @@ class StormTypesTest(s_test.SynTest):
1269
1314
 
1270
1315
  self.eq('foo bar baz faz', await core.callStorm('return($lib.regex.replace("[ ]{2,}", " ", "foo bar baz faz"))'))
1271
1316
 
1317
+ self.eq(((1, 2, 3)), await core.callStorm('return(("[1, 2, 3]").json())'))
1318
+
1319
+ with self.raises(s_exc.BadJsonText):
1320
+ await core.callStorm('return(("foo").json())')
1321
+
1272
1322
  async def test_storm_lib_bytes_gzip(self):
1273
1323
  async with self.getTestCore() as core:
1274
1324
  hstr = 'ohhai'
@@ -1943,20 +1993,20 @@ class StormTypesTest(s_test.SynTest):
1943
1993
 
1944
1994
  # Dict
1945
1995
  q = '''
1946
- $dict = $lib.dict(
1947
- "foo" = "bar",
1948
- "biz" = "baz",
1949
- )
1996
+ $dict = ({
1997
+ "foo": "bar",
1998
+ "biz": "baz",
1999
+ })
1950
2000
  $set = $lib.set($dict)
1951
2001
  '''
1952
2002
  msgs = await core.stormlist(q)
1953
2003
  self.stormIsInErr('is mutable and cannot be used in a set', msgs)
1954
2004
 
1955
2005
  q = '''
1956
- $dict = $lib.dict(
1957
- "foo" = "bar",
1958
- "biz" = "baz",
1959
- )
2006
+ $dict = ({
2007
+ "foo": "bar",
2008
+ "biz": "baz",
2009
+ })
1960
2010
  $set = $lib.set()
1961
2011
  $set.adds($dict)
1962
2012
  $lib.print('There are {count} items in the set', count=$lib.len($set))
@@ -2162,7 +2212,7 @@ class StormTypesTest(s_test.SynTest):
2162
2212
 
2163
2213
  q = '''
2164
2214
  inet:fqdn=vertex.link
2165
- $path.meta.wat = $lib.dict(foo=bar, biz=baz, thing=$lib.dict(1=2, 2=(a, b, c), five=nine))
2215
+ $path.meta.wat = ({"foo": "bar", "biz": "baz", "thing": ({"1": "2", "2": ["a", "b", "c"], "five": "nine"}) })
2166
2216
  $path.meta.neato = (awesome, burrito)
2167
2217
  '''
2168
2218
  msgs = [mesg async for mesg in proxy.storm(q)]
@@ -2189,7 +2239,7 @@ class StormTypesTest(s_test.SynTest):
2189
2239
 
2190
2240
  q = '''
2191
2241
  inet:fqdn=vertex.link
2192
- $test = $lib.dict(foo=bar)
2242
+ $test = ({"foo": "bar"})
2193
2243
  $path.meta.data = $test
2194
2244
  $test.biz = baz
2195
2245
  '''
@@ -2251,7 +2301,7 @@ class StormTypesTest(s_test.SynTest):
2251
2301
  mesgs = await s_test.alist(prox.storm(popq))
2252
2302
  self.stormIsInPrint('pop valu is beep', mesgs)
2253
2303
 
2254
- q = '''$x=$lib.dict(foo=1)
2304
+ q = '''$x=({"foo": "1"})
2255
2305
  $lib.globals.set(bar, $x)
2256
2306
  $y=$lib.globals.get(bar)
2257
2307
  $lib.print("valu={v}", v=$y.foo)
@@ -3046,6 +3096,29 @@ class StormTypesTest(s_test.SynTest):
3046
3096
  retn = await core.callStorm('return($lib.bytes.upload($chunks))', opts=opts)
3047
3097
  self.eq((8, '9ed8ffd0a11e337e6e461358195ebf8ea2e12a82db44561ae5d9e638f6f922c4'), retn)
3048
3098
 
3099
+ visi = await core.auth.addUser('visi')
3100
+ await visi.addRule((False, ('axon', 'has')))
3101
+
3102
+ opts = {'user': visi.iden, 'vars': {'hash': asdfhash_h}}
3103
+ with self.raises(s_exc.AuthDeny):
3104
+ await core.callStorm('return($lib.bytes.has($hash))', opts=opts)
3105
+
3106
+ with self.raises(s_exc.AuthDeny):
3107
+ await core.callStorm('return($lib.bytes.size($hash))', opts=opts)
3108
+
3109
+ with self.raises(s_exc.AuthDeny):
3110
+ await core.callStorm('return($lib.bytes.hashset($hash))', opts=opts)
3111
+
3112
+ await visi.addRule((False, ('axon', 'upload')))
3113
+
3114
+ opts = {'user': visi.iden, 'vars': {'byts': b'foo'}}
3115
+ with self.raises(s_exc.AuthDeny):
3116
+ await core.callStorm('return($lib.bytes.put($byts))', opts=opts)
3117
+
3118
+ opts = {'user': visi.iden, 'vars': {'chunks': (b'visi', b'kewl')}}
3119
+ with self.raises(s_exc.AuthDeny):
3120
+ await core.callStorm('return($lib.bytes.upload($chunks))', opts=opts)
3121
+
3049
3122
  async def test_storm_lib_base64(self):
3050
3123
 
3051
3124
  async with self.getTestCore() as core:
@@ -3284,6 +3357,7 @@ class StormTypesTest(s_test.SynTest):
3284
3357
  size = info.get('totalsize')
3285
3358
 
3286
3359
  self.gt(size, 1)
3360
+ self.nn(info.get('created'))
3287
3361
  # Verify we're showing actual disk usage and not just apparent
3288
3362
  self.lt(size, 1000000000)
3289
3363
 
@@ -3316,7 +3390,7 @@ class StormTypesTest(s_test.SynTest):
3316
3390
  self.sorteq(idens, core.layers)
3317
3391
 
3318
3392
  # Create a new layer with a name
3319
- q = f'$lib.print($lib.layer.add($lib.dict(name=foo)).iden)'
3393
+ q = f'$lib.print($lib.layer.add(({{"name": "foo"}})).iden)'
3320
3394
  for mesg in await core.stormlist(q):
3321
3395
  if mesg[0] == 'print':
3322
3396
  namedlayer = mesg[1]['mesg']
@@ -3623,6 +3697,7 @@ class StormTypesTest(s_test.SynTest):
3623
3697
  await core.stormlist('$lib.view.get().set(name, $lib.undef)')
3624
3698
  vdef = await core.callStorm('return($lib.view.get())')
3625
3699
  self.notin('name', vdef)
3700
+ self.nn(vdef.get('created'))
3626
3701
 
3627
3702
  await core.stormlist('$lib.layer.get().set(name, $lib.null)')
3628
3703
  ldef = await core.callStorm('return($lib.layer.get())')
@@ -4131,6 +4206,7 @@ class StormTypesTest(s_test.SynTest):
4131
4206
  self.true(trigdef.get('enabled'))
4132
4207
  self.nn(trigdef.get('user'))
4133
4208
  self.nn(trigdef.get('view'))
4209
+ self.nn(trigdef.get('created'))
4134
4210
  self.eq(trigdef.get('storm'), '[ test:int=99 ] | spin')
4135
4211
  self.eq(trigdef.get('cond'), 'node:add')
4136
4212
  self.eq(trigdef.get('form'), 'test:str')
@@ -4154,12 +4230,12 @@ class StormTypesTest(s_test.SynTest):
4154
4230
 
4155
4231
  # Move a trigger to a different view
4156
4232
  q = '''
4157
- $tdef = $lib.dict(
4158
- condition='node:add',
4159
- form='test:str',
4160
- storm='{[ +#tagged ]}',
4161
- doc='some trigger'
4162
- )
4233
+ $tdef = ({
4234
+ "condition": 'node:add',
4235
+ "form": 'test:str',
4236
+ "storm": '{[ +#tagged ]}',
4237
+ "doc": 'some trigger'
4238
+ })
4163
4239
  $trig = $lib.trigger.add($tdef)
4164
4240
  return($trig.pack())
4165
4241
  '''
@@ -4170,6 +4246,10 @@ class StormTypesTest(s_test.SynTest):
4170
4246
  tdef = await core.callStorm(q, opts={'vars': {'trig': trig}})
4171
4247
  self.eq(tdef.get('doc'), 'awesome trigger')
4172
4248
 
4249
+ with self.raises(s_exc.BadArg):
4250
+ q = '$t = $lib.trigger.get($trig) $t.set("created", "woot") return ( $t.pack() )'
4251
+ await core.callStorm(q, opts={'vars': {'trig': trig}})
4252
+
4173
4253
  with self.raises(s_exc.BadArg):
4174
4254
  q = '$t = $lib.trigger.get($trig) $t.set("foo", "bar")'
4175
4255
  await core.callStorm(q, opts={'vars': {'trig': trig}})
@@ -4188,6 +4268,7 @@ class StormTypesTest(s_test.SynTest):
4188
4268
  self.stormIsInPrint(forkview, mesgs)
4189
4269
  self.len(1, nodes)
4190
4270
  othr = nodes[0].ndef[1]
4271
+ self.nn(nodes[0].props.get('.created'))
4191
4272
 
4192
4273
  # fetch a trigger from another view
4193
4274
  self.nn(await core.callStorm(f'return($lib.trigger.get({othr}))'))
@@ -4241,12 +4322,12 @@ class StormTypesTest(s_test.SynTest):
4241
4322
  await core.nodes(f'$lib.trigger.get({trig}).move(newp)')
4242
4323
 
4243
4324
  q = '''
4244
- $tdef = $lib.dict(
4245
- condition='node:add',
4246
- form='test:str',
4247
- storm='{[ +#tagged ]}',
4248
- iden=$trig
4249
- )
4325
+ $tdef = ({
4326
+ "condition": 'node:add',
4327
+ "form": 'test:str',
4328
+ "storm": '{[ +#tagged ]}',
4329
+ "iden": $trig
4330
+ })
4250
4331
  $trig = $lib.trigger.add($tdef)
4251
4332
  return($trig.iden)
4252
4333
  '''
@@ -5054,7 +5135,7 @@ class StormTypesTest(s_test.SynTest):
5054
5135
  nodes = await core.nodes('[test:guid=(beep,)] $node.props.".seen"=2020')
5055
5136
  self.eq((1577836800000, 1577836800001), nodes[0].get('.seen'))
5056
5137
 
5057
- text = '$d=$lib.dict() test:guid=(beep,) { for ($name, $valu) in $node.props { $d.$name=$valu } } return ($d)'
5138
+ text = '$d=({}) test:guid=(beep,) { for ($name, $valu) in $node.props { $d.$name=$valu } } return ($d)'
5058
5139
  props = await core.callStorm(text)
5059
5140
  self.eq(12, props.get('size'))
5060
5141
  self.eq((1577836800000, 1577836800001), props.get('.seen'))
@@ -5096,7 +5177,7 @@ class StormTypesTest(s_test.SynTest):
5096
5177
 
5097
5178
  q = '$list = $lib.list() $list.append(foo) $list.append(bar) return($list)'
5098
5179
  self.eq(('foo', 'bar'), await core.callStorm(q))
5099
- self.eq({'foo': 'bar'}, await core.callStorm('$dict = $lib.dict() $dict.foo = bar return($dict)'))
5180
+ self.eq({'foo': 'bar'}, await core.callStorm('$dict = ({}) $dict.foo = bar return($dict)'))
5100
5181
  q = '$tally = $lib.stats.tally() $tally.inc(foo) $tally.inc(foo) return($tally)'
5101
5182
  self.eq({'foo': 2}, await core.callStorm(q))
5102
5183
 
@@ -5518,7 +5599,7 @@ class StormTypesTest(s_test.SynTest):
5518
5599
  ret = await core.callStorm('$x=$lib.set() $y=$lib.list(1,2,3) $x.adds($y) return($x)')
5519
5600
  self.eq({'1', '2', '3'}, ret)
5520
5601
 
5521
- ret = await core.callStorm('$x=$lib.set() $y=$lib.dict(foo=1, bar=2) $x.adds($y) return($x)')
5602
+ ret = await core.callStorm('$x=$lib.set() $y=({"foo": "1", "bar": "2"}) $x.adds($y) return($x)')
5522
5603
  self.eq({('foo', '1'), ('bar', '2')}, ret)
5523
5604
 
5524
5605
  ret = await core.nodes('$x=$lib.set() $x.adds(${inet:ipv4}) for $n in $x { yield $n.iden() }')
@@ -5536,16 +5617,16 @@ class StormTypesTest(s_test.SynTest):
5536
5617
 
5537
5618
  scmd = '''
5538
5619
  $x=$lib.set()
5539
- $y=$lib.dict(foo=1, bar=2)
5620
+ $y=({"foo": "1", "bar": "2"})
5540
5621
  $x.adds($y)
5541
- $z=$lib.dict(foo=1)
5622
+ $z=({"foo": "1"})
5542
5623
  $x.rems($z)
5543
5624
  return($x)
5544
5625
  '''
5545
5626
  ret = await core.callStorm(scmd)
5546
5627
  self.eq({('bar', '2')}, ret)
5547
5628
 
5548
- ret = await core.callStorm('$x=$lib.set() $y=$lib.dict(foo=1, bar=2) $x.adds($y) return($x)')
5629
+ ret = await core.callStorm('$x=$lib.set() $y=({"foo": "1", "bar": "2"}) $x.adds($y) return($x)')
5549
5630
  self.eq({('foo', '1'), ('bar', '2')}, ret)
5550
5631
 
5551
5632
  ret = await core.callStorm('$x=$lib.set(1,2,3) $x.rems((1,2)) return($x)')
@@ -6335,6 +6416,9 @@ words\tword\twrd'''
6335
6416
  with self.raises(s_exc.SynErr):
6336
6417
  await core.callStorm('$lib.view.get().merge()', opts={'view': fork00})
6337
6418
 
6419
+ with self.raises(s_exc.BadState):
6420
+ core.getView(fork00).reqValidVoter(visi.iden)
6421
+
6338
6422
  with self.raises(s_exc.AuthDeny):
6339
6423
  await core.callStorm('$lib.view.get().setMergeRequest()', opts={'user': visi.iden, 'view': fork00})
6340
6424
 
@@ -6344,6 +6428,18 @@ words\tword\twrd'''
6344
6428
  self.eq(merge['comment'], 'woot')
6345
6429
  self.eq(merge['creator'], core.auth.rootuser.iden)
6346
6430
 
6431
+ with self.raises(s_exc.AuthDeny):
6432
+ core.getView(fork00).reqValidVoter(root.iden)
6433
+
6434
+ merge = await core.callStorm('return($lib.view.get().getMergeRequest())', opts={'view': fork00})
6435
+ self.nn(merge['iden'])
6436
+ self.nn(merge['created'])
6437
+ self.eq(merge['comment'], 'woot')
6438
+ self.eq(merge['creator'], core.auth.rootuser.iden)
6439
+
6440
+ with self.raises(s_exc.AuthDeny):
6441
+ await core.callStorm('$lib.view.get().setMergeVote()', opts={'view': fork00})
6442
+
6347
6443
  with self.raises(s_exc.AuthDeny):
6348
6444
  await core.callStorm('$lib.view.get().setMergeVote()', opts={'user': visi.iden, 'view': fork00})
6349
6445
 
@@ -6365,6 +6461,13 @@ words\tword\twrd'''
6365
6461
  self.true(vote['approved'])
6366
6462
  self.eq(vote['user'], newp.iden)
6367
6463
 
6464
+ summary = await core.callStorm('return($lib.view.get().getMergeRequestSummary())', opts={'view': fork00})
6465
+ self.nn(summary['merge'])
6466
+ self.nn(summary['quorum'])
6467
+ self.nn(summary['offset'])
6468
+ self.len(2, summary['votes'])
6469
+ self.false(summary['merging'])
6470
+
6368
6471
  with self.raises(s_exc.AuthDeny):
6369
6472
  opts = {'user': newp.iden, 'view': fork00, 'vars': {'visi': visi.iden}}
6370
6473
  await core.callStorm('return($lib.view.get().delMergeVote(useriden=$visi))', opts=opts)
@@ -6415,7 +6518,11 @@ words\tword\twrd'''
6415
6518
  await core.stormlist('[ inet:ipv4=1.2.3.0/20 ]', opts=opts)
6416
6519
  await core.callStorm('return($lib.view.get().setMergeRequest())', opts=opts)
6417
6520
 
6418
- waiter = core.waiter(7, 'cell:beholder')
6521
+ nevents = 8
6522
+ if s_common.envbool('SYNDEV_NEXUS_REPLAY'):
6523
+ # view:merge:vote:set fires twice
6524
+ nevents = nevents + 1
6525
+ waiter = core.waiter(nevents, 'cell:beholder')
6419
6526
 
6420
6527
  opts = {'view': fork.iden, 'user': visi.iden}
6421
6528
  await core.callStorm('return($lib.view.get().setMergeVote())', opts=opts)
@@ -6478,6 +6585,11 @@ words\tword\twrd'''
6478
6585
  async with self.getTestCore(conf={'mirror': core.getLocalUrl()}, dirn=dirn) as mirror:
6479
6586
  await mirror.sync()
6480
6587
  view = mirror.getView(fork.iden)
6588
+ layr = view.layers[0]
6481
6589
  await mirror.promote(graceful=False)
6482
- self.true(await view.waitfini(3))
6590
+ self.true(await view.waitfini(6))
6591
+ self.true(await layr.waitfini(6))
6483
6592
  self.len(1, await mirror.nodes('inet:ipv4=5.5.5.5'))
6593
+
6594
+ msgs = await core.stormlist('$lib.view.get().set(quorum, $lib.null)')
6595
+ self.stormHasNoWarnErr(msgs)
@@ -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=$lib.dict(net4="10.0.0.0/28", asof=(2554869000000), id='NET-10-0-0-0-1', status=validated)
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 = $lib.dict(
562
- cond="edge:add",
563
- form="test:int",
564
- storm="[+#asdfasdf]"
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 = $lib.dict(
571
- cond="edge:add",
572
- form="test:int",
573
- storm="[+#asdfasdf]",
574
- verb=$lib.null
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
 
@@ -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 = $lib.dict(mirror=$lib.str.concat($baseurl, "/", $baseiden))
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 = $lib.dict(name=WootWoot)
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
@@ -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'))
@@ -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
 
@@ -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)
@@ -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'))
@@ -23,7 +23,7 @@ class StormCliTest(s_test.SynTest):
23
23
  self.eq('woot', opts.cortex)
24
24
  self.none(opts.view)
25
25
 
26
- q = '$lib.model.ext.addFormProp(inet:ipv4, "_test:score", (int, $lib.dict()), $lib.dict())'
26
+ q = '$lib.model.ext.addFormProp(inet:ipv4, "_test:score", (int, ({})), ({}))'
27
27
  await core.callStorm(q)
28
28
 
29
29
  async with core.getLocalProxy() as proxy: