synapse 2.173.1__py311-none-any.whl → 2.175.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 (54) hide show
  1. synapse/axon.py +1 -1
  2. synapse/common.py +19 -5
  3. synapse/cortex.py +46 -10
  4. synapse/daemon.py +11 -12
  5. synapse/lib/agenda.py +6 -0
  6. synapse/lib/ast.py +5 -1
  7. synapse/lib/cell.py +22 -13
  8. synapse/lib/jupyter.py +21 -0
  9. synapse/lib/layer.py +124 -30
  10. synapse/lib/link.py +3 -2
  11. synapse/lib/lmdbslab.py +11 -1
  12. synapse/lib/modelrev.py +31 -1
  13. synapse/lib/modules.py +1 -0
  14. synapse/lib/msgpack.py +25 -3
  15. synapse/lib/nexus.py +26 -22
  16. synapse/lib/schemas.py +31 -0
  17. synapse/lib/snap.py +13 -0
  18. synapse/lib/storm.py +103 -86
  19. synapse/lib/stormsvc.py +30 -11
  20. synapse/lib/stormtypes.py +23 -9
  21. synapse/lib/trigger.py +0 -4
  22. synapse/lib/types.py +1 -1
  23. synapse/lib/version.py +2 -2
  24. synapse/lib/view.py +2 -0
  25. synapse/models/crypto.py +22 -0
  26. synapse/models/economic.py +23 -2
  27. synapse/models/entity.py +16 -0
  28. synapse/models/files.py +4 -1
  29. synapse/models/geopol.py +3 -0
  30. synapse/models/orgs.py +3 -4
  31. synapse/tests/test_cortex.py +13 -0
  32. synapse/tests/test_daemon.py +36 -0
  33. synapse/tests/test_lib_agenda.py +129 -1
  34. synapse/tests/test_lib_ast.py +56 -0
  35. synapse/tests/test_lib_cell.py +11 -0
  36. synapse/tests/test_lib_grammar.py +4 -0
  37. synapse/tests/test_lib_httpapi.py +1 -0
  38. synapse/tests/test_lib_lmdbslab.py +16 -1
  39. synapse/tests/test_lib_modelrev.py +86 -0
  40. synapse/tests/test_lib_msgpack.py +58 -8
  41. synapse/tests/test_lib_nexus.py +44 -1
  42. synapse/tests/test_lib_storm.py +134 -18
  43. synapse/tests/test_lib_stormsvc.py +128 -51
  44. synapse/tests/test_lib_stormtypes.py +43 -4
  45. synapse/tests/test_lib_trigger.py +23 -4
  46. synapse/tests/test_model_crypto.py +6 -0
  47. synapse/tests/test_model_economic.py +14 -1
  48. synapse/tests/test_model_geopol.py +3 -0
  49. synapse/tools/changelog.py +256 -0
  50. {synapse-2.173.1.dist-info → synapse-2.175.0.dist-info}/METADATA +1 -1
  51. {synapse-2.173.1.dist-info → synapse-2.175.0.dist-info}/RECORD +54 -52
  52. {synapse-2.173.1.dist-info → synapse-2.175.0.dist-info}/WHEEL +1 -1
  53. {synapse-2.173.1.dist-info → synapse-2.175.0.dist-info}/LICENSE +0 -0
  54. {synapse-2.173.1.dist-info → synapse-2.175.0.dist-info}/top_level.txt +0 -0
synapse/lib/storm.py CHANGED
@@ -14,6 +14,7 @@ import synapse.datamodel as s_datamodel
14
14
  import synapse.lib.ast as s_ast
15
15
  import synapse.lib.base as s_base
16
16
  import synapse.lib.chop as s_chop
17
+ import synapse.lib.coro as s_coro
17
18
  import synapse.lib.node as s_node
18
19
  import synapse.lib.snap as s_snap
19
20
  import synapse.lib.time as s_time
@@ -3491,13 +3492,18 @@ class DiffCmd(Cmd):
3491
3492
  // Lift the nodes with the tag #cno.mal.redtree added in the top layer.
3492
3493
 
3493
3494
  diff --tag cno.mal.redtree
3495
+
3496
+ // Lift nodes by multiple tags (results are uniqued)
3497
+
3498
+ diff --tag cno.mal.redtree rep.vt
3494
3499
  '''
3495
3500
  name = 'diff'
3496
3501
  readonly = True
3497
3502
 
3498
3503
  def getArgParser(self):
3499
3504
  pars = Cmd.getArgParser(self)
3500
- pars.add_argument('--tag', default=None, help='Lift only nodes with the given tag in the top layer.')
3505
+ pars.add_argument('--tag', default=None, nargs='*',
3506
+ help='Lift only nodes with the given tag (or tags) in the top layer.')
3501
3507
  pars.add_argument('--prop', default=None, help='Lift nodes with changes to the given property the top layer.')
3502
3508
  return pars
3503
3509
 
@@ -3516,10 +3522,11 @@ class DiffCmd(Cmd):
3516
3522
 
3517
3523
  if self.opts.tag:
3518
3524
 
3519
- tagname = await s_stormtypes.tostr(self.opts.tag)
3525
+ tagnames = [await s_stormtypes.tostr(tag) for tag in self.opts.tag]
3520
3526
 
3521
3527
  layr = runt.snap.view.layers[0]
3522
- async for _, buid, sode in layr.liftByTag(tagname):
3528
+
3529
+ async for _, buid, sode in layr.liftByTags(tagnames):
3523
3530
  node = await self.runt.snap._joinStorNode(buid, {layr.iden: sode})
3524
3531
  if node is not None:
3525
3532
  yield node, runt.initPath(node)
@@ -3765,73 +3772,76 @@ class MergeCmd(Cmd):
3765
3772
  def _getPropFilter(self):
3766
3773
  if self.opts.include_props:
3767
3774
 
3775
+ _include_props = set(self.opts.include_props)
3776
+
3768
3777
  def propfilter(prop):
3769
- if prop in self.opts.include_props:
3770
- return False
3771
- return True
3778
+ return prop not in _include_props
3772
3779
 
3773
3780
  return propfilter
3774
3781
 
3775
3782
  if self.opts.exclude_props:
3776
3783
 
3784
+ _exclude_props = set(self.opts.exclude_props)
3785
+
3777
3786
  def propfilter(prop):
3778
- if prop in self.opts.exclude_props:
3779
- return True
3780
- return False
3787
+ return prop in _exclude_props
3781
3788
 
3782
3789
  return propfilter
3783
3790
 
3784
3791
  return None
3785
3792
 
3786
- async def _checkNodePerms(self, node, sode, runt):
3793
+ async def _checkNodePerms(self, node, sode, runt, allows):
3787
3794
 
3788
3795
  layr0 = runt.snap.view.layers[0].iden
3789
3796
  layr1 = runt.snap.view.layers[1].iden
3790
3797
 
3791
- if sode.get('valu') is not None:
3798
+ if not allows['forms'] and sode.get('valu') is not None:
3792
3799
  runt.confirm(('node', 'del', node.form.name), gateiden=layr0)
3793
3800
  runt.confirm(('node', 'add', node.form.name), gateiden=layr1)
3794
3801
 
3795
- for name, (valu, stortype) in sode.get('props', {}).items():
3796
- prop = node.form.prop(name)
3797
- runt.confirmPropDel(prop, layriden=layr0)
3798
- runt.confirmPropSet(prop, layriden=layr1)
3802
+ if not allows['props']:
3803
+ for name in sode.get('props', {}).keys():
3804
+ prop = node.form.prop(name)
3805
+ runt.confirmPropDel(prop, layriden=layr0)
3806
+ runt.confirmPropSet(prop, layriden=layr1)
3807
+
3808
+ if not allows['tags']:
3809
+
3810
+ tags = []
3811
+ tagadds = []
3812
+ for tag, valu in sode.get('tags', {}).items():
3813
+ if valu != (None, None):
3814
+ tagadds.append(tag)
3815
+ tagperm = tuple(tag.split('.'))
3816
+ runt.confirm(('node', 'tag', 'del') + tagperm, gateiden=layr0)
3817
+ runt.confirm(('node', 'tag', 'add') + tagperm, gateiden=layr1)
3818
+ else:
3819
+ tags.append((len(tag), tag))
3820
+
3821
+ for _, tag in sorted(tags, reverse=True):
3822
+ look = tag + '.'
3823
+ if any([tagadd.startswith(look) for tagadd in tagadds]):
3824
+ continue
3799
3825
 
3800
- tags = []
3801
- tagadds = []
3802
- for tag, valu in sode.get('tags', {}).items():
3803
- if valu != (None, None):
3804
3826
  tagadds.append(tag)
3805
3827
  tagperm = tuple(tag.split('.'))
3806
3828
  runt.confirm(('node', 'tag', 'del') + tagperm, gateiden=layr0)
3807
3829
  runt.confirm(('node', 'tag', 'add') + tagperm, gateiden=layr1)
3808
- else:
3809
- tags.append((len(tag), tag))
3810
-
3811
- for _, tag in sorted(tags, reverse=True):
3812
- look = tag + '.'
3813
- if any([tagadd.startswith(look) for tagadd in tagadds]):
3814
- continue
3815
-
3816
- tagadds.append(tag)
3817
- tagperm = tuple(tag.split('.'))
3818
- runt.confirm(('node', 'tag', 'del') + tagperm, gateiden=layr0)
3819
- runt.confirm(('node', 'tag', 'add') + tagperm, gateiden=layr1)
3820
3830
 
3821
- for tag, tagdict in sode.get('tagprops', {}).items():
3822
- for prop, (valu, stortype) in tagdict.items():
3831
+ for tag in sode.get('tagprops', {}).keys():
3823
3832
  tagperm = tuple(tag.split('.'))
3824
3833
  runt.confirm(('node', 'tag', 'del') + tagperm, gateiden=layr0)
3825
3834
  runt.confirm(('node', 'tag', 'add') + tagperm, gateiden=layr1)
3826
3835
 
3827
- async for name in runt.snap.view.layers[0].iterNodeDataKeys(node.buid):
3828
- runt.confirm(('node', 'data', 'pop', name), gateiden=layr0)
3829
- runt.confirm(('node', 'data', 'set', name), gateiden=layr1)
3836
+ if not allows['ndata']:
3837
+ async for name in runt.snap.view.layers[0].iterNodeDataKeys(node.buid):
3838
+ runt.confirm(('node', 'data', 'pop', name), gateiden=layr0)
3839
+ runt.confirm(('node', 'data', 'set', name), gateiden=layr1)
3830
3840
 
3831
- async for edge in runt.snap.view.layers[0].iterNodeEdgesN1(node.buid):
3832
- verb = edge[0]
3833
- runt.confirm(('node', 'edge', 'del', verb), gateiden=layr0)
3834
- runt.confirm(('node', 'edge', 'add', verb), gateiden=layr1)
3841
+ if not allows['edges']:
3842
+ async for verb in runt.snap.view.layers[0].iterNodeEdgeVerbsN1(node.buid):
3843
+ runt.confirm(('node', 'edge', 'del', verb), gateiden=layr0)
3844
+ runt.confirm(('node', 'edge', 'add', verb), gateiden=layr1)
3835
3845
 
3836
3846
  async def execStormCmd(self, runt, genr):
3837
3847
 
@@ -3841,12 +3851,31 @@ class MergeCmd(Cmd):
3841
3851
 
3842
3852
  notags = self.opts.no_tags
3843
3853
  onlytags = self.opts.only_tags
3854
+ doapply = self.opts.apply
3844
3855
 
3845
3856
  tagfilter = self._getTagFilter()
3846
3857
  propfilter = self._getPropFilter()
3847
3858
 
3848
- layr0 = runt.snap.view.layers[0].iden
3849
- layr1 = runt.snap.view.layers[1].iden
3859
+ layr0 = runt.snap.view.layers[0]
3860
+ layr1 = runt.snap.view.layers[1]
3861
+
3862
+ doperms = doapply and not (runt.isAdmin(gateiden=layr0.iden) and runt.isAdmin(gateiden=layr1.iden))
3863
+
3864
+ if doperms:
3865
+ allows = {
3866
+ 'forms': runt.user.allowed(('node', 'del'), gateiden=layr0.iden, deepdeny=True) and
3867
+ runt.user.allowed(('node', 'add'), gateiden=layr1.iden, deepdeny=True),
3868
+ 'props': runt.user.allowed(('node', 'prop', 'del'), gateiden=layr0.iden, deepdeny=True) and
3869
+ runt.user.allowed(('node', 'prop', 'set'), gateiden=layr1.iden, deepdeny=True),
3870
+ 'tags': runt.user.allowed(('node', 'tag', 'del'), gateiden=layr0.iden, deepdeny=True) and
3871
+ runt.user.allowed(('node', 'tag', 'add'), gateiden=layr1.iden, deepdeny=True),
3872
+ 'ndata': runt.user.allowed(('node', 'data', 'pop'), gateiden=layr0.iden, deepdeny=True) and
3873
+ runt.user.allowed(('node', 'data', 'set'), gateiden=layr1.iden, deepdeny=True),
3874
+ 'edges': runt.user.allowed(('node', 'edge', 'del'), gateiden=layr0.iden, deepdeny=True) and
3875
+ runt.user.allowed(('node', 'edge', 'add'), gateiden=layr1.iden, deepdeny=True),
3876
+ }
3877
+
3878
+ doperms = not all(allows.values())
3850
3879
 
3851
3880
  if self.opts.diff:
3852
3881
 
@@ -3854,7 +3883,7 @@ class MergeCmd(Cmd):
3854
3883
  yield node, path
3855
3884
 
3856
3885
  async def diffgenr():
3857
- async for buid, sode in runt.snap.view.layers[0].getStorNodes():
3886
+ async for buid, sode in layr0.getStorNodes():
3858
3887
  node = await runt.snap.getNodeByBuid(buid)
3859
3888
  if node is not None:
3860
3889
  yield node, runt.initPath(node)
@@ -3873,33 +3902,19 @@ class MergeCmd(Cmd):
3873
3902
  sodes = await node.getStorNodes()
3874
3903
  sode = sodes[0]
3875
3904
 
3876
- if self.opts.apply:
3905
+ if doapply:
3877
3906
  editor = s_snap.SnapEditor(snap)
3878
3907
 
3879
3908
  subs = []
3880
3909
 
3881
- async def sync():
3882
-
3883
- if not self.opts.apply:
3884
- subs.clear()
3885
- return
3886
-
3887
- addedits = editor.getNodeEdits()
3888
- if addedits:
3889
- await runt.snap.view.parent.storNodeEdits(addedits, meta=meta)
3890
-
3891
- if subs:
3892
- subedits = [(node.buid, node.form.name, subs)]
3893
- await runt.snap.view.storNodeEdits(subedits, meta=meta)
3894
- subs.clear()
3895
-
3896
3910
  # check all node perms first
3897
- if self.opts.apply:
3898
- await self._checkNodePerms(node, sode, runt)
3911
+ if doperms:
3912
+ await self._checkNodePerms(node, sode, runt, allows)
3899
3913
 
3900
3914
  form = node.form.name
3901
3915
  if form == 'syn:tag':
3902
3916
  if notags:
3917
+ await asyncio.sleep(0)
3903
3918
  continue
3904
3919
  else:
3905
3920
  # avoid merging a tag if the node won't exist below us
@@ -3908,6 +3923,7 @@ class MergeCmd(Cmd):
3908
3923
  if undr.get('valu') is not None:
3909
3924
  break
3910
3925
  else:
3926
+ await asyncio.sleep(0)
3911
3927
  continue
3912
3928
 
3913
3929
  protonode = None
@@ -3916,23 +3932,24 @@ class MergeCmd(Cmd):
3916
3932
  valu = sode.get('valu')
3917
3933
  if valu is not None:
3918
3934
 
3919
- if tagfilter and form == 'syn:tag' and tagfilter(valu[0]):
3935
+ if tagfilter is not None and form == 'syn:tag' and tagfilter(valu[0]):
3936
+ await asyncio.sleep(0)
3920
3937
  continue
3921
3938
 
3922
- if not self.opts.apply:
3939
+ if not doapply:
3923
3940
  valurepr = node.form.type.repr(valu[0])
3924
3941
  await runt.printf(f'{nodeiden} {form} = {valurepr}')
3925
3942
  else:
3926
3943
  delnode = True
3927
3944
  protonode = await editor.addNode(form, valu[0])
3928
3945
 
3929
- elif self.opts.apply:
3946
+ elif doapply:
3930
3947
  protonode = await editor.addNode(form, node.ndef[1], norminfo={})
3931
3948
 
3932
3949
  for name, (valu, stortype) in sode.get('props', {}).items():
3933
3950
 
3934
3951
  prop = node.form.prop(name)
3935
- if propfilter:
3952
+ if propfilter is not None:
3936
3953
  if name[0] == '.':
3937
3954
  if propfilter(name):
3938
3955
  continue
@@ -3942,7 +3959,7 @@ class MergeCmd(Cmd):
3942
3959
 
3943
3960
  if prop.info.get('ro'):
3944
3961
  if name == '.created':
3945
- if self.opts.apply:
3962
+ if doapply:
3946
3963
  protonode.props['.created'] = valu
3947
3964
  subs.append((s_layer.EDIT_PROP_DEL, (name, valu, stortype), ()))
3948
3965
  continue
@@ -3952,8 +3969,8 @@ class MergeCmd(Cmd):
3952
3969
  props = undr.get('props')
3953
3970
  if props is not None:
3954
3971
  curv = props.get(name)
3955
- if curv is not None and curv[0] != valu:
3956
- isset = True
3972
+ if curv is not None:
3973
+ isset = curv[0] != valu
3957
3974
  break
3958
3975
 
3959
3976
  if isset:
@@ -3963,24 +3980,23 @@ class MergeCmd(Cmd):
3963
3980
  await runt.snap.warn(mesg)
3964
3981
  continue
3965
3982
 
3966
- if not self.opts.apply:
3983
+ if not doapply:
3967
3984
  valurepr = prop.type.repr(valu)
3968
3985
  await runt.printf(f'{nodeiden} {form}:{name} = {valurepr}')
3969
3986
  else:
3970
3987
  await protonode.set(name, valu)
3971
3988
  subs.append((s_layer.EDIT_PROP_DEL, (name, valu, stortype), ()))
3972
3989
 
3973
- if self.opts.apply and protonode is None:
3990
+ if doapply and protonode is None:
3974
3991
  protonode = await editor.addNode(form, node.ndef[1], norminfo={})
3975
3992
 
3976
3993
  if not notags:
3977
3994
  for tag, valu in sode.get('tags', {}).items():
3978
3995
 
3979
- if tagfilter and tagfilter(tag):
3996
+ if tagfilter is not None and tagfilter(tag):
3980
3997
  continue
3981
3998
 
3982
- tagperm = tuple(tag.split('.'))
3983
- if not self.opts.apply:
3999
+ if not doapply:
3984
4000
  valurepr = ''
3985
4001
  if valu != (None, None):
3986
4002
  tagrepr = runt.model.type('ival').repr(valu)
@@ -3992,12 +4008,11 @@ class MergeCmd(Cmd):
3992
4008
 
3993
4009
  for tag, tagdict in sode.get('tagprops', {}).items():
3994
4010
 
3995
- if tagfilter and tagfilter(tag):
4011
+ if tagfilter is not None and tagfilter(tag):
3996
4012
  continue
3997
4013
 
3998
4014
  for prop, (valu, stortype) in tagdict.items():
3999
- tagperm = tuple(tag.split('.'))
4000
- if not self.opts.apply:
4015
+ if not doapply:
4001
4016
  valurepr = repr(valu)
4002
4017
  await runt.printf(f'{nodeiden} {form}#{tag}:{prop} = {valurepr}')
4003
4018
  else:
@@ -4006,31 +4021,33 @@ class MergeCmd(Cmd):
4006
4021
 
4007
4022
  if not onlytags or form == 'syn:tag':
4008
4023
 
4009
- layr = runt.snap.view.layers[0]
4010
- async for name, valu in layr.iterNodeData(node.buid):
4011
- if not self.opts.apply:
4024
+ async for name, valu in s_coro.pause(layr0.iterNodeData(node.buid)):
4025
+ if not doapply:
4012
4026
  valurepr = repr(valu)
4013
4027
  await runt.printf(f'{nodeiden} {form} DATA {name} = {valurepr}')
4014
4028
  else:
4015
4029
  await protonode.setData(name, valu)
4016
4030
  subs.append((s_layer.EDIT_NODEDATA_DEL, (name, valu), ()))
4017
- if len(subs) >= 1000:
4018
- await asyncio.sleep(0)
4019
4031
 
4020
- async for edge in layr.iterNodeEdgesN1(node.buid):
4032
+ async for edge in s_coro.pause(layr0.iterNodeEdgesN1(node.buid)):
4021
4033
  name, dest = edge
4022
- if not self.opts.apply:
4034
+ if not doapply:
4023
4035
  await runt.printf(f'{nodeiden} {form} +({name})> {dest}')
4024
4036
  else:
4025
4037
  await protonode.addEdge(name, dest)
4026
4038
  subs.append((s_layer.EDIT_EDGE_DEL, edge, ()))
4027
- if len(subs) >= 1000:
4028
- await asyncio.sleep(0)
4029
4039
 
4030
4040
  if delnode:
4031
4041
  subs.append((s_layer.EDIT_NODE_DEL, valu, ()))
4032
4042
 
4033
- await sync()
4043
+ if doapply:
4044
+ addedits = editor.getNodeEdits()
4045
+ if addedits:
4046
+ await runt.snap.view.parent.storNodeEdits(addedits, meta=meta)
4047
+
4048
+ if subs:
4049
+ subedits = [(node.buid, node.form.name, subs)]
4050
+ await runt.snap.view.storNodeEdits(subedits, meta=meta)
4034
4051
 
4035
4052
  runt.snap.clearCachedNode(node.buid)
4036
4053
  yield await runt.snap.getNodeByBuid(node.buid), path
synapse/lib/stormsvc.py CHANGED
@@ -4,6 +4,7 @@ import logging
4
4
  import synapse.telepath as s_telepath
5
5
 
6
6
  import synapse.lib.base as s_base
7
+ import synapse.lib.hashitem as s_hashitem
7
8
 
8
9
  logger = logging.getLogger(__name__)
9
10
 
@@ -139,32 +140,50 @@ class StormSvcClient(s_base.Base):
139
140
  self.core.svcsbysvcname[self.svcname] = self
140
141
 
141
142
  await self.core.feedBeholder('svc:set', {'name': self.name, 'iden': self.iden, 'svcname': self.svcname, 'version': self.svcvers})
143
+ # if the old service is the same as the new service, just skip
142
144
 
143
- try:
144
- await self.core._delStormSvcPkgs(self.iden)
145
-
146
- except asyncio.CancelledError: # pragma: no cover TODO: remove once >= py 3.8 only
147
- raise
148
-
149
- except Exception:
150
- logger.exception(f'_delStormSvcPkgs failed for service {self.name} ({self.iden})')
145
+ oldpkgs = self.core.getStormSvcPkgs(self.iden)
146
+ byname = {}
147
+ done = set()
148
+ for pdef in oldpkgs:
149
+ iden = s_hashitem.hashitem(pdef)
150
+ byname[pdef.get('name')] = iden
151
151
 
152
152
  # Register new packages
153
153
  for pdef in self.info.get('pkgs', ()):
154
-
155
154
  try:
156
- # push the svciden in the package metadata for later reference.
157
155
  pdef['svciden'] = self.iden
158
156
  await self.core._normStormPkg(pdef)
157
+ except Exception:
158
+ name = pdef.get('name')
159
+ logger.exception(f'normStormPkg ({name}) failed for service {self.name} ({self.iden})')
160
+ continue
161
+
162
+ name = pdef.get('name')
163
+ iden = s_hashitem.hashitem(pdef)
164
+
165
+ done.add(name)
166
+ if name in byname:
167
+ if byname[name] != iden:
168
+ await self.core._delStormPkg(name) # we're updating an old package, so delete the old and then re-add
169
+ else:
170
+ continue # pkg unchanged. Can skip.
171
+
172
+ try:
173
+ # push the svciden in the package metadata for later reference.
159
174
  await self.core._addStormPkg(pdef)
160
175
 
161
176
  except asyncio.CancelledError: # pragma: no cover TODO: remove once >= py 3.8 only
162
177
  raise
163
178
 
164
179
  except Exception:
165
- name = pdef.get('name')
166
180
  logger.exception(f'addStormPkg ({name}) failed for service {self.name} ({self.iden})')
167
181
 
182
+ # clean up any packages that no longer exist
183
+ for name in byname.keys():
184
+ if name not in done:
185
+ await self.core._delStormPkg(name)
186
+
168
187
  # Set events and fire as needed
169
188
  evts = self.info.get('evts')
170
189
  try:
synapse/lib/stormtypes.py CHANGED
@@ -18,7 +18,6 @@ import calendar
18
18
  import functools
19
19
  import contextlib
20
20
  import collections
21
- from typing import Any
22
21
 
23
22
  import synapse.exc as s_exc
24
23
  import synapse.common as s_common
@@ -8440,7 +8439,9 @@ class Trigger(Prim):
8440
8439
 
8441
8440
  async def set(self, name, valu):
8442
8441
  trigiden = self.valu.get('iden')
8443
- viewiden = self.runt.snap.view.iden
8442
+ viewiden = self.valu.get('view')
8443
+
8444
+ view = self.runt.snap.core.reqView(viewiden)
8444
8445
 
8445
8446
  name = await tostr(name)
8446
8447
  if name in ('async', 'enabled', ):
@@ -8449,11 +8450,11 @@ class Trigger(Prim):
8449
8450
  valu = await tostr(valu)
8450
8451
 
8451
8452
  if name == 'user':
8452
- self.runt.user.confirm(('trigger', 'set', 'user'))
8453
+ self.runt.confirm(('trigger', 'set', 'user'))
8453
8454
  else:
8454
- self.runt.user.confirm(('trigger', 'set', name), gateiden=viewiden)
8455
+ self.runt.confirm(('trigger', 'set', name), gateiden=viewiden)
8455
8456
 
8456
- await self.runt.snap.view.setTriggerInfo(trigiden, name, valu)
8457
+ await view.setTriggerInfo(trigiden, name, valu)
8457
8458
 
8458
8459
  self.valu[name] = valu
8459
8460
 
@@ -8825,6 +8826,8 @@ class LibCron(Lib):
8825
8826
  'desc': 'Permits a user to create a cron job.'},
8826
8827
  {'perm': ('cron', 'del'), 'gate': 'cronjob',
8827
8828
  'desc': 'Permits a user to remove a cron job.'},
8829
+ {'perm': ('cron', 'kill'), 'gate': 'cronjob',
8830
+ 'desc': 'Controls the ability to terminate a running cron job.'},
8828
8831
  {'perm': ('cron', 'get'), 'gate': 'cronjob',
8829
8832
  'desc': 'Permits a user to list cron jobs.'},
8830
8833
  {'perm': ('cron', 'set'), 'gate': 'cronjob',
@@ -9276,14 +9279,19 @@ class CronJob(Prim):
9276
9279
  {'name': 'valu', 'type': 'any', 'desc': 'The value to set on the definition.', },
9277
9280
  ),
9278
9281
  'returns': {'type': 'cronjob', 'desc': 'The ``cronjob``', }}},
9282
+
9283
+ {'name': 'kill', 'desc': 'If the job is currently running, terminate the task.',
9284
+ 'type': {'type': 'function', '_funcname': '_methCronJobKill',
9285
+ 'returns': {'type': 'boolean', 'desc': 'A boolean value which is true if the task was terminated.'}}},
9286
+
9279
9287
  {'name': 'pack', 'desc': 'Get the Cronjob definition.',
9280
9288
  'type': {'type': 'function', '_funcname': '_methCronJobPack',
9281
- 'returns': {'type': 'dict', 'desc': 'The definition.', }}},
9289
+ 'returns': {'type': 'dict', 'desc': 'The definition.'}}},
9282
9290
  {'name': 'pprint', 'desc': 'Get a dictionary containing user friendly strings for printing the CronJob.',
9283
9291
  'type': {'type': 'function', '_funcname': '_methCronJobPprint',
9284
9292
  'returns':
9285
9293
  {'type': 'dict',
9286
- 'desc': 'A dictionary containing structured data about a cronjob for display purposes.', }}},
9294
+ 'desc': 'A dictionary containing structured data about a cronjob for display purposes.'}}},
9287
9295
  )
9288
9296
  _storm_typename = 'cronjob'
9289
9297
  _ismutable = False
@@ -9300,10 +9308,16 @@ class CronJob(Prim):
9300
9308
  def getObjLocals(self):
9301
9309
  return {
9302
9310
  'set': self._methCronJobSet,
9311
+ 'kill': self._methCronJobKill,
9303
9312
  'pack': self._methCronJobPack,
9304
9313
  'pprint': self._methCronJobPprint,
9305
9314
  }
9306
9315
 
9316
+ async def _methCronJobKill(self):
9317
+ iden = self.valu.get('iden')
9318
+ self.runt.confirm(('cron', 'kill'), gateiden=iden)
9319
+ return await self.runt.snap.core.killCronTask(iden)
9320
+
9307
9321
  async def _methCronJobSet(self, name, valu):
9308
9322
  name = await tostr(name)
9309
9323
  valu = await toprim(valu)
@@ -9312,9 +9326,9 @@ class CronJob(Prim):
9312
9326
  if name == 'creator':
9313
9327
  # this permission must be granted cortex wide
9314
9328
  # to prevent abuse...
9315
- self.runt.user.confirm(('cron', 'set', 'creator'))
9329
+ self.runt.confirm(('cron', 'set', 'creator'))
9316
9330
  else:
9317
- self.runt.user.confirm(('cron', 'set', name), gateiden=iden)
9331
+ self.runt.confirm(('cron', 'set', name), gateiden=iden)
9318
9332
 
9319
9333
  self.valu = await self.runt.snap.core.editCronJob(iden, name, valu)
9320
9334
 
synapse/lib/trigger.py CHANGED
@@ -522,10 +522,6 @@ class Trigger:
522
522
  logger.warning(f'Skipping trigger execution because user {self.user.iden} is locked')
523
523
  return
524
524
 
525
- tag = self.tdef.get('tag')
526
- cond = self.tdef.get('cond')
527
- form = self.tdef.get('form')
528
- prop = self.tdef.get('prop')
529
525
  storm = self.tdef.get('storm')
530
526
 
531
527
  query = await self.view.core.getStormQuery(storm)
synapse/lib/types.py CHANGED
@@ -1402,7 +1402,7 @@ class Loc(Type):
1402
1402
 
1403
1403
  class Ndef(Type):
1404
1404
 
1405
- stortype = s_layer.STOR_TYPE_MSGP
1405
+ stortype = s_layer.STOR_TYPE_NDEF
1406
1406
 
1407
1407
  def postTypeInit(self):
1408
1408
  self.setNormFunc(list, self._normPyTuple)
synapse/lib/version.py CHANGED
@@ -223,6 +223,6 @@ def reqVersion(valu, reqver,
223
223
  ##############################################################################
224
224
  # The following are touched during the release process by bumpversion.
225
225
  # Do not modify these directly.
226
- version = (2, 173, 1)
226
+ version = (2, 175, 0)
227
227
  verstring = '.'.join([str(x) for x in version])
228
- commit = '06b04fd5f58964b7897442d4c88cbfed145093d9'
228
+ commit = 'c331c50ef1e7b2234be997c4b791fb8b8bed7cf2'
synapse/lib/view.py CHANGED
@@ -1518,6 +1518,8 @@ class View(s_nexus.Pusher): # type: ignore
1518
1518
  elif self.triggers.get(iden) is not None:
1519
1519
  raise s_exc.DupIden(mesg='A trigger with this iden already exists')
1520
1520
 
1521
+ tdef['view'] = self.iden
1522
+
1521
1523
  root = await self.core.auth.getUserByName('root')
1522
1524
 
1523
1525
  tdef.setdefault('created', s_common.now())
synapse/models/crypto.py CHANGED
@@ -371,31 +371,53 @@ class CryptoModule(s_module.CoreModule):
371
371
  ('crypto:algorithm', {}, ()),
372
372
 
373
373
  ('crypto:key', {}, (
374
+
374
375
  ('algorithm', ('crypto:algorithm', {}), {
375
376
  'ex': 'aes256',
376
377
  'doc': 'The cryptographic algorithm which uses the key material.'}),
378
+
377
379
  ('mode', ('str', {'lower': True, 'onespace': True}), {
378
380
  'doc': 'The algorithm specific mode in use.'}),
381
+
379
382
  ('iv', ('hex', {}), {
380
383
  'doc': 'The hex encoded initialization vector.'}),
384
+
385
+ ('iv:text', ('it:dev:str', {}), {
386
+ 'doc': 'Set only if the :iv property decodes to ASCII.'}),
387
+
381
388
  ('public', ('hex', {}), {
382
389
  'doc': 'The hex encoded public key material if the algorithm has a public/private key pair.'}),
390
+
391
+ ('public:text', ('it:dev:str', {}), {
392
+ 'doc': 'Set only if the :public property decodes to ASCII.'}),
393
+
383
394
  ('public:md5', ('hash:md5', {}), {
384
395
  'doc': 'The MD5 hash of the public key in raw binary form.'}),
396
+
385
397
  ('public:sha1', ('hash:sha1', {}), {
386
398
  'doc': 'The SHA1 hash of the public key in raw binary form.'}),
399
+
387
400
  ('public:sha256', ('hash:sha256', {}), {
388
401
  'doc': 'The SHA256 hash of the public key in raw binary form.'}),
402
+
389
403
  ('private', ('hex', {}), {
390
404
  'doc': 'The hex encoded private key material. All symmetric keys are private.'}),
405
+
406
+ ('private:text', ('it:dev:str', {}), {
407
+ 'doc': 'Set only if the :private property decodes to ASCII.'}),
408
+
391
409
  ('private:md5', ('hash:md5', {}), {
392
410
  'doc': 'The MD5 hash of the private key in raw binary form.'}),
411
+
393
412
  ('private:sha1', ('hash:sha1', {}), {
394
413
  'doc': 'The SHA1 hash of the private key in raw binary form.'}),
414
+
395
415
  ('private:sha256', ('hash:sha256', {}), {
396
416
  'doc': 'The SHA256 hash of the private key in raw binary form.'}),
417
+
397
418
  ('seed:passwd', ('inet:passwd', {}), {
398
419
  'doc': 'The seed password used to generate the key material.'}),
420
+
399
421
  ('seed:algorithm', ('crypto:algorithm', {}), {
400
422
  'ex': 'pbkdf2',
401
423
  'doc': 'The algorithm used to generate the key from the seed password.'})