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.
- synapse/axon.py +1 -1
- synapse/common.py +19 -5
- synapse/cortex.py +46 -10
- synapse/daemon.py +11 -12
- synapse/lib/agenda.py +6 -0
- synapse/lib/ast.py +5 -1
- synapse/lib/cell.py +22 -13
- synapse/lib/jupyter.py +21 -0
- synapse/lib/layer.py +124 -30
- synapse/lib/link.py +3 -2
- synapse/lib/lmdbslab.py +11 -1
- synapse/lib/modelrev.py +31 -1
- synapse/lib/modules.py +1 -0
- synapse/lib/msgpack.py +25 -3
- synapse/lib/nexus.py +26 -22
- synapse/lib/schemas.py +31 -0
- synapse/lib/snap.py +13 -0
- synapse/lib/storm.py +103 -86
- synapse/lib/stormsvc.py +30 -11
- synapse/lib/stormtypes.py +23 -9
- synapse/lib/trigger.py +0 -4
- synapse/lib/types.py +1 -1
- synapse/lib/version.py +2 -2
- synapse/lib/view.py +2 -0
- synapse/models/crypto.py +22 -0
- synapse/models/economic.py +23 -2
- synapse/models/entity.py +16 -0
- synapse/models/files.py +4 -1
- synapse/models/geopol.py +3 -0
- synapse/models/orgs.py +3 -4
- synapse/tests/test_cortex.py +13 -0
- synapse/tests/test_daemon.py +36 -0
- synapse/tests/test_lib_agenda.py +129 -1
- synapse/tests/test_lib_ast.py +56 -0
- synapse/tests/test_lib_cell.py +11 -0
- synapse/tests/test_lib_grammar.py +4 -0
- synapse/tests/test_lib_httpapi.py +1 -0
- synapse/tests/test_lib_lmdbslab.py +16 -1
- synapse/tests/test_lib_modelrev.py +86 -0
- synapse/tests/test_lib_msgpack.py +58 -8
- synapse/tests/test_lib_nexus.py +44 -1
- synapse/tests/test_lib_storm.py +134 -18
- synapse/tests/test_lib_stormsvc.py +128 -51
- synapse/tests/test_lib_stormtypes.py +43 -4
- synapse/tests/test_lib_trigger.py +23 -4
- synapse/tests/test_model_crypto.py +6 -0
- synapse/tests/test_model_economic.py +14 -1
- synapse/tests/test_model_geopol.py +3 -0
- synapse/tools/changelog.py +256 -0
- {synapse-2.173.1.dist-info → synapse-2.175.0.dist-info}/METADATA +1 -1
- {synapse-2.173.1.dist-info → synapse-2.175.0.dist-info}/RECORD +54 -52
- {synapse-2.173.1.dist-info → synapse-2.175.0.dist-info}/WHEEL +1 -1
- {synapse-2.173.1.dist-info → synapse-2.175.0.dist-info}/LICENSE +0 -0
- {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,
|
|
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
|
-
|
|
3525
|
+
tagnames = [await s_stormtypes.tostr(tag) for tag in self.opts.tag]
|
|
3520
3526
|
|
|
3521
3527
|
layr = runt.snap.view.layers[0]
|
|
3522
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
3796
|
-
|
|
3797
|
-
|
|
3798
|
-
|
|
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
|
-
|
|
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
|
-
|
|
3828
|
-
runt.
|
|
3829
|
-
|
|
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
|
-
|
|
3832
|
-
verb
|
|
3833
|
-
|
|
3834
|
-
|
|
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]
|
|
3849
|
-
layr1 = runt.snap.view.layers[1]
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
3956
|
-
isset =
|
|
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
|
|
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
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
4010
|
-
|
|
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
|
|
4032
|
+
async for edge in s_coro.pause(layr0.iterNodeEdgesN1(node.buid)):
|
|
4021
4033
|
name, dest = edge
|
|
4022
|
-
if not
|
|
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
|
-
|
|
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
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
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.
|
|
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.
|
|
8453
|
+
self.runt.confirm(('trigger', 'set', 'user'))
|
|
8453
8454
|
else:
|
|
8454
|
-
self.runt.
|
|
8455
|
+
self.runt.confirm(('trigger', 'set', name), gateiden=viewiden)
|
|
8455
8456
|
|
|
8456
|
-
await
|
|
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.
|
|
9329
|
+
self.runt.confirm(('cron', 'set', 'creator'))
|
|
9316
9330
|
else:
|
|
9317
|
-
self.runt.
|
|
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
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,
|
|
226
|
+
version = (2, 175, 0)
|
|
227
227
|
verstring = '.'.join([str(x) for x in version])
|
|
228
|
-
commit = '
|
|
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.'})
|