synapse 2.221.0__py311-none-any.whl → 2.223.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/cortex.py +143 -44
- synapse/cryotank.py +1 -1
- synapse/data/lark/storm.lark +9 -6
- synapse/lib/ast.py +13 -5
- synapse/lib/layer.py +18 -11
- synapse/lib/nexus.py +1 -1
- synapse/lib/parser.py +1 -0
- synapse/lib/rstorm.py +19 -1
- synapse/lib/schemas.py +4 -0
- synapse/lib/snap.py +15 -9
- synapse/lib/storm.py +0 -190
- synapse/lib/stormlib/auth.py +1 -1
- synapse/lib/stormlib/cortex.py +1 -1
- synapse/lib/stormlib/mime.py +15 -5
- synapse/lib/stormlib/pkg.py +598 -0
- synapse/lib/stormlib/task.py +115 -0
- synapse/lib/stormtypes.py +42 -178
- synapse/lib/trigger.py +16 -14
- synapse/lib/version.py +2 -2
- synapse/lib/view.py +17 -14
- synapse/models/files.py +1 -1
- synapse/models/orgs.py +3 -0
- synapse/tests/test_cortex.py +1 -1
- synapse/tests/test_lib_aha.py +68 -53
- synapse/tests/test_lib_ast.py +3 -0
- synapse/tests/test_lib_cell.py +12 -12
- synapse/tests/test_lib_grammar.py +4 -4
- synapse/tests/test_lib_rstorm.py +55 -7
- synapse/tests/test_lib_storm.py +105 -249
- synapse/tests/test_lib_stormlib_auth.py +84 -0
- synapse/tests/test_lib_stormlib_cortex.py +1 -0
- synapse/tests/test_lib_stormlib_mime.py +24 -0
- synapse/tests/test_lib_stormlib_pkg.py +456 -0
- synapse/tests/test_lib_stormlib_task.py +98 -0
- synapse/tests/test_lib_stormtypes.py +25 -100
- synapse/tests/test_lib_trigger.py +66 -3
- synapse/tests/test_lib_view.py +53 -0
- synapse/tests/test_model_files.py +11 -0
- synapse/tests/test_model_orgs.py +6 -1
- synapse/tools/cryo/cat.py +2 -1
- synapse/tools/cryo/list.py +2 -0
- {synapse-2.221.0.dist-info → synapse-2.223.0.dist-info}/METADATA +1 -1
- {synapse-2.221.0.dist-info → synapse-2.223.0.dist-info}/RECORD +46 -42
- {synapse-2.221.0.dist-info → synapse-2.223.0.dist-info}/WHEEL +0 -0
- {synapse-2.221.0.dist-info → synapse-2.223.0.dist-info}/licenses/LICENSE +0 -0
- {synapse-2.221.0.dist-info → synapse-2.223.0.dist-info}/top_level.txt +0 -0
|
@@ -0,0 +1,115 @@
|
|
|
1
|
+
import asyncio
|
|
2
|
+
import logging
|
|
3
|
+
|
|
4
|
+
import synapse.exc as s_exc
|
|
5
|
+
import synapse.lib.stormtypes as s_stormtypes
|
|
6
|
+
|
|
7
|
+
logger = logging.getLogger(__name__)
|
|
8
|
+
|
|
9
|
+
stormcmds = [
|
|
10
|
+
{
|
|
11
|
+
'name': 'task.list',
|
|
12
|
+
'descr': 'List running tasks on the Cortex and any mirrors.',
|
|
13
|
+
'cmdargs': (
|
|
14
|
+
('--verbose', {'default': False, 'action': 'store_true', 'help': 'Enable verbose output.'}),
|
|
15
|
+
),
|
|
16
|
+
'storm': '''
|
|
17
|
+
$tcnt = (0)
|
|
18
|
+
for $task in $lib.task.list() {
|
|
19
|
+
$lib.print(`task iden: {$task.iden}`)
|
|
20
|
+
$lib.print(` name: {$task.name}`)
|
|
21
|
+
$lib.print(` user: {$task.username}`)
|
|
22
|
+
$lib.print(` service: {$task.service}`)
|
|
23
|
+
$lib.print(` start time: {$lib.time.format($task.tick, '%Y-%m-%d %H:%M:%S')}`)
|
|
24
|
+
$lib.print(' metadata:')
|
|
25
|
+
if $cmdopts.verbose {
|
|
26
|
+
$lib.pprint($task.info, prefix=' ')
|
|
27
|
+
} else {
|
|
28
|
+
$lib.pprint($task.info, prefix=' ', clamp=120)
|
|
29
|
+
}
|
|
30
|
+
$tcnt = ($tcnt + 1)
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
if ($tcnt = 1) {
|
|
34
|
+
$lib.print('1 task found.')
|
|
35
|
+
} else {
|
|
36
|
+
$lib.print(`{$tcnt} tasks found.`)
|
|
37
|
+
}
|
|
38
|
+
''',
|
|
39
|
+
},
|
|
40
|
+
{
|
|
41
|
+
'name': 'task.kill',
|
|
42
|
+
'descr': 'Kill a running task on the Cortex or a mirror.',
|
|
43
|
+
'cmdargs': (
|
|
44
|
+
('iden', {'help': 'Any prefix that matches exactly one valid task iden is accepted.'}),
|
|
45
|
+
),
|
|
46
|
+
'storm': '''
|
|
47
|
+
$kild = $lib.task.kill($cmdopts.iden)
|
|
48
|
+
$lib.print("kill status: {kild}", kild=$kild)
|
|
49
|
+
''',
|
|
50
|
+
},
|
|
51
|
+
]
|
|
52
|
+
|
|
53
|
+
@s_stormtypes.registry.registerLib
|
|
54
|
+
class LibTask(s_stormtypes.Lib):
|
|
55
|
+
'''
|
|
56
|
+
A Storm Library for interacting with tasks on a Cortex and its mirrors.
|
|
57
|
+
'''
|
|
58
|
+
_storm_locals = (
|
|
59
|
+
{'name': 'list', 'desc': 'List tasks the current user can access on the Cortex and its mirrors.',
|
|
60
|
+
'type': {'type': 'function', '_funcname': '_methTaskList', 'args': (),
|
|
61
|
+
'returns': {'name': 'yields', 'type': 'dict', 'desc': 'Task definitions.'}}},
|
|
62
|
+
{'name': 'kill', 'desc': 'Stop a running task on the Cortex or a mirror.',
|
|
63
|
+
'type': {'type': 'function', '_funcname': '_methTaskKill', 'args': (
|
|
64
|
+
{'name': 'prefix', 'type': 'str',
|
|
65
|
+
'desc': 'The prefix of the task to stop. '
|
|
66
|
+
'Tasks will only be stopped if there is a single prefix match.'},),
|
|
67
|
+
'returns': {'type': 'boolean', 'desc': 'True if the task was cancelled, False otherwise.'}}},
|
|
68
|
+
)
|
|
69
|
+
_storm_lib_path = ('task',)
|
|
70
|
+
_storm_lib_perms = (
|
|
71
|
+
{'perm': ('task', 'get'), 'gate': 'cortex',
|
|
72
|
+
'desc': 'Permits a user to view tasks owned by other users.'},
|
|
73
|
+
{'perm': ('task', 'del'), 'gate': 'cortex',
|
|
74
|
+
'desc': 'Permits a user to kill tasks owned by other users.'},
|
|
75
|
+
)
|
|
76
|
+
|
|
77
|
+
def getObjLocals(self):
|
|
78
|
+
return {
|
|
79
|
+
'list': self._methTaskList,
|
|
80
|
+
'kill': self._methTaskKill,
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
@s_stormtypes.stormfunc(readonly=True)
|
|
84
|
+
async def _methTaskList(self):
|
|
85
|
+
useriden = self.runt.user.iden
|
|
86
|
+
isallowed = self.runt.allowed(('task', 'get'))
|
|
87
|
+
|
|
88
|
+
async for task in self.runt.snap.core.getTasks():
|
|
89
|
+
if isallowed or task['user'] == useriden:
|
|
90
|
+
yield task
|
|
91
|
+
|
|
92
|
+
async def _methTaskKill(self, prefix):
|
|
93
|
+
useriden = self.runt.user.iden
|
|
94
|
+
isallowed = self.runt.allowed(('task', 'del'))
|
|
95
|
+
|
|
96
|
+
prefix = await s_stormtypes.tostr(prefix)
|
|
97
|
+
if not prefix:
|
|
98
|
+
mesg = 'An empty task iden prefix is not allowed.'
|
|
99
|
+
raise s_exc.StormRuntimeError(mesg=mesg, iden=prefix)
|
|
100
|
+
|
|
101
|
+
iden = None
|
|
102
|
+
async for task in self.runt.snap.core.getTasks():
|
|
103
|
+
taskiden = task['iden']
|
|
104
|
+
if (isallowed or task['user'] == useriden) and taskiden.startswith(prefix):
|
|
105
|
+
if iden is None:
|
|
106
|
+
iden = taskiden
|
|
107
|
+
else:
|
|
108
|
+
mesg = 'Provided iden matches more than one task.'
|
|
109
|
+
raise s_exc.StormRuntimeError(mesg=mesg, iden=prefix)
|
|
110
|
+
|
|
111
|
+
if iden is None:
|
|
112
|
+
mesg = 'Provided iden does not match any tasks.'
|
|
113
|
+
raise s_exc.StormRuntimeError(mesg=mesg, iden=prefix)
|
|
114
|
+
|
|
115
|
+
return await self.runt.snap.core.killTask(iden)
|
synapse/lib/stormtypes.py
CHANGED
|
@@ -699,117 +699,6 @@ class Lib(StormType):
|
|
|
699
699
|
async for item in self.runt.dyniter(iden, todo, gatekeys=gatekeys):
|
|
700
700
|
yield item
|
|
701
701
|
|
|
702
|
-
@registry.registerLib
|
|
703
|
-
class LibPkg(Lib):
|
|
704
|
-
'''
|
|
705
|
-
A Storm Library for interacting with Storm Packages.
|
|
706
|
-
'''
|
|
707
|
-
_storm_locals = (
|
|
708
|
-
{'name': 'add', 'desc': 'Add a Storm Package to the Cortex.',
|
|
709
|
-
'type': {'type': 'function', '_funcname': '_libPkgAdd',
|
|
710
|
-
'args': (
|
|
711
|
-
{'name': 'pkgdef', 'type': 'dict', 'desc': 'A Storm Package definition.', },
|
|
712
|
-
{'name': 'verify', 'type': 'boolean', 'default': False,
|
|
713
|
-
'desc': 'Verify storm package signature.', },
|
|
714
|
-
),
|
|
715
|
-
'returns': {'type': 'null', }}},
|
|
716
|
-
{'name': 'get', 'desc': 'Get a Storm Package from the Cortex.',
|
|
717
|
-
'type': {'type': 'function', '_funcname': '_libPkgGet',
|
|
718
|
-
'args': (
|
|
719
|
-
{'name': 'name', 'type': 'str', 'desc': 'A Storm Package name.', },
|
|
720
|
-
),
|
|
721
|
-
'returns': {'type': 'dict', 'desc': 'The Storm package definition.', }}},
|
|
722
|
-
{'name': 'has', 'desc': 'Check if a Storm Package is available in the Cortex.',
|
|
723
|
-
'type': {'type': 'function', '_funcname': '_libPkgHas',
|
|
724
|
-
'args': (
|
|
725
|
-
{'name': 'name', 'type': 'str',
|
|
726
|
-
'desc': 'A Storm Package name to check for the existence of.', },
|
|
727
|
-
),
|
|
728
|
-
'returns': {'type': 'boolean',
|
|
729
|
-
'desc': 'True if the package exists in the Cortex, False if it does not.', }}},
|
|
730
|
-
{'name': 'del', 'desc': 'Delete a Storm Package from the Cortex.',
|
|
731
|
-
'type': {'type': 'function', '_funcname': '_libPkgDel',
|
|
732
|
-
'args': (
|
|
733
|
-
{'name': 'name', 'type': 'str', 'desc': 'The name of the package to delete.', },
|
|
734
|
-
),
|
|
735
|
-
'returns': {'type': 'null', }}},
|
|
736
|
-
{'name': 'list', 'desc': 'Get a list of Storm Packages loaded in the Cortex.',
|
|
737
|
-
'type': {'type': 'function', '_funcname': '_libPkgList',
|
|
738
|
-
'returns': {'type': 'list', 'desc': 'A list of Storm Package definitions.', }}},
|
|
739
|
-
{'name': 'deps', 'desc': 'Verify the dependencies for a Storm Package.',
|
|
740
|
-
'type': {'type': 'function', '_funcname': '_libPkgDeps',
|
|
741
|
-
'args': (
|
|
742
|
-
{'name': 'pkgdef', 'type': 'dict', 'desc': 'A Storm Package definition.', },
|
|
743
|
-
),
|
|
744
|
-
'returns': {'type': 'dict', 'desc': 'A dictionary listing dependencies and if they are met.', }}},
|
|
745
|
-
{'name': 'vars',
|
|
746
|
-
'desc': "Get a dictionary representing the package's persistent variables.",
|
|
747
|
-
'type': {'type': 'function', '_funcname': '_libPkgVars',
|
|
748
|
-
'args': (
|
|
749
|
-
{'name': 'name', 'type': 'str',
|
|
750
|
-
'desc': 'A Storm Package name to get vars for.', },
|
|
751
|
-
),
|
|
752
|
-
'returns': {'type': 'pkg:vars', 'desc': 'A dictionary representing the package variables.', }}},
|
|
753
|
-
)
|
|
754
|
-
_storm_lib_perms = (
|
|
755
|
-
{'perm': ('power-ups', '<name>', 'admin'), 'gate': 'cortex',
|
|
756
|
-
'desc': 'Controls the ability to interact with the vars for a Storm Package by name.'},
|
|
757
|
-
)
|
|
758
|
-
_storm_lib_path = ('pkg',)
|
|
759
|
-
|
|
760
|
-
def getObjLocals(self):
|
|
761
|
-
return {
|
|
762
|
-
'add': self._libPkgAdd,
|
|
763
|
-
'get': self._libPkgGet,
|
|
764
|
-
'has': self._libPkgHas,
|
|
765
|
-
'del': self._libPkgDel,
|
|
766
|
-
'list': self._libPkgList,
|
|
767
|
-
'deps': self._libPkgDeps,
|
|
768
|
-
'vars': self._libPkgVars,
|
|
769
|
-
}
|
|
770
|
-
|
|
771
|
-
async def _libPkgAdd(self, pkgdef, verify=False):
|
|
772
|
-
self.runt.confirm(('pkg', 'add'), None)
|
|
773
|
-
pkgdef = await toprim(pkgdef)
|
|
774
|
-
verify = await tobool(verify)
|
|
775
|
-
await self.runt.snap.core.addStormPkg(pkgdef, verify=verify)
|
|
776
|
-
|
|
777
|
-
@stormfunc(readonly=True)
|
|
778
|
-
async def _libPkgGet(self, name):
|
|
779
|
-
name = await tostr(name)
|
|
780
|
-
pkgdef = await self.runt.snap.core.getStormPkg(name)
|
|
781
|
-
if pkgdef is None:
|
|
782
|
-
return None
|
|
783
|
-
|
|
784
|
-
return Dict(pkgdef)
|
|
785
|
-
|
|
786
|
-
@stormfunc(readonly=True)
|
|
787
|
-
async def _libPkgHas(self, name):
|
|
788
|
-
name = await tostr(name)
|
|
789
|
-
pkgdef = await self.runt.snap.core.getStormPkg(name)
|
|
790
|
-
if pkgdef is None:
|
|
791
|
-
return False
|
|
792
|
-
return True
|
|
793
|
-
|
|
794
|
-
async def _libPkgDel(self, name):
|
|
795
|
-
self.runt.confirm(('pkg', 'del'), None)
|
|
796
|
-
await self.runt.snap.core.delStormPkg(name)
|
|
797
|
-
|
|
798
|
-
@stormfunc(readonly=True)
|
|
799
|
-
async def _libPkgList(self):
|
|
800
|
-
pkgs = await self.runt.snap.core.getStormPkgs()
|
|
801
|
-
return list(sorted(pkgs, key=lambda x: x.get('name')))
|
|
802
|
-
|
|
803
|
-
@stormfunc(readonly=True)
|
|
804
|
-
async def _libPkgDeps(self, pkgdef):
|
|
805
|
-
pkgdef = await toprim(pkgdef)
|
|
806
|
-
return await self.runt.snap.core.verifyStormPkgDeps(pkgdef)
|
|
807
|
-
|
|
808
|
-
async def _libPkgVars(self, name):
|
|
809
|
-
name = await tostr(name)
|
|
810
|
-
confirm(('power-ups', name, 'admin'))
|
|
811
|
-
return PkgVars(self.runt, name)
|
|
812
|
-
|
|
813
702
|
@registry.registerLib
|
|
814
703
|
class LibDmon(Lib):
|
|
815
704
|
'''
|
|
@@ -1595,8 +1484,16 @@ class LibBase(Lib):
|
|
|
1595
1484
|
|
|
1596
1485
|
if not asroot:
|
|
1597
1486
|
permtext = ' or '.join(('.'.join(p) for p in rootperms))
|
|
1598
|
-
|
|
1599
|
-
|
|
1487
|
+
|
|
1488
|
+
match mdef.get('asroot:ondeny:import', 'deny'):
|
|
1489
|
+
case 'allow':
|
|
1490
|
+
pass
|
|
1491
|
+
case 'warn':
|
|
1492
|
+
mesg = f'Module ({name}) permissions will not be elevated. Missing permission: {permtext}.'
|
|
1493
|
+
await self.runt.warnonce(mesg, log=False)
|
|
1494
|
+
case _:
|
|
1495
|
+
mesg = f'Module ({name}) requires permission: {permtext}'
|
|
1496
|
+
raise s_exc.AuthDeny(mesg=mesg, user=self.runt.user.iden, username=self.runt.user.name)
|
|
1600
1497
|
|
|
1601
1498
|
else:
|
|
1602
1499
|
perm = ('storm', 'asroot', 'mod') + tuple(name.split('.'))
|
|
@@ -3948,22 +3845,22 @@ class LibQueue(Lib):
|
|
|
3948
3845
|
{'name': 'add', 'desc': 'Add a Queue to the Cortex with a given name.',
|
|
3949
3846
|
'type': {'type': 'function', '_funcname': '_methQueueAdd',
|
|
3950
3847
|
'args': (
|
|
3951
|
-
{'name': 'name', 'type': 'str', 'desc': 'The name of the
|
|
3848
|
+
{'name': 'name', 'type': 'str', 'desc': 'The name of the Queue to add.', },
|
|
3952
3849
|
),
|
|
3953
3850
|
'returns': {'type': 'queue', }}},
|
|
3954
|
-
{'name': 'gen', 'desc': 'Add or get a
|
|
3851
|
+
{'name': 'gen', 'desc': 'Add or get a Queue in a single operation.',
|
|
3955
3852
|
'type': {'type': 'function', '_funcname': '_methQueueGen',
|
|
3956
3853
|
'args': (
|
|
3957
3854
|
{'name': 'name', 'type': 'str', 'desc': 'The name of the Queue to add or get.', },
|
|
3958
3855
|
),
|
|
3959
3856
|
'returns': {'type': 'queue', }}},
|
|
3960
|
-
{'name': 'del', 'desc': 'Delete a given
|
|
3857
|
+
{'name': 'del', 'desc': 'Delete a given Queue.',
|
|
3961
3858
|
'type': {'type': 'function', '_funcname': '_methQueueDel',
|
|
3962
3859
|
'args': (
|
|
3963
|
-
{'name': 'name', 'type': 'str', 'desc': 'The name of the
|
|
3860
|
+
{'name': 'name', 'type': 'str', 'desc': 'The name of the Queue to delete.', },
|
|
3964
3861
|
),
|
|
3965
3862
|
'returns': {'type': 'null', }}},
|
|
3966
|
-
{'name': 'get', 'desc': 'Get an existing
|
|
3863
|
+
{'name': 'get', 'desc': 'Get an existing Queue.',
|
|
3967
3864
|
'type': {'type': 'function', '_funcname': '_methQueueGet',
|
|
3968
3865
|
'args': (
|
|
3969
3866
|
{'name': 'name', 'type': 'str', 'desc': 'The name of the Queue to get.', },
|
|
@@ -3972,17 +3869,17 @@ class LibQueue(Lib):
|
|
|
3972
3869
|
{'name': 'list', 'desc': 'Get a list of the Queues in the Cortex.',
|
|
3973
3870
|
'type': {'type': 'function', '_funcname': '_methQueueList',
|
|
3974
3871
|
'returns': {'type': 'list',
|
|
3975
|
-
'desc': 'A list of
|
|
3872
|
+
'desc': 'A list of Queue definitions the current user is allowed to interact with.', }}},
|
|
3976
3873
|
)
|
|
3977
3874
|
_storm_lib_perms = (
|
|
3978
3875
|
{'perm': ('queue', 'add'), 'gate': 'cortex',
|
|
3979
|
-
'desc': 'Permits a user to create a
|
|
3876
|
+
'desc': 'Permits a user to create a Queue.'},
|
|
3980
3877
|
{'perm': ('queue', 'get'), 'gate': 'queue',
|
|
3981
|
-
'desc': 'Permits a user to access a
|
|
3878
|
+
'desc': 'Permits a user to access a Queue. This allows the user to read from the Queue and remove items from it.'},
|
|
3982
3879
|
{'perm': ('queue', 'put'), 'gate': 'queue',
|
|
3983
|
-
'desc': 'Permits a user to put items into a
|
|
3880
|
+
'desc': 'Permits a user to put items into a Queue.'},
|
|
3984
3881
|
{'perm': ('queue', 'del'), 'gate': 'queue',
|
|
3985
|
-
'desc': 'Permits a user to delete a
|
|
3882
|
+
'desc': 'Permits a user to delete a Queue.'},
|
|
3986
3883
|
)
|
|
3987
3884
|
_storm_lib_path = ('queue',)
|
|
3988
3885
|
|
|
@@ -4045,7 +3942,7 @@ class LibQueue(Lib):
|
|
|
4045
3942
|
@registry.registerType
|
|
4046
3943
|
class Queue(StormType):
|
|
4047
3944
|
'''
|
|
4048
|
-
A StormLib API instance of a named channel in the Cortex
|
|
3945
|
+
A StormLib API instance of a named channel in the Cortex MultiQueue.
|
|
4049
3946
|
'''
|
|
4050
3947
|
_storm_locals = (
|
|
4051
3948
|
{'name': 'name', 'desc': 'The name of the Queue.', 'type': 'str', },
|
|
@@ -4059,48 +3956,48 @@ class Queue(StormType):
|
|
|
4059
3956
|
'desc': 'Wait for the offset to be available before returning the item.', },
|
|
4060
3957
|
),
|
|
4061
3958
|
'returns': {'type': 'list',
|
|
4062
|
-
'desc': 'A tuple of the offset and the item from the
|
|
3959
|
+
'desc': 'A tuple of the offset and the item from the Queue. If wait is false and '
|
|
4063
3960
|
'the offset is not present, null is returned.', }}},
|
|
4064
|
-
{'name': 'pop', 'desc': 'Pop
|
|
3961
|
+
{'name': 'pop', 'desc': 'Pop an item from the Queue at a specific offset.',
|
|
4065
3962
|
'type': {'type': 'function', '_funcname': '_methQueuePop',
|
|
4066
3963
|
'args': (
|
|
4067
3964
|
{'name': 'offs', 'type': 'int', 'default': None,
|
|
4068
|
-
'desc': 'Offset to pop the item from. If not specified, the first item in the
|
|
3965
|
+
'desc': 'Offset to pop the item from. If not specified, the first item in the Queue will be'
|
|
4069
3966
|
' popped.', },
|
|
4070
3967
|
{'name': 'wait', 'type': 'boolean', 'default': False,
|
|
4071
3968
|
'desc': 'Wait for an item to be available to pop.'},
|
|
4072
3969
|
),
|
|
4073
3970
|
'returns': {'type': 'list',
|
|
4074
|
-
'desc': 'The offset and item popped from the
|
|
4075
|
-
'offset or the
|
|
4076
|
-
{'name': 'put', 'desc': 'Put an item into the
|
|
3971
|
+
'desc': 'The offset and item popped from the Queue. If there is no item at the '
|
|
3972
|
+
'offset or the Queue is empty and wait is false, it returns null.', }}},
|
|
3973
|
+
{'name': 'put', 'desc': 'Put an item into the Queue.',
|
|
4077
3974
|
'type': {'type': 'function', '_funcname': '_methQueuePut',
|
|
4078
3975
|
'args': (
|
|
4079
|
-
{'name': 'item', 'type': 'prim', 'desc': 'The item being put into the
|
|
3976
|
+
{'name': 'item', 'type': 'prim', 'desc': 'The item being put into the Queue.', },
|
|
4080
3977
|
),
|
|
4081
|
-
'returns': {'type': 'int', 'desc': 'The
|
|
3978
|
+
'returns': {'type': 'int', 'desc': 'The Queue offset of the item.'}}},
|
|
4082
3979
|
{'name': 'puts', 'desc': 'Put multiple items into the Queue.',
|
|
4083
3980
|
'type': {'type': 'function', '_funcname': '_methQueuePuts',
|
|
4084
3981
|
'args': (
|
|
4085
3982
|
{'name': 'items', 'type': 'list', 'desc': 'The items to put into the Queue.', },
|
|
4086
3983
|
),
|
|
4087
|
-
'returns': {'type': 'int', 'desc': 'The
|
|
3984
|
+
'returns': {'type': 'int', 'desc': 'The Queue offset of the first item.'}}},
|
|
4088
3985
|
{'name': 'gets', 'desc': 'Get multiple items from the Queue as a iterator.',
|
|
4089
3986
|
'type': {'type': 'function', '_funcname': '_methQueueGets',
|
|
4090
3987
|
'args': (
|
|
4091
|
-
{'name': 'offs', 'type': 'int', 'desc': 'The offset to retrieve
|
|
3988
|
+
{'name': 'offs', 'type': 'int', 'desc': 'The offset to retrieve items from.', 'default': 0, },
|
|
4092
3989
|
{'name': 'wait', 'type': 'boolean', 'default': True,
|
|
4093
3990
|
'desc': 'Wait for the offset to be available before returning the item.', },
|
|
4094
3991
|
{'name': 'cull', 'type': 'boolean', 'default': False,
|
|
4095
3992
|
'desc': 'Culls items up to, but not including, the specified offset.', },
|
|
4096
|
-
{'name': 'size', 'type': 'int', 'desc': 'The maximum number of items to yield',
|
|
3993
|
+
{'name': 'size', 'type': 'int', 'desc': 'The maximum number of items to yield.',
|
|
4097
3994
|
'default': None, },
|
|
4098
3995
|
),
|
|
4099
3996
|
'returns': {'name': 'Yields', 'type': 'list', 'desc': 'Yields tuples of the offset and item.', }}},
|
|
4100
|
-
{'name': 'cull', 'desc': 'Remove items from the
|
|
3997
|
+
{'name': 'cull', 'desc': 'Remove items from the Queue up to, and including, the offset.',
|
|
4101
3998
|
'type': {'type': 'function', '_funcname': '_methQueueCull',
|
|
4102
3999
|
'args': (
|
|
4103
|
-
{'name': 'offs', 'type': 'int', 'desc': 'The offset which to cull records from the
|
|
4000
|
+
{'name': 'offs', 'type': 'int', 'desc': 'The offset which to cull records from the Queue.', },
|
|
4104
4001
|
),
|
|
4105
4002
|
'returns': {'type': 'null', }}},
|
|
4106
4003
|
{'name': 'size', 'desc': 'Get the number of items in the Queue.',
|
|
@@ -6088,45 +5985,6 @@ class LibVars(Lib):
|
|
|
6088
5985
|
async def _libVarsType(self, valu):
|
|
6089
5986
|
return await totype(valu)
|
|
6090
5987
|
|
|
6091
|
-
@registry.registerType
|
|
6092
|
-
class PkgVars(Prim):
|
|
6093
|
-
'''
|
|
6094
|
-
The Storm deref/setitem/iter convention on top of pkg vars information.
|
|
6095
|
-
'''
|
|
6096
|
-
_storm_typename = 'pkg:vars'
|
|
6097
|
-
_ismutable = True
|
|
6098
|
-
|
|
6099
|
-
def __init__(self, runt, valu, path=None):
|
|
6100
|
-
Prim.__init__(self, valu, path=path)
|
|
6101
|
-
self.runt = runt
|
|
6102
|
-
|
|
6103
|
-
def _reqPkgAdmin(self):
|
|
6104
|
-
confirm(('power-ups', self.valu, 'admin'))
|
|
6105
|
-
|
|
6106
|
-
@stormfunc(readonly=True)
|
|
6107
|
-
async def deref(self, name):
|
|
6108
|
-
self._reqPkgAdmin()
|
|
6109
|
-
name = await tostr(name)
|
|
6110
|
-
return await self.runt.snap.core.getStormPkgVar(self.valu, name)
|
|
6111
|
-
|
|
6112
|
-
async def setitem(self, name, valu):
|
|
6113
|
-
self._reqPkgAdmin()
|
|
6114
|
-
name = await tostr(name)
|
|
6115
|
-
|
|
6116
|
-
if valu is undef:
|
|
6117
|
-
await self.runt.snap.core.popStormPkgVar(self.valu, name)
|
|
6118
|
-
return
|
|
6119
|
-
|
|
6120
|
-
valu = await toprim(valu)
|
|
6121
|
-
await self.runt.snap.core.setStormPkgVar(self.valu, name, valu)
|
|
6122
|
-
|
|
6123
|
-
@stormfunc(readonly=True)
|
|
6124
|
-
async def iter(self):
|
|
6125
|
-
self._reqPkgAdmin()
|
|
6126
|
-
async for name, valu in self.runt.snap.core.iterStormPkgVars(self.valu):
|
|
6127
|
-
yield name, valu
|
|
6128
|
-
await asyncio.sleep(0)
|
|
6129
|
-
|
|
6130
5988
|
@registry.registerType
|
|
6131
5989
|
class Query(Prim):
|
|
6132
5990
|
'''
|
|
@@ -7837,7 +7695,8 @@ class Layer(Prim):
|
|
|
7837
7695
|
|
|
7838
7696
|
layr = self.runt.snap.core.reqLayer(self.valu.get('iden'))
|
|
7839
7697
|
|
|
7840
|
-
self.runt.
|
|
7698
|
+
if not self.runt.allowed(('layer', 'edits', 'read'), gateiden=layr.iden):
|
|
7699
|
+
self.runt.confirm(('layer', 'read'), gateiden=layr.iden)
|
|
7841
7700
|
|
|
7842
7701
|
if reverse:
|
|
7843
7702
|
wait = False
|
|
@@ -10439,5 +10298,10 @@ async def totype(valu, basetypes=False) -> str:
|
|
|
10439
10298
|
async def typeerr(name, reqt):
|
|
10440
10299
|
if not isinstance(name, reqt):
|
|
10441
10300
|
styp = await totype(name, basetypes=True)
|
|
10442
|
-
|
|
10301
|
+
|
|
10302
|
+
reqtname = str(reqt)
|
|
10303
|
+
if (clsname := getattr(reqt, '__name__')):
|
|
10304
|
+
reqtname = clsname
|
|
10305
|
+
|
|
10306
|
+
mesg = f"Expected value of type '{reqtname}', got '{styp}' with value {name}."
|
|
10443
10307
|
return s_exc.StormRuntimeError(mesg=mesg, name=name, type=styp)
|
synapse/lib/trigger.py
CHANGED
|
@@ -136,26 +136,28 @@ class Triggers:
|
|
|
136
136
|
finally:
|
|
137
137
|
RecursionDepth.reset(token)
|
|
138
138
|
|
|
139
|
-
async def runNodeAdd(self, node):
|
|
139
|
+
async def runNodeAdd(self, node, useriden):
|
|
140
|
+
vars = {'auto': {'opts': {'user': useriden}}}
|
|
140
141
|
with self._recursion_check():
|
|
141
|
-
[await trig.execute(node) for trig in self.nodeadd.get(node.form.name, ())]
|
|
142
|
+
[await trig.execute(node, vars=vars) for trig in self.nodeadd.get(node.form.name, ())]
|
|
142
143
|
|
|
143
|
-
async def runNodeDel(self, node):
|
|
144
|
+
async def runNodeDel(self, node, useriden):
|
|
145
|
+
vars = {'auto': {'opts': {'user': useriden}}}
|
|
144
146
|
with self._recursion_check():
|
|
145
|
-
[await trig.execute(node) for trig in self.nodedel.get(node.form.name, ())]
|
|
147
|
+
[await trig.execute(node, vars=vars) for trig in self.nodedel.get(node.form.name, ())]
|
|
146
148
|
|
|
147
|
-
async def runPropSet(self, node, prop, oldv):
|
|
149
|
+
async def runPropSet(self, node, prop, oldv, useriden):
|
|
148
150
|
vars = {'propname': prop.name, 'propfull': prop.full,
|
|
149
|
-
'auto': {'opts': {'propname': prop.name, 'propfull': prop.full, }},
|
|
151
|
+
'auto': {'opts': {'propname': prop.name, 'propfull': prop.full, 'user': useriden}},
|
|
150
152
|
}
|
|
151
153
|
with self._recursion_check():
|
|
152
154
|
[await trig.execute(node, vars=vars) for trig in self.propset.get(prop.full, ())]
|
|
153
155
|
if prop.univ is not None:
|
|
154
156
|
[await trig.execute(node, vars=vars) for trig in self.propset.get(prop.univ.full, ())]
|
|
155
157
|
|
|
156
|
-
async def runTagAdd(self, node, tag):
|
|
158
|
+
async def runTagAdd(self, node, tag, useriden):
|
|
157
159
|
|
|
158
|
-
vars = {'tag': tag, 'auto': {'opts': {'tag': tag}}}
|
|
160
|
+
vars = {'tag': tag, 'auto': {'opts': {'tag': tag, 'user': useriden}}}
|
|
159
161
|
with self._recursion_check():
|
|
160
162
|
|
|
161
163
|
for trig in self.tagadd.get((node.form.name, tag), ()):
|
|
@@ -176,10 +178,10 @@ class Triggers:
|
|
|
176
178
|
for _, trig in globs.get(tag):
|
|
177
179
|
await trig.execute(node, vars=vars)
|
|
178
180
|
|
|
179
|
-
async def runTagDel(self, node, tag):
|
|
181
|
+
async def runTagDel(self, node, tag, useriden):
|
|
180
182
|
|
|
181
183
|
vars = {'tag': tag,
|
|
182
|
-
'auto': {'opts': {'tag': tag}},
|
|
184
|
+
'auto': {'opts': {'tag': tag, 'user': useriden}},
|
|
183
185
|
}
|
|
184
186
|
with self._recursion_check():
|
|
185
187
|
|
|
@@ -201,11 +203,11 @@ class Triggers:
|
|
|
201
203
|
for _, trig in globs.get(tag):
|
|
202
204
|
await trig.execute(node, vars=vars)
|
|
203
205
|
|
|
204
|
-
async def runEdgeAdd(self, n1, verb, n2):
|
|
206
|
+
async def runEdgeAdd(self, n1, verb, n2, useriden):
|
|
205
207
|
n1form = n1.form.name if n1 else None
|
|
206
208
|
n2form = n2.form.name if n2 else None
|
|
207
209
|
n2iden = n2.iden() if n2 else None
|
|
208
|
-
varz = {'auto': {'opts': {'verb': verb, 'n2iden': n2iden}}}
|
|
210
|
+
varz = {'auto': {'opts': {'verb': verb, 'n2iden': n2iden, 'user': useriden}}}
|
|
209
211
|
with self._recursion_check():
|
|
210
212
|
cachekey = (n1form, verb, n2form)
|
|
211
213
|
cached = self.edgeaddcache.get(cachekey)
|
|
@@ -251,11 +253,11 @@ class Triggers:
|
|
|
251
253
|
for trig in cached:
|
|
252
254
|
await trig.execute(n1, vars=varz)
|
|
253
255
|
|
|
254
|
-
async def runEdgeDel(self, n1, verb, n2):
|
|
256
|
+
async def runEdgeDel(self, n1, verb, n2, useriden):
|
|
255
257
|
n1form = n1.form.name if n1 else None
|
|
256
258
|
n2form = n2.form.name if n2 else None
|
|
257
259
|
n2iden = n2.iden() if n2 else None
|
|
258
|
-
varz = {'auto': {'opts': {'verb': verb, 'n2iden': n2iden}}}
|
|
260
|
+
varz = {'auto': {'opts': {'verb': verb, 'n2iden': n2iden, 'user': useriden}}}
|
|
259
261
|
with self._recursion_check():
|
|
260
262
|
cachekey = (n1form, verb, n2form)
|
|
261
263
|
cached = self.edgedelcache.get(cachekey)
|
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, 223, 0)
|
|
227
227
|
verstring = '.'.join([str(x) for x in version])
|
|
228
|
-
commit = '
|
|
228
|
+
commit = 'b40e64b75fa2820856ad138b8ad9f8c4b6e9547e'
|
synapse/lib/view.py
CHANGED
|
@@ -58,6 +58,9 @@ class ViewApi(s_cell.CellApi):
|
|
|
58
58
|
@s_cell.adminapi()
|
|
59
59
|
async def saveNodeEdits(self, edits, meta):
|
|
60
60
|
meta['link:user'] = self.user.iden
|
|
61
|
+
user = meta.get('user', '')
|
|
62
|
+
if not s_common.isguid(user):
|
|
63
|
+
raise s_exc.BadArg(mesg=f'Meta argument requires user key to be a guid, got {user=}')
|
|
61
64
|
async with await self.view.snap(user=self.user) as snap:
|
|
62
65
|
return await snap.saveNodeEdits(edits, meta)
|
|
63
66
|
|
|
@@ -1584,57 +1587,57 @@ class View(s_nexus.Pusher): # type: ignore
|
|
|
1584
1587
|
layer = self.layers[0]
|
|
1585
1588
|
await layer.confirmLayerEditPerms(user, layer.iden, delete=True)
|
|
1586
1589
|
|
|
1587
|
-
async def runTagAdd(self, node, tag, valu):
|
|
1590
|
+
async def runTagAdd(self, node, tag, valu, useriden):
|
|
1588
1591
|
|
|
1589
1592
|
if self.core.migration or self.core.safemode:
|
|
1590
1593
|
return
|
|
1591
1594
|
|
|
1592
1595
|
# Run any trigger handlers
|
|
1593
|
-
await self.triggers.runTagAdd(node, tag)
|
|
1596
|
+
await self.triggers.runTagAdd(node, tag, useriden)
|
|
1594
1597
|
|
|
1595
|
-
async def runTagDel(self, node, tag, valu):
|
|
1598
|
+
async def runTagDel(self, node, tag, valu, useriden):
|
|
1596
1599
|
|
|
1597
1600
|
if self.core.migration or self.core.safemode:
|
|
1598
1601
|
return
|
|
1599
1602
|
|
|
1600
|
-
await self.triggers.runTagDel(node, tag)
|
|
1603
|
+
await self.triggers.runTagDel(node, tag, useriden)
|
|
1601
1604
|
|
|
1602
|
-
async def runNodeAdd(self, node):
|
|
1605
|
+
async def runNodeAdd(self, node, useriden):
|
|
1603
1606
|
|
|
1604
1607
|
if self.core.migration or self.core.safemode:
|
|
1605
1608
|
return
|
|
1606
1609
|
|
|
1607
|
-
await self.triggers.runNodeAdd(node)
|
|
1610
|
+
await self.triggers.runNodeAdd(node, useriden)
|
|
1608
1611
|
|
|
1609
|
-
async def runNodeDel(self, node):
|
|
1612
|
+
async def runNodeDel(self, node, useriden):
|
|
1610
1613
|
|
|
1611
1614
|
if self.core.migration or self.core.safemode:
|
|
1612
1615
|
return
|
|
1613
1616
|
|
|
1614
|
-
await self.triggers.runNodeDel(node)
|
|
1617
|
+
await self.triggers.runNodeDel(node, useriden)
|
|
1615
1618
|
|
|
1616
|
-
async def runPropSet(self, node, prop, oldv):
|
|
1619
|
+
async def runPropSet(self, node, prop, oldv, useriden):
|
|
1617
1620
|
'''
|
|
1618
1621
|
Handle when a prop set trigger event fired
|
|
1619
1622
|
'''
|
|
1620
1623
|
if self.core.migration or self.core.safemode:
|
|
1621
1624
|
return
|
|
1622
1625
|
|
|
1623
|
-
await self.triggers.runPropSet(node, prop, oldv)
|
|
1626
|
+
await self.triggers.runPropSet(node, prop, oldv, useriden)
|
|
1624
1627
|
|
|
1625
|
-
async def runEdgeAdd(self, n1, edge, n2):
|
|
1628
|
+
async def runEdgeAdd(self, n1, edge, n2, useriden):
|
|
1626
1629
|
|
|
1627
1630
|
if self.core.migration or self.core.safemode:
|
|
1628
1631
|
return
|
|
1629
1632
|
|
|
1630
|
-
await self.triggers.runEdgeAdd(n1, edge, n2)
|
|
1633
|
+
await self.triggers.runEdgeAdd(n1, edge, n2, useriden)
|
|
1631
1634
|
|
|
1632
|
-
async def runEdgeDel(self, n1, edge, n2):
|
|
1635
|
+
async def runEdgeDel(self, n1, edge, n2, useriden):
|
|
1633
1636
|
|
|
1634
1637
|
if self.core.migration or self.core.safemode:
|
|
1635
1638
|
return
|
|
1636
1639
|
|
|
1637
|
-
await self.triggers.runEdgeDel(n1, edge, n2)
|
|
1640
|
+
await self.triggers.runEdgeDel(n1, edge, n2, useriden)
|
|
1638
1641
|
|
|
1639
1642
|
async def addTrigger(self, tdef):
|
|
1640
1643
|
'''
|
synapse/models/files.py
CHANGED
|
@@ -390,7 +390,7 @@ class FileModule(s_module.CoreModule):
|
|
|
390
390
|
'doc': 'The typecode for the resource.',
|
|
391
391
|
}),
|
|
392
392
|
|
|
393
|
-
('pe:langid', ('int', {'enums': s_l_pe.getLangCodes()}), {
|
|
393
|
+
('pe:langid', ('int', {'min': 0, 'max': 0xffff, 'enums': s_l_pe.getLangCodes(), 'enums:strict': False}), {
|
|
394
394
|
'doc': 'The PE language id.',
|
|
395
395
|
}),
|
|
396
396
|
|
synapse/models/orgs.py
CHANGED
|
@@ -729,6 +729,9 @@ class OuModule(s_module.CoreModule):
|
|
|
729
729
|
|
|
730
730
|
('ext:id', ('str', {'strip': True}), {
|
|
731
731
|
'doc': 'An external identifier for the technique.'}),
|
|
732
|
+
|
|
733
|
+
('parent', ('ou:technique', {}), {
|
|
734
|
+
'doc': 'The parent technique for the technique.'}),
|
|
732
735
|
)),
|
|
733
736
|
('ou:technique:taxonomy', {}, ()),
|
|
734
737
|
('ou:orgtype', {}, ()),
|
synapse/tests/test_cortex.py
CHANGED
|
@@ -426,7 +426,7 @@ class CortexTest(s_t_utils.SynTest):
|
|
|
426
426
|
self.len(1, await core00.nodes('test:str=foo', opts=view00opts))
|
|
427
427
|
|
|
428
428
|
layr = core01.getLayer(layr01iden)
|
|
429
|
-
await layr.storNodeEdits((), {})
|
|
429
|
+
await layr.storNodeEdits((), {'user': s_common.guid()})
|
|
430
430
|
|
|
431
431
|
async def test_cortex_must_upgrade(self):
|
|
432
432
|
|