synapse 2.154.1__py311-none-any.whl → 2.156.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 (74) hide show
  1. synapse/cmds/cortex.py +2 -14
  2. synapse/common.py +13 -36
  3. synapse/cortex.py +15 -508
  4. synapse/lib/ast.py +215 -22
  5. synapse/lib/cell.py +35 -8
  6. synapse/lib/certdir.py +11 -0
  7. synapse/lib/cmdr.py +0 -5
  8. synapse/lib/gis.py +2 -2
  9. synapse/lib/httpapi.py +14 -43
  10. synapse/lib/layer.py +64 -201
  11. synapse/lib/lmdbslab.py +11 -0
  12. synapse/lib/node.py +1 -3
  13. synapse/lib/parser.py +10 -0
  14. synapse/lib/slabseqn.py +2 -1
  15. synapse/lib/snap.py +121 -21
  16. synapse/lib/spooled.py +9 -0
  17. synapse/lib/storm.lark +23 -6
  18. synapse/lib/storm.py +16 -339
  19. synapse/lib/storm_format.py +5 -0
  20. synapse/lib/stormhttp.py +10 -1
  21. synapse/lib/stormlib/gen.py +1 -2
  22. synapse/lib/stormlib/gis.py +41 -0
  23. synapse/lib/stormlib/graph.py +2 -1
  24. synapse/lib/stormlib/stats.py +21 -2
  25. synapse/lib/stormlib/storm.py +16 -1
  26. synapse/lib/stormtypes.py +244 -16
  27. synapse/lib/types.py +16 -2
  28. synapse/lib/version.py +2 -2
  29. synapse/lib/view.py +118 -25
  30. synapse/models/base.py +2 -2
  31. synapse/models/inet.py +60 -30
  32. synapse/models/infotech.py +130 -8
  33. synapse/models/orgs.py +3 -0
  34. synapse/models/proj.py +3 -0
  35. synapse/models/risk.py +24 -6
  36. synapse/models/syn.py +0 -38
  37. synapse/tests/test_cmds_cortex.py +1 -1
  38. synapse/tests/test_cortex.py +70 -338
  39. synapse/tests/test_lib_agenda.py +19 -54
  40. synapse/tests/test_lib_aha.py +97 -0
  41. synapse/tests/test_lib_ast.py +596 -0
  42. synapse/tests/test_lib_grammar.py +30 -10
  43. synapse/tests/test_lib_httpapi.py +33 -49
  44. synapse/tests/test_lib_layer.py +19 -234
  45. synapse/tests/test_lib_lmdbslab.py +22 -0
  46. synapse/tests/test_lib_snap.py +9 -0
  47. synapse/tests/test_lib_spooled.py +4 -0
  48. synapse/tests/test_lib_storm.py +16 -309
  49. synapse/tests/test_lib_stormlib_gis.py +21 -0
  50. synapse/tests/test_lib_stormlib_stats.py +107 -20
  51. synapse/tests/test_lib_stormlib_storm.py +25 -0
  52. synapse/tests/test_lib_stormtypes.py +253 -8
  53. synapse/tests/test_lib_types.py +40 -0
  54. synapse/tests/test_lib_view.py +6 -13
  55. synapse/tests/test_model_base.py +1 -1
  56. synapse/tests/test_model_inet.py +15 -0
  57. synapse/tests/test_model_infotech.py +110 -0
  58. synapse/tests/test_model_orgs.py +10 -0
  59. synapse/tests/test_model_person.py +0 -3
  60. synapse/tests/test_model_proj.py +2 -1
  61. synapse/tests/test_model_risk.py +24 -0
  62. synapse/tests/test_model_syn.py +20 -34
  63. synapse/tests/test_tools_csvtool.py +2 -1
  64. synapse/tests/test_tools_feed.py +4 -30
  65. synapse/tools/csvtool.py +2 -1
  66. {synapse-2.154.1.dist-info → synapse-2.156.0.dist-info}/METADATA +9 -9
  67. {synapse-2.154.1.dist-info → synapse-2.156.0.dist-info}/RECORD +70 -72
  68. {synapse-2.154.1.dist-info → synapse-2.156.0.dist-info}/WHEEL +1 -1
  69. synapse/cmds/cron.py +0 -726
  70. synapse/cmds/trigger.py +0 -319
  71. synapse/tests/test_cmds_cron.py +0 -453
  72. synapse/tests/test_cmds_trigger.py +0 -176
  73. {synapse-2.154.1.dist-info → synapse-2.156.0.dist-info}/LICENSE +0 -0
  74. {synapse-2.154.1.dist-info → synapse-2.156.0.dist-info}/top_level.txt +0 -0
@@ -937,14 +937,6 @@ class CortexTest(s_t_utils.SynTest):
937
937
  return($list.size())
938
938
  '''))
939
939
 
940
- # check that edge node edits dont bork up legacy splice generation
941
- nodeedits = [(ipv4.buid, 'inet:ipv4', (
942
- (s_layer.EDIT_EDGE_ADD, (), ()),
943
- (s_layer.EDIT_EDGE_DEL, (), ()),
944
- ))]
945
-
946
- self.eq((), await alist(core.view.layers[0].makeSplices(0, nodeedits, {})))
947
-
948
940
  # Run multiple nodes through edge creation/deletion ( test coverage for perm caching )
949
941
  await core.nodes('inet:ipv4 [ <(test)+ { meta:source:name=test }]')
950
942
  self.len(2, await core.nodes('meta:source:name=test -(test)> *'))
@@ -1799,45 +1791,41 @@ class CortexTest(s_t_utils.SynTest):
1799
1791
 
1800
1792
  async with self.getTestCore(dirn=dirn) as core:
1801
1793
 
1802
- async with core.getLocalProxy() as prox:
1803
-
1804
- await prox.setStormCmd(cdef0)
1794
+ await core.setStormCmd(cdef0)
1805
1795
 
1806
- nodes = await core.nodes('[ inet:asn=10 ] | testcmd0 zoinks')
1807
- self.true(nodes[0].tags.get('zoinks'))
1796
+ nodes = await core.nodes('[ inet:asn=10 ] | testcmd0 zoinks')
1797
+ self.true(nodes[0].tags.get('zoinks'))
1808
1798
 
1809
- nodes = await core.nodes('[ inet:asn=11 ] | testcmd0 zoinks --domore')
1799
+ nodes = await core.nodes('[ inet:asn=11 ] | testcmd0 zoinks --domore')
1810
1800
 
1811
- self.true(nodes[0].tags.get('haha'))
1812
- self.true(nodes[0].tags.get('zoinks'))
1801
+ self.true(nodes[0].tags.get('haha'))
1802
+ self.true(nodes[0].tags.get('zoinks'))
1813
1803
 
1814
- # test that cmdopts/cmdconf/locals dont leak
1815
- with self.raises(s_exc.NoSuchVar):
1816
- q = '[ inet:asn=11 ] | testcmd0 zoinks --domore | if ($cmdopts) {[ +#hascmdopts ]}'
1817
- nodes = await core.nodes(q)
1804
+ # test that cmdopts/cmdconf/locals dont leak
1805
+ with self.raises(s_exc.NoSuchVar):
1806
+ q = '[ inet:asn=11 ] | testcmd0 zoinks --domore | if ($cmdopts) {[ +#hascmdopts ]}'
1807
+ nodes = await core.nodes(q)
1818
1808
 
1819
- with self.raises(s_exc.NoSuchVar):
1820
- q = '[ inet:asn=11 ] | testcmd0 zoinks --domore | if ($cmdconf) {[ +#hascmdconf ]}'
1821
- nodes = await core.nodes(q)
1809
+ with self.raises(s_exc.NoSuchVar):
1810
+ q = '[ inet:asn=11 ] | testcmd0 zoinks --domore | if ($cmdconf) {[ +#hascmdconf ]}'
1811
+ nodes = await core.nodes(q)
1822
1812
 
1823
- with self.raises(s_exc.NoSuchVar):
1824
- q = '[ inet:asn=11 ] | testcmd0 zoinks --domore | if ($foo) {[ +#hasfoo ]}'
1825
- nodes = await core.nodes(q)
1813
+ with self.raises(s_exc.NoSuchVar):
1814
+ q = '[ inet:asn=11 ] | testcmd0 zoinks --domore | if ($foo) {[ +#hasfoo ]}'
1815
+ nodes = await core.nodes(q)
1826
1816
 
1827
1817
  # make sure it's still loaded...
1828
1818
  async with self.getTestCore(dirn=dirn) as core:
1829
1819
 
1830
- async with core.getLocalProxy() as prox:
1831
-
1832
- await core.nodes('[ inet:asn=30 ] | testcmd0 zoinks')
1820
+ await core.nodes('[ inet:asn=30 ] | testcmd0 zoinks')
1833
1821
 
1834
- await prox.delStormCmd('testcmd0')
1822
+ await core.delStormCmd('testcmd0')
1835
1823
 
1836
- with self.raises(s_exc.NoSuchCmd):
1837
- await prox.delStormCmd('newpcmd')
1824
+ with self.raises(s_exc.NoSuchCmd):
1825
+ await core.delStormCmd('newpcmd')
1838
1826
 
1839
- with self.raises(s_exc.NoSuchName):
1840
- await core.nodes('[ inet:asn=31 ] | testcmd0 zoinks')
1827
+ with self.raises(s_exc.NoSuchName):
1828
+ await core.nodes('[ inet:asn=31 ] | testcmd0 zoinks')
1841
1829
 
1842
1830
  async def test_base_types2(self):
1843
1831
 
@@ -2019,6 +2007,35 @@ class CortexTest(s_t_utils.SynTest):
2019
2007
  with self.raises(s_exc.NoSuchIden):
2020
2008
  await core.nodes('', opts=opts)
2021
2009
 
2010
+ # init / fini messages contain tick/tock/took/count information
2011
+ msgs = await core.stormlist('{}')
2012
+ self.len(2, msgs)
2013
+
2014
+ (ityp, info) = msgs[0]
2015
+ self.eq('init', ityp)
2016
+ self.gt(info.get('tick'), 0)
2017
+ self.gt(info.get('abstick'), 0)
2018
+ self.eq(info.get('text'), '{}')
2019
+ self.eq(info.get('hash'), '99914b932bd37a50b983c5e7c90ae93b')
2020
+
2021
+ (ftyp, fnfo) = msgs[1]
2022
+ self.eq('fini', ftyp)
2023
+ self.eq(fnfo.get('count'), 0)
2024
+ took = fnfo.get('took')
2025
+ self.ge(took, 0)
2026
+ self.ge(fnfo.get('tock'), info.get('tick'))
2027
+ self.ge(fnfo.get('abstock'), info.get('abstick'))
2028
+ self.eq(took, fnfo.get('tock') - info.get('tick'))
2029
+ self.eq(took, fnfo.get('abstock') - info.get('abstick'))
2030
+
2031
+ # count = 2
2032
+ msgs = await core.stormlist('test:comp=(10, haha) test:str="foo bar" ')
2033
+ self.len(4, msgs)
2034
+
2035
+ (ftyp, fnfo) = msgs[-1]
2036
+ self.eq('fini', ftyp)
2037
+ self.eq(fnfo.get('count'), 2)
2038
+
2022
2039
  # Test and/or/not
2023
2040
  await core.nodes('[test:comp=(1, test) +#meep.morp +#bleep.blorp +#cond]')
2024
2041
  await core.nodes('[test:comp=(2, test) +#meep.morp +#bleep.zlorp +#cond]')
@@ -2445,6 +2462,13 @@ class CortexTest(s_t_utils.SynTest):
2445
2462
  with self.raises(s_exc.NoSuchForm) as cm:
2446
2463
  await core.nodes('.created <- test:newp')
2447
2464
 
2465
+ with self.raises(s_exc.StormRuntimeError) as cm:
2466
+ await core.nodes('test:str <- test:str')
2467
+
2468
+ mesg = 'Pivot in from a specific form cannot be used with nodes of type test:str'
2469
+ self.eq(cm.exception.get('mesg'), mesg)
2470
+ self.eq(cm.exception.get('name'), 'test:str')
2471
+
2448
2472
  # Setup a propvalu pivot where the secondary prop may fail to norm
2449
2473
  # to the destination prop for some of the inbound nodes.
2450
2474
  await wcore.nodes('[ test:comp=(127,newp) ] [test:comp=(127,127)]')
@@ -3094,6 +3118,7 @@ class CortexBasicTest(s_t_utils.SynTest):
3094
3118
  self.eq(corever, s_version.version)
3095
3119
  self.eq(corever, cellver)
3096
3120
 
3121
+ # NOTE: addNode / addNodes are deprecated in 3.0.0
3097
3122
  nodes = ((('inet:user', 'visi'), {}),)
3098
3123
 
3099
3124
  nodes = await alist(proxy.addNodes(nodes))
@@ -3101,24 +3126,6 @@ class CortexBasicTest(s_t_utils.SynTest):
3101
3126
 
3102
3127
  node = await proxy.addNode('test:str', 'foo')
3103
3128
 
3104
- pack = await proxy.addNodeTag(node[1].get('iden'), '#foo.bar')
3105
- self.eq(pack[1]['tags'].get('foo.bar'), (None, None))
3106
-
3107
- pack = await proxy.setNodeProp(node[1].get('iden'), 'tick', '2015')
3108
- self.eq(pack[1]['props'].get('tick'), 1420070400000)
3109
-
3110
- self.eq(1, await proxy.count('test:str#foo.bar'))
3111
- self.eq(1, await proxy.count('test:str:tick=2015'))
3112
-
3113
- pack = await proxy.delNodeProp(node[1].get('iden'), 'tick')
3114
- self.none(pack[1]['props'].get('tick'))
3115
-
3116
- iden = s_common.ehex(s_common.buid('newp'))
3117
- await self.asyncraises(s_exc.NoSuchIden, proxy.delNodeProp(iden, 'tick'))
3118
-
3119
- await proxy.delNodeTag(node[1].get('iden'), '#foo.bar')
3120
- self.eq(0, await proxy.count('test:str#foo.bar'))
3121
-
3122
3129
  opts = {'ndefs': [('inet:user', 'visi')]}
3123
3130
 
3124
3131
  msgs = await proxy.storm('', opts=opts).list()
@@ -3138,9 +3145,7 @@ class CortexBasicTest(s_t_utils.SynTest):
3138
3145
  ret = await proxy.getFeedFuncs()
3139
3146
  resp = {rec.get('name'): rec for rec in ret}
3140
3147
  self.isin('com.test.record', resp)
3141
- self.isin('syn.splice', resp)
3142
3148
  self.isin('syn.nodes', resp)
3143
- self.isin('syn.nodeedits', resp)
3144
3149
  rec = resp.get('syn.nodes')
3145
3150
  self.eq(rec.get('name'), 'syn.nodes')
3146
3151
  self.eq(rec.get('desc'), 'Add nodes to the Cortex via the packed node format.')
@@ -3736,7 +3741,7 @@ class CortexBasicTest(s_t_utils.SynTest):
3736
3741
 
3737
3742
  'degrees': 2,
3738
3743
 
3739
- 'pivots': ['<- meta:seen <- meta:source'],
3744
+ 'pivots': [],
3740
3745
 
3741
3746
  'filters': ['-#nope'],
3742
3747
 
@@ -3856,7 +3861,7 @@ class CortexBasicTest(s_t_utils.SynTest):
3856
3861
  inet:fqdn | graph
3857
3862
  --degrees 2
3858
3863
  --filter { -#nope }
3859
- --pivot { <- meta:seen <- meta:source }
3864
+ --pivot {}
3860
3865
  --form-pivot inet:fqdn {<- * | limit 20}
3861
3866
  --form-pivot inet:fqdn {-> * | limit 20}
3862
3867
  --form-filter inet:fqdn {-inet:fqdn:issuffix=1}
@@ -4416,46 +4421,6 @@ class CortexBasicTest(s_t_utils.SynTest):
4416
4421
 
4417
4422
  self.len(0, await core.nodes('test:cycle0=foo | delnode --force', opts=opts))
4418
4423
 
4419
- async def test_cortex_cell_splices(self):
4420
-
4421
- async with self.getTestCore() as core:
4422
-
4423
- async with core.getLocalProxy() as prox:
4424
- # TestModule creates one node and 3 splices
4425
- await self.agenlen(3, prox.splices((0, 0, 0), 1000))
4426
-
4427
- await alist(prox.eval('[ test:str=foo ]'))
4428
-
4429
- splicelist = await alist(prox.splices((0, 0, 0), 1000))
4430
- splicecount = len(splicelist)
4431
- self.ge(splicecount, 3)
4432
-
4433
- # should get the same splices in reverse order
4434
- splicelist.reverse()
4435
- self.eq(await alist(prox.splicesBack(splicelist[0][0], 1000)), splicelist)
4436
- self.eq(await alist(prox.splicesBack(splicelist[0][0], 3)), splicelist[:3])
4437
-
4438
- self.eq(await alist(prox.spliceHistory()), [s[1] for s in splicelist])
4439
-
4440
- visi = await prox.addUser('visi')
4441
- await prox.setUserPasswd(visi['iden'], 'secret')
4442
-
4443
- await prox.addUserRule(visi['iden'], (True, ('node', 'add')))
4444
- await prox.addUserRule(visi['iden'], (True, ('prop', 'set')))
4445
-
4446
- async with core.getLocalProxy(user='visi') as asvisi:
4447
-
4448
- # normal user can't user splicesBack
4449
- await self.agenraises(s_exc.AuthDeny, asvisi.splicesBack((1000, 0, 0), 1000))
4450
-
4451
- # make sure a normal user only gets their own splices
4452
- await alist(asvisi.eval('[ test:str=bar ]'))
4453
- await self.agenlen(2, asvisi.spliceHistory())
4454
-
4455
- # should get all splices now as an admin
4456
- await prox.setUserAdmin(visi['iden'], True)
4457
- await self.agenlen(splicecount + 2, asvisi.spliceHistory())
4458
-
4459
4424
  async def test_node_repr(self):
4460
4425
 
4461
4426
  async with self.getTestCore() as core:
@@ -4554,12 +4519,13 @@ class CortexBasicTest(s_t_utils.SynTest):
4554
4519
  self.len(2, await core.nodes('test:str'))
4555
4520
 
4556
4521
  layr = core.getLayer()
4557
- await self.agenlen(0, layr.splices())
4558
- await self.agenlen(0, layr.splicesBack())
4559
- await self.agenlen(0, layr.syncNodeEdits(0))
4560
- self.eq(0, await layr.getEditIndx())
4522
+ await self.agenlen(0, layr.syncNodeEdits(0, wait=False))
4523
+ await self.agenlen(0, layr.syncNodeEdits2(0, wait=False))
4524
+ # We can still generate synthetic edits though
4525
+ ndedits = await alist(layr.iterLayerNodeEdits())
4526
+ self.gt(len(ndedits), 0)
4561
4527
 
4562
- self.nn(await core.stat())
4528
+ self.eq(0, await layr.getEditIndx())
4563
4529
 
4564
4530
  async def test_cortex_layer_settings(self):
4565
4531
  '''
@@ -4753,181 +4719,6 @@ class CortexBasicTest(s_t_utils.SynTest):
4753
4719
  q = '[test:deprform=dform :deprprop=(1, 2)]'
4754
4720
  await core1.nodes(q, opts={'view': view2_iden})
4755
4721
 
4756
- async def test_feed_syn_splice(self):
4757
-
4758
- async with self.getTestCoreAndProxy() as (core, prox):
4759
-
4760
- mesg = ('node:add', {'ndef': ('test:str', 'foo')})
4761
- await core.addFeedData('syn.splice', [mesg])
4762
-
4763
- async with await core.snap() as snap:
4764
- node = await snap.getNodeByNdef(('test:str', 'foo'))
4765
- self.nn(node)
4766
-
4767
- # test coreapi addFeedData
4768
- mesg = ('node:add', {'ndef': ('test:str', 'foobar')})
4769
- await prox.addFeedData('syn.splice', [mesg])
4770
-
4771
- async with await core.snap() as snap:
4772
- node = await snap.getNodeByNdef(('test:str', 'foobar'))
4773
- self.nn(node)
4774
-
4775
- mesg = ('prop:set', {'ndef': ('test:str', 'foo'), 'prop': 'tick', 'valu': 200})
4776
- await core.addFeedData('syn.splice', [mesg])
4777
-
4778
- async with await core.snap() as snap:
4779
- node = await snap.getNodeByNdef(('test:str', 'foo'))
4780
- self.eq(200, node.get('tick'))
4781
-
4782
- mesg = ('prop:del', {'ndef': ('test:str', 'foo'), 'prop': 'tick'})
4783
- await core.addFeedData('syn.splice', [mesg])
4784
-
4785
- async with await core.snap() as snap:
4786
- node = await snap.getNodeByNdef(('test:str', 'foo'))
4787
- self.none(node.get('tick'))
4788
-
4789
- mesg = ('tag:add', {'ndef': ('test:str', 'foo'), 'tag': 'bar', 'valu': (200, 300)})
4790
- await core.addFeedData('syn.splice', [mesg])
4791
-
4792
- async with await core.snap() as snap:
4793
- node = await snap.getNodeByNdef(('test:str', 'foo'))
4794
- self.eq((200, 300), node.getTag('bar'))
4795
-
4796
- mesg = ('tag:del', {'ndef': ('test:str', 'foo'), 'tag': 'bar'})
4797
- await core.addFeedData('syn.splice', [mesg])
4798
-
4799
- async with await core.snap() as snap:
4800
- node = await snap.getNodeByNdef(('test:str', 'foo'))
4801
- self.none(node.getTag('bar'))
4802
-
4803
- await core.addTagProp('score', ('int', {}), {})
4804
- splice = ('tag:prop:set', {'ndef': ('test:str', 'foo'), 'tag': 'lol', 'prop': 'score', 'valu': 100,
4805
- 'curv': None})
4806
- await core.addFeedData('syn.splice', [splice])
4807
-
4808
- self.len(1, await core.nodes('#lol:score=100'))
4809
-
4810
- splice = ('tag:prop:del', {'ndef': ('test:str', 'foo'), 'tag': 'lol', 'prop': 'score', 'valu': 100})
4811
- await core.addFeedData('syn.splice', [splice])
4812
-
4813
- self.len(0, await core.nodes('#lol:score=100'))
4814
-
4815
- mesg = ('node:del', {'ndef': ('test:str', 'foo')})
4816
- await core.addFeedData('syn.splice', [mesg])
4817
-
4818
- async with await core.snap() as snap:
4819
- node = await snap.getNodeByNdef(('test:str', 'foo'))
4820
- self.none(node)
4821
-
4822
- # test feeding to a different view
4823
- vdef2 = await core.view.fork()
4824
- view2_iden = vdef2.get('iden')
4825
- view2 = core.getView(view2_iden)
4826
-
4827
- mesg = ('node:add', {'ndef': ('test:str', 'bar')})
4828
- await core.addFeedData('syn.splice', [mesg], viewiden=view2_iden)
4829
-
4830
- async with await core.snap(view=view2) as snap:
4831
- node = await snap.getNodeByNdef(('test:str', 'bar'))
4832
- self.nn(node)
4833
-
4834
- async with await core.snap() as snap:
4835
- node = await snap.getNodeByNdef(('test:str', 'bar'))
4836
- self.none(node)
4837
-
4838
- # test coreapi addFeedData to a different view
4839
- mesg = ('node:add', {'ndef': ('test:str', 'baz')})
4840
- await prox.addFeedData('syn.splice', [mesg], viewiden=view2_iden)
4841
-
4842
- async with await core.snap(view=view2) as snap:
4843
- node = await snap.getNodeByNdef(('test:str', 'baz'))
4844
- self.nn(node)
4845
-
4846
- async with await core.snap() as snap:
4847
- node = await snap.getNodeByNdef(('test:str', 'baz'))
4848
- self.none(node)
4849
-
4850
- # sad paths
4851
- await self.asyncraises(s_exc.NoSuchView, core.addFeedData('syn.splice', [mesg], viewiden='badiden'))
4852
- await self.asyncraises(s_exc.NoSuchView, prox.addFeedData('syn.splice', [mesg], viewiden='badiden'))
4853
-
4854
- async def test_feed_syn_nodeedits(self):
4855
-
4856
- async with self.getTestCoreAndProxy() as (core0, prox0):
4857
-
4858
- nodelist0 = []
4859
- nodelist0.extend(await core0.nodes('[ test:str=foo ]'))
4860
- nodelist0.extend(await core0.nodes('[ inet:ipv4=1.2.3.4 .seen=(2012,2014) +#foo.bar=(2012, 2014) ]'))
4861
- nodelist0.extend(await core0.nodes('[ test:int=42 ]'))
4862
- await core0.nodes('test:int=42 | delnode')
4863
-
4864
- with self.raises(s_exc.NoSuchLayer):
4865
- async for _, nodeedits in prox0.syncLayerNodeEdits(0, layriden='asdf', wait=False):
4866
- pass
4867
-
4868
- with self.raises(s_exc.NoSuchLayer):
4869
- async for _, nodeedits in core0.syncLayerNodeEdits('asdf', 0, wait=False):
4870
- pass
4871
-
4872
- editlist = []
4873
- async for _, nodeedits in prox0.syncLayerNodeEdits(0, wait=False):
4874
- editlist.append(nodeedits)
4875
-
4876
- deledit = editlist.pop(len(editlist) - 1)
4877
-
4878
- async with self.getTestCoreAndProxy() as (core1, prox1):
4879
-
4880
- await prox1.addFeedData('syn.nodeedits', editlist)
4881
-
4882
- nodelist1 = []
4883
- nodelist1.extend(await core1.nodes('test:str'))
4884
- nodelist1.extend(await core1.nodes('inet:ipv4'))
4885
- nodelist1.extend(await core1.nodes('test:int'))
4886
-
4887
- nodelist0 = [node.pack() for node in nodelist0]
4888
- nodelist1 = [node.pack() for node in nodelist1]
4889
- self.eq(nodelist0, nodelist1)
4890
-
4891
- await core1.nodes('trigger.add node:del --form test:int --query {[test:int=7]}')
4892
-
4893
- self.len(1, await core1.nodes('test:int=42'))
4894
-
4895
- await prox1.addFeedData('syn.nodeedits', [deledit])
4896
-
4897
- self.len(0, await core1.nodes('test:int=42'))
4898
- self.len(1, await core1.nodes('test:int=7'))
4899
-
4900
- # Try a nodeedits we might get from cmdr
4901
- cmdrnodeedits = s_common.jsonsafe_nodeedits(editlist[1])
4902
- await core0.nodes('test:str=foo | delnode')
4903
-
4904
- await prox1.addFeedData('syn.nodeedits', [cmdrnodeedits])
4905
- self.len(1, await core1.nodes('test:str'))
4906
-
4907
- async def test_stat(self):
4908
-
4909
- async with self.getTestCoreAndProxy() as (realcore, core):
4910
- coreiden = realcore.iden
4911
- ostat = await core.stat()
4912
- self.eq(ostat.get('iden'), coreiden)
4913
- self.isin('layer', ostat)
4914
- self.len(1, await realcore.nodes('[test:str=123 :tick=2018]'))
4915
- nstat = await core.stat()
4916
-
4917
- counts = nstat.get('formcounts')
4918
- self.eq(counts.get('test:str'), 1)
4919
-
4920
- async def test_stat_lock(self):
4921
- self.thisHostMust(hasmemlocking=True)
4922
- conf = {'layers:lockmemory': True}
4923
- async with self.getTestCoreAndProxy(conf=conf) as (realcore, core):
4924
- slab = realcore.view.layers[0].layrslab
4925
- self.true(await asyncio.wait_for(slab.lockdoneevent.wait(), 8))
4926
-
4927
- nstat = await core.stat()
4928
- layr = nstat.get('layer')
4929
- self.gt(layr.get('lock_goal'), 0)
4930
-
4931
4722
  async def test_storm_sub_query(self):
4932
4723
 
4933
4724
  async with self.getTestCore() as core:
@@ -5088,6 +4879,9 @@ class CortexBasicTest(s_t_utils.SynTest):
5088
4879
  self.nn(node.getTag('known'))
5089
4880
  self.none(node.getTag('unknown'))
5090
4881
 
4882
+ q = '$valu={[test:str=foo]} switch $valu { foo: {test:str=foo return($node.value()) } }'
4883
+ self.eq('foo', await core.callStorm(q))
4884
+
5091
4885
  async def test_storm_tagvar(self):
5092
4886
 
5093
4887
  async with self.getTestCore() as core:
@@ -6627,35 +6421,6 @@ class CortexBasicTest(s_t_utils.SynTest):
6627
6421
  self.eq(view, core.getView(core.iden))
6628
6422
  self.none(core.getView('xxx'))
6629
6423
 
6630
- async def test_cortex_cronjob_perms(self):
6631
- async with self.getTestCore() as realcore:
6632
- async with realcore.getLocalProxy() as core:
6633
- fred = await core.addUser('fred')
6634
- await core.setUserPasswd(fred['iden'], 'secret')
6635
- cdef = {'storm': '[test:str=foo]', 'reqs': {'dayofmonth': 1},
6636
- 'incunit': None, 'incvals': None}
6637
- adef = await core.addCronJob(cdef)
6638
- iden = adef.get('iden')
6639
-
6640
- async with realcore.getLocalProxy(user='fred') as core:
6641
- # Rando user can't make cron jobs
6642
- cdef = {'storm': '[test:int=1]', 'reqs': {'month': 1},
6643
- 'incunit': None, 'incvals': None}
6644
- await self.asyncraises(s_exc.AuthDeny, core.addCronJob(cdef))
6645
-
6646
- # Rando user can't mod cron jobs
6647
- await self.asyncraises(s_exc.AuthDeny, core.updateCronJob(iden, '[test:str=bar]'))
6648
-
6649
- # Rando user doesn't see any cron jobs
6650
- self.len(0, await core.listCronJobs())
6651
-
6652
- # Rando user can't delete cron jobs
6653
- await self.asyncraises(s_exc.AuthDeny, core.delCronJob(iden))
6654
-
6655
- # Rando user can't enable/disable cron jobs
6656
- await self.asyncraises(s_exc.AuthDeny, core.enableCronJob(iden))
6657
- await self.asyncraises(s_exc.AuthDeny, core.disableCronJob(iden))
6658
-
6659
6424
  async def test_cortex_cron_deluser(self):
6660
6425
 
6661
6426
  async with self.getTestCore() as core:
@@ -6731,39 +6496,6 @@ class CortexBasicTest(s_t_utils.SynTest):
6731
6496
  await self.asyncraises(s_exc.AuthDeny, prox.enableMigrationMode())
6732
6497
  await self.asyncraises(s_exc.AuthDeny, prox.disableMigrationMode())
6733
6498
 
6734
- async def test_cortex_watch(self):
6735
-
6736
- async with self.getTestCore() as core:
6737
-
6738
- async with core.getLocalProxy() as prox:
6739
-
6740
- async def nodes():
6741
- await asyncio.sleep(0.1) # due to telepath proxy causing task switch
6742
- await core.nodes('[ test:int=10 +#foo.bar +#baz.faz ]')
6743
- await core.nodes('test:int=10 [ -#foo.bar -#baz.faz ]')
6744
-
6745
- task = core.schedCoro(nodes())
6746
-
6747
- data = []
6748
- async for mesg in prox.watch({'tags': ['foo.bar', 'baz.*']}):
6749
- data.append(mesg)
6750
- if len(data) == 4:
6751
- break
6752
-
6753
- await asyncio.wait_for(task, timeout=1)
6754
-
6755
- self.eq(data[0][0], 'tag:add')
6756
- self.eq(data[0][1]['tag'], 'foo.bar')
6757
-
6758
- self.eq(data[1][0], 'tag:add')
6759
- self.eq(data[1][1]['tag'], 'baz.faz')
6760
-
6761
- self.eq(data[2][0], 'tag:del')
6762
- self.eq(data[2][1]['tag'], 'foo.bar')
6763
-
6764
- self.eq(data[3][0], 'tag:del')
6765
- self.eq(data[3][1]['tag'], 'baz.faz')
6766
-
6767
6499
  async def test_cortex_behold(self):
6768
6500
  async with self.getTestCore() as core:
6769
6501
  async with core.getLocalProxy() as prox:
@@ -496,51 +496,6 @@ class AgendaTest(s_t_utils.SynTest):
496
496
 
497
497
  self.len(0, [appt for (iden, appt) in appts if iden == badguid2])
498
498
 
499
- async def test_cron_perms(self):
500
-
501
- async with self.getTestCore() as core:
502
-
503
- visi = await core.auth.addUser('visi')
504
- newb = await core.auth.addUser('newb')
505
- async with core.getLocalProxy(user='visi') as proxy:
506
-
507
- cdef = {'storm': 'inet:ipv4', 'reqs': {'hour': 2}}
508
- with self.raises(s_exc.AuthDeny):
509
- await proxy.addCronJob(cdef)
510
-
511
- await visi.addRule((True, ('cron', 'add')))
512
- cron0 = await proxy.addCronJob(cdef)
513
- cron0_iden = cron0.get('iden')
514
-
515
- cdef = {'storm': 'inet:ipv6', 'reqs': {'hour': 2}}
516
- cron1 = await proxy.addCronJob(cdef)
517
- cron1_iden = cron1.get('iden')
518
-
519
- await proxy.delCronJob(cron0_iden)
520
-
521
- cdef = {'storm': '[test:str=foo]', 'reqs': {'now': True},
522
- 'incunit': 'month',
523
- 'incvals': 1}
524
- await self.asyncraises(s_exc.BadConfValu, proxy.addCronJob(cdef))
525
-
526
- async with core.getLocalProxy(user='newb') as proxy:
527
-
528
- with self.raises(s_exc.AuthDeny):
529
- await proxy.delCronJob(cron1_iden)
530
-
531
- self.eq(await proxy.listCronJobs(), ())
532
- await newb.addRule((True, ('cron', 'get')))
533
- self.len(1, await proxy.listCronJobs())
534
-
535
- with self.raises(s_exc.AuthDeny):
536
- await proxy.disableCronJob(cron1_iden)
537
-
538
- await newb.addRule((True, ('cron', 'set')))
539
- self.none(await proxy.disableCronJob(cron1_iden))
540
-
541
- await newb.addRule((True, ('cron', 'del')))
542
- await proxy.delCronJob(cron1_iden)
543
-
544
499
  async def test_agenda_stop(self):
545
500
 
546
501
  async with self.getTestCore() as core:
@@ -727,7 +682,8 @@ class AgendaTest(s_t_utils.SynTest):
727
682
 
728
683
  async with self.getTestCore() as core:
729
684
 
730
- derp = await core.auth.addUser('derp')
685
+ lowuser = await core.addUser('lowuser')
686
+ lowuser = lowuser.get('iden')
731
687
 
732
688
  msgs = await core.stormlist('cron.add --hourly 32 { $lib.print(woot) }')
733
689
  self.stormHasNoWarnErr(msgs)
@@ -735,14 +691,23 @@ class AgendaTest(s_t_utils.SynTest):
735
691
  cdef = await core.callStorm('for $cron in $lib.cron.list() { return($cron) }')
736
692
  self.eq(cdef['creator'], core.auth.rootuser.iden)
737
693
 
738
- opts = {'vars': {'derp': derp.iden}}
739
- cdef = await core.callStorm('for $cron in $lib.cron.list() { return($cron.set(creator, $derp)) }', opts=opts)
740
-
741
- self.eq(cdef['creator'], derp.iden)
742
-
743
- async with core.getLocalProxy(user='derp') as proxy:
744
- with self.raises(s_exc.AuthDeny):
745
- await proxy.editCronJob(cdef.get('iden'), 'creator', derp.iden)
694
+ opts = {'vars': {'lowuser': lowuser}}
695
+ cdef = await core.callStorm('for $cron in $lib.cron.list() { return($cron.set(creator, $lowuser)) }',
696
+ opts=opts)
697
+ self.eq(cdef['creator'], lowuser)
698
+
699
+ opts = {'user': lowuser, 'vars': {'iden': cdef.get('iden'), 'lowuser': lowuser}}
700
+ q = '$cron = $lib.cron.get($iden) return ( $cron.set(creator, $lowuser) )'
701
+ msgs = await core.stormlist(q, opts=opts)
702
+ # XXX FIXME - This is an odd message since the new creator does not implicitly have
703
+ # access to the cronjob that is running as them.
704
+ self.stormIsInErr('Provided iden does not match any valid authorized cron job.', msgs)
705
+
706
+ await core.addUserRule(lowuser, (True, ('cron', 'get')))
707
+ opts = {'user': lowuser, 'vars': {'iden': cdef.get('iden'), 'lowuser': lowuser}}
708
+ q = '$cron = $lib.cron.get($iden) return ( $cron.set(creator, $lowuser) )'
709
+ msgs = await core.stormlist(q, opts=opts)
710
+ self.stormIsInErr('must have permission cron.set.creator', msgs)
746
711
 
747
712
  async def test_agenda_fatal_run(self):
748
713