synapse 2.134.0__py310-none-any.whl → 2.136.0__py310-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 +10 -2
- synapse/cortex.py +43 -29
- synapse/lib/ast.py +106 -48
- synapse/lib/cell.py +13 -5
- synapse/lib/layer.py +13 -1
- synapse/lib/parser.py +8 -40
- synapse/lib/storm.lark +25 -25
- synapse/lib/storm.py +4 -2
- synapse/lib/storm_format.py +6 -4
- synapse/lib/stormlib/auth.py +25 -3
- synapse/lib/stormlib/compression.py +176 -0
- synapse/lib/stormlib/graph.py +2 -0
- synapse/lib/stormtypes.py +77 -31
- synapse/lib/types.py +4 -1
- synapse/lib/version.py +2 -2
- synapse/lib/view.py +4 -1
- synapse/tests/test_axon.py +8 -2
- synapse/tests/test_cortex.py +38 -4
- synapse/tests/test_lib_grammar.py +64 -64
- synapse/tests/test_lib_httpapi.py +53 -1
- synapse/tests/test_lib_layer.py +20 -0
- synapse/tests/test_lib_rstorm.py +1 -1
- synapse/tests/test_lib_storm.py +40 -5
- synapse/tests/test_lib_stormlib_auth.py +16 -3
- synapse/tests/test_lib_stormlib_compression.py +61 -0
- synapse/tests/test_lib_stormlib_model.py +1 -1
- synapse/tests/test_lib_stormtypes.py +59 -6
- synapse/tests/test_lib_trigger.py +1 -1
- synapse/tests/test_lib_types.py +4 -2
- {synapse-2.134.0.dist-info → synapse-2.136.0.dist-info}/METADATA +4 -5
- {synapse-2.134.0.dist-info → synapse-2.136.0.dist-info}/RECORD +34 -32
- {synapse-2.134.0.dist-info → synapse-2.136.0.dist-info}/LICENSE +0 -0
- {synapse-2.134.0.dist-info → synapse-2.136.0.dist-info}/WHEEL +0 -0
- {synapse-2.134.0.dist-info → synapse-2.136.0.dist-info}/top_level.txt +0 -0
synapse/axon.py
CHANGED
|
@@ -1355,12 +1355,14 @@ class Axon(s_cell.Cell):
|
|
|
1355
1355
|
|
|
1356
1356
|
link00, sock00 = await s_link.linksock(forceclose=True)
|
|
1357
1357
|
|
|
1358
|
+
feedtask = None
|
|
1359
|
+
|
|
1358
1360
|
try:
|
|
1359
1361
|
todo = s_common.todo(_spawn_readlines, sock00)
|
|
1360
1362
|
async with await s_base.Base.anit() as scope:
|
|
1361
1363
|
|
|
1362
1364
|
scope.schedCoro(s_coro.spawn(todo, log_conf=await self._getSpawnLogConf()))
|
|
1363
|
-
scope.schedCoro(self._sha256ToLink(sha256, link00))
|
|
1365
|
+
feedtask = scope.schedCoro(self._sha256ToLink(sha256, link00))
|
|
1364
1366
|
|
|
1365
1367
|
while not self.isfini:
|
|
1366
1368
|
|
|
@@ -1377,6 +1379,8 @@ class Axon(s_cell.Cell):
|
|
|
1377
1379
|
finally:
|
|
1378
1380
|
sock00.close()
|
|
1379
1381
|
await link00.fini()
|
|
1382
|
+
if feedtask is not None:
|
|
1383
|
+
await feedtask
|
|
1380
1384
|
|
|
1381
1385
|
async def csvrows(self, sha256, dialect='excel', **fmtparams):
|
|
1382
1386
|
await self._reqHas(sha256)
|
|
@@ -1385,12 +1389,14 @@ class Axon(s_cell.Cell):
|
|
|
1385
1389
|
|
|
1386
1390
|
link00, sock00 = await s_link.linksock(forceclose=True)
|
|
1387
1391
|
|
|
1392
|
+
feedtask = None
|
|
1393
|
+
|
|
1388
1394
|
try:
|
|
1389
1395
|
todo = s_common.todo(_spawn_readrows, sock00, dialect, fmtparams)
|
|
1390
1396
|
async with await s_base.Base.anit() as scope:
|
|
1391
1397
|
|
|
1392
1398
|
scope.schedCoro(s_coro.spawn(todo, log_conf=await self._getSpawnLogConf()))
|
|
1393
|
-
scope.schedCoro(self._sha256ToLink(sha256, link00))
|
|
1399
|
+
feedtask = scope.schedCoro(self._sha256ToLink(sha256, link00))
|
|
1394
1400
|
|
|
1395
1401
|
while not self.isfini:
|
|
1396
1402
|
|
|
@@ -1407,6 +1413,8 @@ class Axon(s_cell.Cell):
|
|
|
1407
1413
|
finally:
|
|
1408
1414
|
sock00.close()
|
|
1409
1415
|
await link00.fini()
|
|
1416
|
+
if feedtask is not None:
|
|
1417
|
+
await feedtask
|
|
1410
1418
|
|
|
1411
1419
|
async def jsonlines(self, sha256):
|
|
1412
1420
|
async for line in self.readlines(sha256):
|
synapse/cortex.py
CHANGED
|
@@ -82,6 +82,7 @@ import synapse.lib.stormlib.project as s_stormlib_project # NOQA
|
|
|
82
82
|
import synapse.lib.stormlib.version as s_stormlib_version # NOQA
|
|
83
83
|
import synapse.lib.stormlib.ethereum as s_stormlib_ethereum # NOQA
|
|
84
84
|
import synapse.lib.stormlib.modelext as s_stormlib_modelext # NOQA
|
|
85
|
+
import synapse.lib.stormlib.compression as s_stormlib_compression # NOQA
|
|
85
86
|
import synapse.lib.stormlib.notifications as s_stormlib_notifications # NOQA
|
|
86
87
|
|
|
87
88
|
logger = logging.getLogger(__name__)
|
|
@@ -1176,6 +1177,9 @@ class Cortex(s_oauth.OAuthMixin, s_cell.Cell): # type: ignore
|
|
|
1176
1177
|
|
|
1177
1178
|
self.view = None # The default/main view
|
|
1178
1179
|
|
|
1180
|
+
self._cortex_permdefs = []
|
|
1181
|
+
self._initCorePerms()
|
|
1182
|
+
|
|
1179
1183
|
# Reset the storm:log:level from the config value to an int for internal use.
|
|
1180
1184
|
self.conf['storm:log:level'] = s_common.normLogLevel(self.conf.get('storm:log:level'))
|
|
1181
1185
|
self.stormlog = self.conf.get('storm:log')
|
|
@@ -1475,65 +1479,72 @@ class Cortex(s_oauth.OAuthMixin, s_cell.Cell): # type: ignore
|
|
|
1475
1479
|
self.modsbyiface[name] = tuple(mods)
|
|
1476
1480
|
return mods
|
|
1477
1481
|
|
|
1478
|
-
|
|
1479
|
-
|
|
1480
|
-
|
|
1481
|
-
|
|
1482
|
-
{'perm': ('view',), 'gate': '
|
|
1483
|
-
|
|
1482
|
+
def _initCorePerms(self):
|
|
1483
|
+
self._cortex_permdefs.extend((
|
|
1484
|
+
{'perm': ('view',), 'gate': 'cortex',
|
|
1485
|
+
'desc': 'Controls all view permissions.'},
|
|
1486
|
+
{'perm': ('view', 'add'), 'gate': 'cortex',
|
|
1487
|
+
'desc': 'Controls access to add a new view including forks.'},
|
|
1484
1488
|
{'perm': ('view', 'read'), 'gate': 'view',
|
|
1485
|
-
|
|
1489
|
+
'desc': 'Used to control read access to a view.'},
|
|
1486
1490
|
|
|
1487
1491
|
{'perm': ('node',), 'gate': 'layer',
|
|
1488
|
-
|
|
1492
|
+
'desc': 'Controls all node edits in a layer.'},
|
|
1489
1493
|
{'perm': ('node', 'add'), 'gate': 'layer',
|
|
1490
|
-
|
|
1494
|
+
'desc': 'Controls adding any form of node in a layer.'},
|
|
1491
1495
|
{'perm': ('node', 'del'), 'gate': 'layer',
|
|
1492
|
-
|
|
1496
|
+
'desc': 'Controls removing any form of node in a layer.'},
|
|
1493
1497
|
|
|
1494
1498
|
{'perm': ('node', 'add', '<form>'), 'gate': 'layer',
|
|
1495
|
-
|
|
1496
|
-
|
|
1499
|
+
'ex': 'node.add.inet:ipv4',
|
|
1500
|
+
'desc': 'Controls adding a specific form of node in a layer.'},
|
|
1497
1501
|
{'perm': ('node', 'del', '<form>'), 'gate': 'layer',
|
|
1498
|
-
|
|
1502
|
+
'desc': 'Controls removing a specific form of node in a layer.'},
|
|
1499
1503
|
|
|
1500
1504
|
{'perm': ('node', 'tag'), 'gate': 'layer',
|
|
1501
|
-
|
|
1505
|
+
'desc': 'Controls editing any tag on any node in a layer.'},
|
|
1502
1506
|
{'perm': ('node', 'tag', 'add'), 'gate': 'layer',
|
|
1503
|
-
|
|
1507
|
+
'desc': 'Controls adding any tag on any node in a layer.'},
|
|
1504
1508
|
{'perm': ('node', 'tag', 'del'), 'gate': 'layer',
|
|
1505
|
-
|
|
1509
|
+
'desc': 'Controls removing any tag on any node in a layer.'},
|
|
1506
1510
|
|
|
1507
1511
|
{'perm': ('node', 'tag', 'add', '<tag...>'), 'gate': 'layer',
|
|
1508
|
-
|
|
1509
|
-
|
|
1512
|
+
'ex': 'node.tag.add.cno.mal.redtree',
|
|
1513
|
+
'desc': 'Controls adding a specific tag on any node in a layer.'},
|
|
1510
1514
|
{'perm': ('node', 'tag', 'del', '<tag...>'), 'gate': 'layer',
|
|
1511
|
-
|
|
1512
|
-
|
|
1515
|
+
'ex': 'node.tag.del.cno.mal.redtree',
|
|
1516
|
+
'desc': 'Controls removing a specific tag on any node in a layer.'},
|
|
1513
1517
|
|
|
1514
1518
|
{'perm': ('node', 'prop'), 'gate': 'layer',
|
|
1515
|
-
|
|
1519
|
+
'desc': 'Controls editing any prop on any node in the layer.'},
|
|
1516
1520
|
|
|
1517
1521
|
{'perm': ('node', 'prop', 'set'), 'gate': 'layer',
|
|
1518
|
-
|
|
1522
|
+
'desc': 'Controls setting any prop on any node in a layer.'},
|
|
1519
1523
|
{'perm': ('node', 'prop', 'set', '<prop>'), 'gate': 'layer',
|
|
1520
|
-
|
|
1521
|
-
|
|
1524
|
+
'ex': 'node.prop.set.inet:ipv4:asn',
|
|
1525
|
+
'desc': 'Controls setting a specific property on a node in a layer.'},
|
|
1522
1526
|
|
|
1523
1527
|
{'perm': ('node', 'prop', 'del'), 'gate': 'layer',
|
|
1524
|
-
|
|
1528
|
+
'desc': 'Controls removing any prop on any node in a layer.'},
|
|
1525
1529
|
{'perm': ('node', 'prop', 'del', '<prop>'), 'gate': 'layer',
|
|
1526
|
-
|
|
1527
|
-
|
|
1530
|
+
'ex': 'node.prop.del.inet:ipv4:asn',
|
|
1531
|
+
'desc': 'Controls removing a specific property from a node in a layer.'},
|
|
1528
1532
|
))
|
|
1533
|
+
for pdef in self._cortex_permdefs:
|
|
1534
|
+
s_storm.reqValidPermDef(pdef)
|
|
1529
1535
|
|
|
1530
|
-
|
|
1536
|
+
async def _getPermDefs(self):
|
|
1537
|
+
|
|
1538
|
+
permdefs = list(await s_cell.Cell._getPermDefs(self))
|
|
1539
|
+
permdefs.extend(self._cortex_permdefs)
|
|
1531
1540
|
|
|
1532
1541
|
for spkg in await self.getStormPkgs():
|
|
1533
1542
|
permdefs.extend(spkg.get('perms', ()))
|
|
1534
1543
|
|
|
1535
1544
|
for (path, ctor) in self.stormlibs:
|
|
1536
|
-
permdefs.extend(
|
|
1545
|
+
permdefs.extend(ctor._storm_lib_perms)
|
|
1546
|
+
|
|
1547
|
+
permdefs.sort(key=lambda x: x['perm'])
|
|
1537
1548
|
|
|
1538
1549
|
return tuple(permdefs)
|
|
1539
1550
|
|
|
@@ -3874,6 +3885,9 @@ class Cortex(s_oauth.OAuthMixin, s_cell.Cell): # type: ignore
|
|
|
3874
3885
|
'''
|
|
3875
3886
|
|
|
3876
3887
|
for path, ctor in s_stormtypes.registry.iterLibs():
|
|
3888
|
+
# Ensure each ctor's permdefs are valid
|
|
3889
|
+
for pdef in ctor._storm_lib_perms:
|
|
3890
|
+
s_storm.reqValidPermDef(pdef)
|
|
3877
3891
|
# Skip libbase which is registered as a default ctor in the storm Runtime
|
|
3878
3892
|
if path:
|
|
3879
3893
|
self.addStormLib(path, ctor)
|
synapse/lib/ast.py
CHANGED
|
@@ -1322,7 +1322,7 @@ class LiftTag(LiftOper):
|
|
|
1322
1322
|
|
|
1323
1323
|
async def lift(self, runt, path):
|
|
1324
1324
|
|
|
1325
|
-
tag = await
|
|
1325
|
+
tag = await self.kids[0].compute(runt, path)
|
|
1326
1326
|
|
|
1327
1327
|
if len(self.kids) == 3:
|
|
1328
1328
|
|
|
@@ -1403,7 +1403,7 @@ class LiftTagTag(LiftOper):
|
|
|
1403
1403
|
|
|
1404
1404
|
async def lift(self, runt, path):
|
|
1405
1405
|
|
|
1406
|
-
tagname = await
|
|
1406
|
+
tagname = await self.kids[0].compute(runt, path)
|
|
1407
1407
|
|
|
1408
1408
|
node = await runt.snap.getNodeByNdef(('syn:tag', tagname))
|
|
1409
1409
|
if node is None:
|
|
@@ -1448,7 +1448,7 @@ class LiftFormTag(LiftOper):
|
|
|
1448
1448
|
if not runt.model.form(form):
|
|
1449
1449
|
raise self.kids[0].addExcInfo(s_exc.NoSuchForm.init(form))
|
|
1450
1450
|
|
|
1451
|
-
tag = await
|
|
1451
|
+
tag = await self.kids[1].compute(runt, path)
|
|
1452
1452
|
|
|
1453
1453
|
if len(self.kids) == 4:
|
|
1454
1454
|
|
|
@@ -2507,7 +2507,18 @@ class HasTagPropCond(Cond):
|
|
|
2507
2507
|
async def getCondEval(self, runt):
|
|
2508
2508
|
|
|
2509
2509
|
async def cond(node, path):
|
|
2510
|
-
tag
|
|
2510
|
+
tag = await self.kids[0].compute(runt, path)
|
|
2511
|
+
name = await self.kids[1].compute(runt, path)
|
|
2512
|
+
|
|
2513
|
+
if tag == '*':
|
|
2514
|
+
return any(name in props for props in node.tagprops.values())
|
|
2515
|
+
|
|
2516
|
+
if '*' in tag:
|
|
2517
|
+
reobj = s_cache.getTagGlobRegx(tag)
|
|
2518
|
+
for tagname, props in node.tagprops.items():
|
|
2519
|
+
if reobj.fullmatch(tagname) and name in props:
|
|
2520
|
+
return True
|
|
2521
|
+
|
|
2511
2522
|
return node.hasTagProp(tag, name)
|
|
2512
2523
|
|
|
2513
2524
|
return cond
|
|
@@ -2707,11 +2718,12 @@ class TagPropCond(Cond):
|
|
|
2707
2718
|
|
|
2708
2719
|
async def getCondEval(self, runt):
|
|
2709
2720
|
|
|
2710
|
-
cmpr = await self.kids[
|
|
2721
|
+
cmpr = await self.kids[2].compute(runt, None)
|
|
2711
2722
|
|
|
2712
2723
|
async def cond(node, path):
|
|
2713
2724
|
|
|
2714
|
-
tag
|
|
2725
|
+
tag = await self.kids[0].compute(runt, path)
|
|
2726
|
+
name = await self.kids[1].compute(runt, path)
|
|
2715
2727
|
|
|
2716
2728
|
prop = runt.model.getTagProp(name)
|
|
2717
2729
|
if prop is None:
|
|
@@ -2719,7 +2731,7 @@ class TagPropCond(Cond):
|
|
|
2719
2731
|
raise self.kids[0].addExcInfo(s_exc.NoSuchTagProp(name=name, mesg=mesg))
|
|
2720
2732
|
|
|
2721
2733
|
# TODO cache on (cmpr, valu) for perf?
|
|
2722
|
-
valu = await self.kids[
|
|
2734
|
+
valu = await self.kids[3].compute(runt, path)
|
|
2723
2735
|
|
|
2724
2736
|
ctor = prop.type.getCmprCtor(cmpr)
|
|
2725
2737
|
if ctor is None:
|
|
@@ -3086,16 +3098,71 @@ class TagName(Value):
|
|
|
3086
3098
|
if self.isconst:
|
|
3087
3099
|
return self.constval
|
|
3088
3100
|
|
|
3101
|
+
if not isinstance(self.kids[0], Const):
|
|
3102
|
+
valu = await self.kids[0].compute(runt, path)
|
|
3103
|
+
valu = await s_stormtypes.toprim(valu)
|
|
3104
|
+
|
|
3105
|
+
if not isinstance(valu, str):
|
|
3106
|
+
mesg = 'Invalid value type for tag name, tag names must be strings.'
|
|
3107
|
+
raise s_exc.BadTypeValu(mesg=mesg)
|
|
3108
|
+
|
|
3109
|
+
normtupl = await runt.snap.getTagNorm(valu)
|
|
3110
|
+
return normtupl[0]
|
|
3111
|
+
|
|
3089
3112
|
vals = []
|
|
3090
3113
|
for kid in self.kids:
|
|
3091
3114
|
part = await kid.compute(runt, path)
|
|
3092
3115
|
if part is None:
|
|
3093
3116
|
mesg = f'Null value from var ${kid.name} is not allowed in tag names.'
|
|
3094
3117
|
raise kid.addExcInfo(s_exc.BadTypeValu(mesg=mesg))
|
|
3095
|
-
|
|
3118
|
+
|
|
3119
|
+
part = await tostr(part)
|
|
3120
|
+
partnorm = await runt.snap.getTagNorm(part)
|
|
3121
|
+
vals.append(partnorm[0])
|
|
3096
3122
|
|
|
3097
3123
|
return '.'.join(vals)
|
|
3098
3124
|
|
|
3125
|
+
async def computeTagArray(self, runt, path, excignore=()):
|
|
3126
|
+
|
|
3127
|
+
if self.isconst:
|
|
3128
|
+
return (self.constval,)
|
|
3129
|
+
|
|
3130
|
+
if not isinstance(self.kids[0], Const):
|
|
3131
|
+
tags = []
|
|
3132
|
+
vals = await self.kids[0].compute(runt, path)
|
|
3133
|
+
vals = await s_stormtypes.toprim(vals)
|
|
3134
|
+
|
|
3135
|
+
if not isinstance(vals, (tuple, list, set)):
|
|
3136
|
+
vals = (vals,)
|
|
3137
|
+
|
|
3138
|
+
for valu in vals:
|
|
3139
|
+
try:
|
|
3140
|
+
if not isinstance(valu, str):
|
|
3141
|
+
mesg = 'Invalid value type for tag name, tag names must be strings.'
|
|
3142
|
+
raise s_exc.BadTypeValu(mesg=mesg)
|
|
3143
|
+
|
|
3144
|
+
normtupl = await runt.snap.getTagNorm(valu)
|
|
3145
|
+
if normtupl is None:
|
|
3146
|
+
continue
|
|
3147
|
+
|
|
3148
|
+
tags.append(normtupl[0])
|
|
3149
|
+
except excignore:
|
|
3150
|
+
pass
|
|
3151
|
+
return tags
|
|
3152
|
+
|
|
3153
|
+
vals = []
|
|
3154
|
+
for kid in self.kids:
|
|
3155
|
+
part = await kid.compute(runt, path)
|
|
3156
|
+
if part is None:
|
|
3157
|
+
mesg = f'Null value from var ${kid.name} is not allowed in tag names.'
|
|
3158
|
+
raise kid.addExcInfo(s_exc.BadTypeValu(mesg=mesg))
|
|
3159
|
+
|
|
3160
|
+
part = await tostr(part)
|
|
3161
|
+
partnorm = await runt.snap.getTagNorm(part)
|
|
3162
|
+
vals.append(partnorm[0])
|
|
3163
|
+
|
|
3164
|
+
return ('.'.join(vals),)
|
|
3165
|
+
|
|
3099
3166
|
class TagMatch(TagName):
|
|
3100
3167
|
'''
|
|
3101
3168
|
Like TagName, but can have asterisks
|
|
@@ -3105,6 +3172,32 @@ class TagMatch(TagName):
|
|
|
3105
3172
|
# TODO support vars with asterisks?
|
|
3106
3173
|
return any('*' in kid.valu for kid in self.kids if isinstance(kid, Const))
|
|
3107
3174
|
|
|
3175
|
+
async def compute(self, runt, path):
|
|
3176
|
+
|
|
3177
|
+
if self.isconst:
|
|
3178
|
+
return self.constval
|
|
3179
|
+
|
|
3180
|
+
if not isinstance(self.kids[0], Const):
|
|
3181
|
+
valu = await self.kids[0].compute(runt, path)
|
|
3182
|
+
valu = await s_stormtypes.toprim(valu)
|
|
3183
|
+
|
|
3184
|
+
if not isinstance(valu, str):
|
|
3185
|
+
mesg = 'Invalid value type for tag name, tag names must be strings.'
|
|
3186
|
+
raise s_exc.BadTypeValu(mesg=mesg)
|
|
3187
|
+
|
|
3188
|
+
return valu
|
|
3189
|
+
|
|
3190
|
+
vals = []
|
|
3191
|
+
for kid in self.kids:
|
|
3192
|
+
part = await kid.compute(runt, path)
|
|
3193
|
+
if part is None:
|
|
3194
|
+
mesg = f'Null value from var ${kid.name} is not allowed in tag names.'
|
|
3195
|
+
raise s_exc.BadTypeValu(mesg=mesg)
|
|
3196
|
+
|
|
3197
|
+
vals.append(await tostr(part))
|
|
3198
|
+
|
|
3199
|
+
return '.'.join(vals)
|
|
3200
|
+
|
|
3108
3201
|
class Const(Value):
|
|
3109
3202
|
|
|
3110
3203
|
def __init__(self, astinfo, valu, kids=()):
|
|
@@ -3756,27 +3849,15 @@ class EditTagAdd(Edit):
|
|
|
3756
3849
|
async for node, path in genr:
|
|
3757
3850
|
|
|
3758
3851
|
try:
|
|
3759
|
-
names = await self.kids[oper_offset].
|
|
3760
|
-
names = await s_stormtypes.toprim(names)
|
|
3852
|
+
names = await self.kids[oper_offset].computeTagArray(runt, path, excignore=excignore)
|
|
3761
3853
|
except excignore:
|
|
3762
3854
|
yield node, path
|
|
3763
3855
|
await asyncio.sleep(0)
|
|
3764
3856
|
continue
|
|
3765
3857
|
|
|
3766
|
-
if not isinstance(names, tuple):
|
|
3767
|
-
names = (names,)
|
|
3768
|
-
|
|
3769
3858
|
for name in names:
|
|
3770
3859
|
|
|
3771
3860
|
try:
|
|
3772
|
-
if name is None:
|
|
3773
|
-
raise self.addExcInfo(s_exc.BadTypeValu(mesg='Null tag names are not allowed.'))
|
|
3774
|
-
|
|
3775
|
-
normtupl = await runt.snap.getTagNorm(name)
|
|
3776
|
-
if normtupl is None:
|
|
3777
|
-
continue
|
|
3778
|
-
|
|
3779
|
-
name, info = normtupl
|
|
3780
3861
|
parts = name.split('.')
|
|
3781
3862
|
|
|
3782
3863
|
runt.layerConfirm(('node', 'tag', 'add', *parts))
|
|
@@ -3802,26 +3883,15 @@ class EditTagDel(Edit):
|
|
|
3802
3883
|
|
|
3803
3884
|
async for node, path in genr:
|
|
3804
3885
|
|
|
3805
|
-
names = await self.kids[0].
|
|
3806
|
-
names = await s_stormtypes.toprim(names)
|
|
3807
|
-
|
|
3808
|
-
if not isinstance(names, tuple):
|
|
3809
|
-
names = (names,)
|
|
3886
|
+
names = await self.kids[0].computeTagArray(runt, path, excignore=(s_exc.BadTypeValu,))
|
|
3810
3887
|
|
|
3811
3888
|
for name in names:
|
|
3812
3889
|
|
|
3813
|
-
|
|
3814
|
-
if name:
|
|
3815
|
-
normtupl = await runt.snap.getTagNorm(name)
|
|
3816
|
-
if normtupl is None:
|
|
3817
|
-
continue
|
|
3818
|
-
|
|
3819
|
-
name, info = normtupl
|
|
3820
|
-
parts = name.split('.')
|
|
3890
|
+
parts = name.split('.')
|
|
3821
3891
|
|
|
3822
|
-
|
|
3892
|
+
runt.layerConfirm(('node', 'tag', 'del', *parts))
|
|
3823
3893
|
|
|
3824
|
-
|
|
3894
|
+
await node.delTag(name)
|
|
3825
3895
|
|
|
3826
3896
|
yield node, path
|
|
3827
3897
|
|
|
@@ -3847,11 +3917,6 @@ class EditTagPropSet(Edit):
|
|
|
3847
3917
|
valu = await self.kids[2].compute(runt, path)
|
|
3848
3918
|
valu = await s_stormtypes.tostor(valu)
|
|
3849
3919
|
|
|
3850
|
-
normtupl = await runt.snap.getTagNorm(tag)
|
|
3851
|
-
if normtupl is None:
|
|
3852
|
-
continue
|
|
3853
|
-
|
|
3854
|
-
tag, info = normtupl
|
|
3855
3920
|
tagparts = tag.split('.')
|
|
3856
3921
|
|
|
3857
3922
|
# for now, use the tag add perms
|
|
@@ -3881,13 +3946,6 @@ class EditTagPropDel(Edit):
|
|
|
3881
3946
|
async for node, path in genr:
|
|
3882
3947
|
|
|
3883
3948
|
tag, prop = await self.kids[0].compute(runt, path)
|
|
3884
|
-
|
|
3885
|
-
normtupl = await runt.snap.getTagNorm(tag)
|
|
3886
|
-
if normtupl is None:
|
|
3887
|
-
continue
|
|
3888
|
-
|
|
3889
|
-
tag, info = normtupl
|
|
3890
|
-
|
|
3891
3949
|
tagparts = tag.split('.')
|
|
3892
3950
|
|
|
3893
3951
|
# for now, use the tag add perms
|
synapse/lib/cell.py
CHANGED
|
@@ -570,8 +570,8 @@ class CellApi(s_base.Base):
|
|
|
570
570
|
return await self.cell.setUserEmail(useriden, email)
|
|
571
571
|
|
|
572
572
|
@adminapi(log=True)
|
|
573
|
-
async def addUserRole(self, useriden, roleiden):
|
|
574
|
-
return await self.cell.addUserRole(useriden, roleiden)
|
|
573
|
+
async def addUserRole(self, useriden, roleiden, indx=None):
|
|
574
|
+
return await self.cell.addUserRole(useriden, roleiden, indx=indx)
|
|
575
575
|
|
|
576
576
|
@adminapi(log=True)
|
|
577
577
|
async def setUserRoles(self, useriden, roleidens):
|
|
@@ -884,6 +884,11 @@ class Cell(s_nexus.Pusher, s_telepath.Aware):
|
|
|
884
884
|
'type': 'object',
|
|
885
885
|
'hidecmdl': True,
|
|
886
886
|
},
|
|
887
|
+
'https:parse:proxy:remoteip': {
|
|
888
|
+
'description': 'Enable the HTTPS server to parse X-Forwarded-For and X-Real-IP headers to determine requester IP addresses.',
|
|
889
|
+
'type': 'boolean',
|
|
890
|
+
'default': False,
|
|
891
|
+
},
|
|
887
892
|
'backup:dir': {
|
|
888
893
|
'description': 'A directory outside the service directory where backups will be saved. Defaults to ./backups in the service storage directory.',
|
|
889
894
|
'type': 'string',
|
|
@@ -2286,10 +2291,10 @@ class Cell(s_nexus.Pusher, s_telepath.Aware):
|
|
|
2286
2291
|
extra=await self.getLogExtra(target_user=user.iden, target_username=user.name,
|
|
2287
2292
|
gateiden=gateiden))
|
|
2288
2293
|
|
|
2289
|
-
async def addUserRole(self, useriden, roleiden):
|
|
2294
|
+
async def addUserRole(self, useriden, roleiden, indx=None):
|
|
2290
2295
|
user = await self.auth.reqUser(useriden)
|
|
2291
2296
|
role = await self.auth.reqRole(roleiden)
|
|
2292
|
-
await user.grant(roleiden)
|
|
2297
|
+
await user.grant(roleiden, indx=indx)
|
|
2293
2298
|
logger.info(f'Granted role {role.name} to user {user.name}',
|
|
2294
2299
|
extra=await self.getLogExtra(target_user=user.iden, target_username=user.name,
|
|
2295
2300
|
target_role=role.iden, target_rolename=role.name))
|
|
@@ -2584,7 +2589,10 @@ class Cell(s_nexus.Pusher, s_telepath.Aware):
|
|
|
2584
2589
|
|
|
2585
2590
|
sslctx = self.initSslCtx(certpath, pkeypath)
|
|
2586
2591
|
|
|
2587
|
-
|
|
2592
|
+
kwargs = {
|
|
2593
|
+
'xheaders': self.conf.reqConfValu('https:parse:proxy:remoteip')
|
|
2594
|
+
}
|
|
2595
|
+
serv = self.wapp.listen(port, address=addr, ssl_options=sslctx, **kwargs)
|
|
2588
2596
|
self.httpds.append(serv)
|
|
2589
2597
|
return list(serv._sockets.values())[0].getsockname()
|
|
2590
2598
|
|
synapse/lib/layer.py
CHANGED
|
@@ -2483,7 +2483,10 @@ class Layer(s_nexus.Pusher):
|
|
|
2483
2483
|
self.logedits = valu
|
|
2484
2484
|
|
|
2485
2485
|
# TODO when we can set more props, we may need to parse values.
|
|
2486
|
-
|
|
2486
|
+
if valu is None:
|
|
2487
|
+
await self.layrinfo.pop(name)
|
|
2488
|
+
else:
|
|
2489
|
+
await self.layrinfo.set(name, valu)
|
|
2487
2490
|
|
|
2488
2491
|
await self.core.feedBeholder('layer:set', {'iden': self.iden, 'name': name, 'valu': valu}, gates=[self.iden])
|
|
2489
2492
|
return valu
|
|
@@ -3247,6 +3250,15 @@ class Layer(s_nexus.Pusher):
|
|
|
3247
3250
|
oldv, oldt = tp_dict.get(prop, (None, None))
|
|
3248
3251
|
if oldv is not None:
|
|
3249
3252
|
|
|
3253
|
+
if stortype == STOR_TYPE_IVAL:
|
|
3254
|
+
valu = (min(*oldv, *valu), max(*oldv, *valu))
|
|
3255
|
+
|
|
3256
|
+
elif stortype == STOR_TYPE_MINTIME:
|
|
3257
|
+
valu = min(valu, oldv)
|
|
3258
|
+
|
|
3259
|
+
elif stortype == STOR_TYPE_MAXTIME:
|
|
3260
|
+
valu = max(valu, oldv)
|
|
3261
|
+
|
|
3250
3262
|
if valu == oldv and stortype == oldt:
|
|
3251
3263
|
return ()
|
|
3252
3264
|
|
synapse/lib/parser.py
CHANGED
|
@@ -56,6 +56,7 @@ terminalEnglishMap = {
|
|
|
56
56
|
'EXPRNEG': '-',
|
|
57
57
|
'EXPRPLUS': '+',
|
|
58
58
|
'EXPRPOW': '**',
|
|
59
|
+
'EXPRTAGSEGNOVAR': 'non-variable tag segment',
|
|
59
60
|
'EXPRTIMES': '*',
|
|
60
61
|
'FOR': 'for',
|
|
61
62
|
'FORMATSTRING': 'backtick-quoted format string',
|
|
@@ -84,8 +85,8 @@ terminalEnglishMap = {
|
|
|
84
85
|
'SETTAGOPER': '?',
|
|
85
86
|
'SINGLEQUOTEDSTRING': 'single-quoted string',
|
|
86
87
|
'SWITCH': 'switch',
|
|
88
|
+
'TAGSEGNOVAR': 'non-variable tag segment',
|
|
87
89
|
'TRY': 'try',
|
|
88
|
-
'TAGMATCH': 'tag name potentially with asterisks',
|
|
89
90
|
'TRIPLEQUOTEDSTRING': 'triple-quoted string',
|
|
90
91
|
'TRYSET': '?=',
|
|
91
92
|
'TRYSETPLUS': '?+=',
|
|
@@ -98,6 +99,7 @@ terminalEnglishMap = {
|
|
|
98
99
|
'WHILE': 'while',
|
|
99
100
|
'WHITETOKN': 'An unquoted string terminated by whitespace',
|
|
100
101
|
'WILDCARD': '*',
|
|
102
|
+
'WILDTAGSEGNOVAR': 'tag segment potentially with asterisks',
|
|
101
103
|
'YIELD': 'yield',
|
|
102
104
|
'_ARRAYCONDSTART': '*[',
|
|
103
105
|
'_COLONDOLLAR': ':$',
|
|
@@ -111,21 +113,21 @@ terminalEnglishMap = {
|
|
|
111
113
|
'_EDGEN2FINI': ')-',
|
|
112
114
|
'_ELSE': 'else',
|
|
113
115
|
'_EMBEDQUERYSTART': '${',
|
|
116
|
+
'_EXPRCOLONNOSPACE': ':',
|
|
114
117
|
'_EMIT': 'emit',
|
|
115
118
|
'_FINI': 'fini',
|
|
116
119
|
'_HASH': '#',
|
|
117
|
-
'_EXPRHASH': '#',
|
|
118
120
|
'_HASHSPACE': '#',
|
|
119
|
-
'_EXPRHASHSPACE': '#',
|
|
120
121
|
'_INIT': 'init',
|
|
121
122
|
'_LEFTJOIN': '<+-',
|
|
122
123
|
'_LEFTPIVOT': '<-',
|
|
123
124
|
'_LPARNOSPACE': '(',
|
|
125
|
+
'_MATCHHASH': '#',
|
|
126
|
+
'_MATCHHASHSPACE': '#',
|
|
124
127
|
'_RETURN': 'return',
|
|
125
128
|
'_RIGHTJOIN': '-+>',
|
|
126
129
|
'_RIGHTPIVOT': '->',
|
|
127
130
|
'_STOP': 'stop',
|
|
128
|
-
'_TAGSEGNOVAR': 'tag segment potentially with asterisks',
|
|
129
131
|
'_WALKNPIVON1': '-->',
|
|
130
132
|
'_WALKNPIVON2': '<--',
|
|
131
133
|
'$END': 'end of input',
|
|
@@ -404,25 +406,6 @@ class AstConverter(lark.Transformer):
|
|
|
404
406
|
|
|
405
407
|
return argv
|
|
406
408
|
|
|
407
|
-
@classmethod
|
|
408
|
-
def _tagsplit(cls, astinfo, tag):
|
|
409
|
-
|
|
410
|
-
if '$' not in tag:
|
|
411
|
-
return [s_ast.Const(astinfo, tag)]
|
|
412
|
-
|
|
413
|
-
kids = []
|
|
414
|
-
segs = tag.split('.')
|
|
415
|
-
|
|
416
|
-
for seg in segs:
|
|
417
|
-
|
|
418
|
-
if seg[0] == '$':
|
|
419
|
-
kids.append(s_ast.VarValue(astinfo, kids=[s_ast.Const(astinfo, seg[1:])]))
|
|
420
|
-
continue
|
|
421
|
-
|
|
422
|
-
kids.append(s_ast.Const(astinfo, seg))
|
|
423
|
-
|
|
424
|
-
return kids
|
|
425
|
-
|
|
426
409
|
@lark.v_args(meta=True)
|
|
427
410
|
def varderef(self, meta, kids):
|
|
428
411
|
assert kids and len(kids) in (3, 4)
|
|
@@ -435,22 +418,6 @@ class AstConverter(lark.Transformer):
|
|
|
435
418
|
newkid = self._convert_child(kids[2])
|
|
436
419
|
return s_ast.VarDeref(astinfo, kids=(kids[0], newkid))
|
|
437
420
|
|
|
438
|
-
@lark.v_args(meta=True)
|
|
439
|
-
def tagname(self, meta, kids):
|
|
440
|
-
assert kids and len(kids) == 1
|
|
441
|
-
astinfo = self.metaToAstInfo(meta)
|
|
442
|
-
kid = kids[0]
|
|
443
|
-
if not isinstance(kid, lark.lexer.Token):
|
|
444
|
-
return self._convert_child(kid)
|
|
445
|
-
|
|
446
|
-
valu = kid.value
|
|
447
|
-
if '*' in valu:
|
|
448
|
-
mesg = f"Invalid wildcard usage in tag {valu}"
|
|
449
|
-
self.raiseBadSyntax(mesg, astinfo)
|
|
450
|
-
|
|
451
|
-
kids = self._tagsplit(astinfo, valu)
|
|
452
|
-
return s_ast.TagName(astinfo, kids=kids)
|
|
453
|
-
|
|
454
421
|
@lark.v_args(meta=True)
|
|
455
422
|
def switchcase(self, meta, kids):
|
|
456
423
|
|
|
@@ -639,7 +606,6 @@ terminalClassMap = {
|
|
|
639
606
|
'HEXNUMBER': lambda astinfo, x: s_ast.Const(astinfo, s_ast.parseNumber(x)),
|
|
640
607
|
'BOOL': lambda astinfo, x: s_ast.Bool(astinfo, x == 'true'),
|
|
641
608
|
'SINGLEQUOTEDSTRING': lambda astinfo, x: s_ast.Const(astinfo, x[1:-1]), # drop quotes
|
|
642
|
-
'TAGMATCH': lambda astinfo, x: s_ast.TagMatch(astinfo, kids=AstConverter._tagsplit(astinfo, x)),
|
|
643
609
|
'NONQUOTEWORD': massage_vartokn,
|
|
644
610
|
'VARTOKN': massage_vartokn,
|
|
645
611
|
'EXPRVARTOKN': massage_vartokn,
|
|
@@ -734,6 +700,8 @@ ruleClassMap = {
|
|
|
734
700
|
'stormcmd': lambda astinfo, kids: s_ast.CmdOper(astinfo, kids=kids if len(kids) == 2 else (kids[0], s_ast.Const(astinfo, tuple()))),
|
|
735
701
|
'stormfunc': s_ast.Function,
|
|
736
702
|
'tagcond': s_ast.TagCond,
|
|
703
|
+
'tagname': s_ast.TagName,
|
|
704
|
+
'tagmatch': s_ast.TagMatch,
|
|
737
705
|
'tagprop': s_ast.TagProp,
|
|
738
706
|
'tagvalu': s_ast.TagValue,
|
|
739
707
|
'tagpropvalu': s_ast.TagPropValue,
|