synapse 2.222.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 +109 -30
- synapse/cryotank.py +1 -1
- synapse/lib/ast.py +5 -3
- synapse/lib/nexus.py +1 -1
- synapse/lib/snap.py +15 -9
- synapse/lib/storm.py +0 -190
- synapse/lib/stormlib/auth.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 +24 -174
- 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/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_storm.py +31 -248
- 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 +0 -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/tools/cryo/cat.py +2 -1
- synapse/tools/cryo/list.py +2 -0
- {synapse-2.222.0.dist-info → synapse-2.223.0.dist-info}/METADATA +1 -1
- {synapse-2.222.0.dist-info → synapse-2.223.0.dist-info}/RECORD +34 -30
- {synapse-2.222.0.dist-info → synapse-2.223.0.dist-info}/WHEEL +0 -0
- {synapse-2.222.0.dist-info → synapse-2.223.0.dist-info}/licenses/LICENSE +0 -0
- {synapse-2.222.0.dist-info → synapse-2.223.0.dist-info}/top_level.txt +0 -0
synapse/cortex.py
CHANGED
|
@@ -61,6 +61,7 @@ import synapse.lib.stormlib.gen as s_stormlib_gen # NOQA
|
|
|
61
61
|
import synapse.lib.stormlib.gis as s_stormlib_gis # NOQA
|
|
62
62
|
import synapse.lib.stormlib.hex as s_stormlib_hex # NOQA
|
|
63
63
|
import synapse.lib.stormlib.log as s_stormlib_log # NOQA
|
|
64
|
+
import synapse.lib.stormlib.pkg as s_stormlib_pkg # NOQA
|
|
64
65
|
import synapse.lib.stormlib.xml as s_stormlib_xml # NOQA
|
|
65
66
|
import synapse.lib.stormlib.auth as s_stormlib_auth # NOQA
|
|
66
67
|
import synapse.lib.stormlib.cell as s_stormlib_cell # NOQA
|
|
@@ -72,6 +73,7 @@ import synapse.lib.stormlib.mime as s_stormlib_mime # NOQA
|
|
|
72
73
|
import synapse.lib.stormlib.pack as s_stormlib_pack # NOQA
|
|
73
74
|
import synapse.lib.stormlib.smtp as s_stormlib_smtp # NOQA
|
|
74
75
|
import synapse.lib.stormlib.stix as s_stormlib_stix # NOQA
|
|
76
|
+
import synapse.lib.stormlib.task as s_stormlib_task # NOQA
|
|
75
77
|
import synapse.lib.stormlib.yaml as s_stormlib_yaml # NOQA
|
|
76
78
|
import synapse.lib.stormlib.basex as s_stormlib_basex # NOQA
|
|
77
79
|
import synapse.lib.stormlib.cache as s_stormlib_cache # NOQA
|
|
@@ -2262,6 +2264,7 @@ class Cortex(s_oauth.OAuthMixin, s_cell.Cell): # type: ignore
|
|
|
2262
2264
|
self.onfini(slab.fini)
|
|
2263
2265
|
|
|
2264
2266
|
self.multiqueue = await slab.getMultiQueue('cortex:queue', nexsroot=self.nexsroot)
|
|
2267
|
+
self.stormpkgqueue = await slab.getMultiQueue('storm:pkg:queue', nexsroot=self.nexsroot)
|
|
2265
2268
|
|
|
2266
2269
|
async def _initStormGraphs(self):
|
|
2267
2270
|
path = os.path.join(self.dirn, 'slabs', 'graphs.lmdb')
|
|
@@ -3062,8 +3065,8 @@ class Cortex(s_oauth.OAuthMixin, s_cell.Cell): # type: ignore
|
|
|
3062
3065
|
if not ok:
|
|
3063
3066
|
break
|
|
3064
3067
|
|
|
3065
|
-
curvers = vers
|
|
3066
|
-
await self.setStormPkgVar(name, varname,
|
|
3068
|
+
curvers = max(vers, await self.getStormPkgVar(name, varname, default=-1))
|
|
3069
|
+
await self.setStormPkgVar(name, varname, curvers)
|
|
3067
3070
|
logger.info(f'{name} finished init vers={vers}: {vname}', extra=logextra)
|
|
3068
3071
|
|
|
3069
3072
|
if onload is not None:
|
|
@@ -3348,6 +3351,91 @@ class Cortex(s_oauth.OAuthMixin, s_cell.Cell): # type: ignore
|
|
|
3348
3351
|
for item in pkgvars.items():
|
|
3349
3352
|
yield item
|
|
3350
3353
|
|
|
3354
|
+
async def addStormPkgQueue(self, pkgname, name):
|
|
3355
|
+
guid = s_common.guid((pkgname, name))
|
|
3356
|
+
if self.stormpkgqueue.exists(guid):
|
|
3357
|
+
mesg = f'Queue named {name} already exists for package {pkgname}!'
|
|
3358
|
+
raise s_exc.DupName(mesg=mesg)
|
|
3359
|
+
|
|
3360
|
+
info = {
|
|
3361
|
+
'iden': guid,
|
|
3362
|
+
'name': name,
|
|
3363
|
+
'pkgname': pkgname,
|
|
3364
|
+
'created': s_common.now()
|
|
3365
|
+
}
|
|
3366
|
+
|
|
3367
|
+
await self._push('storm:pkg:queue:add', pkgname, name, info)
|
|
3368
|
+
|
|
3369
|
+
@s_nexus.Pusher.onPush('storm:pkg:queue:add')
|
|
3370
|
+
async def _addStormPkgQueue(self, pkgname, name, info):
|
|
3371
|
+
guid = s_common.guid((pkgname, name))
|
|
3372
|
+
if self.stormpkgqueue.exists(guid):
|
|
3373
|
+
return
|
|
3374
|
+
await self.stormpkgqueue.add(guid, info)
|
|
3375
|
+
|
|
3376
|
+
async def listStormPkgQueues(self, pkgname=None):
|
|
3377
|
+
for pkginfo in self.stormpkgqueue.list():
|
|
3378
|
+
if pkgname is None or pkginfo['meta'].get('pkgname') == pkgname:
|
|
3379
|
+
yield pkginfo
|
|
3380
|
+
|
|
3381
|
+
async def getStormPkgQueue(self, pkgname, name):
|
|
3382
|
+
guid = s_common.guid((pkgname, name))
|
|
3383
|
+
return self.stormpkgqueue.status(guid)
|
|
3384
|
+
|
|
3385
|
+
async def delStormPkgQueue(self, pkgname, name):
|
|
3386
|
+
guid = s_common.guid((pkgname, name))
|
|
3387
|
+
if not self.stormpkgqueue.exists(guid):
|
|
3388
|
+
mesg = f'No queue named {name} exists for package {pkgname}!'
|
|
3389
|
+
raise s_exc.NoSuchName(mesg=mesg)
|
|
3390
|
+
|
|
3391
|
+
await self._push('storm:pkg:queue:del', pkgname, name)
|
|
3392
|
+
|
|
3393
|
+
@s_nexus.Pusher.onPush('storm:pkg:queue:del')
|
|
3394
|
+
async def _delStormPkgQueue(self, pkgname, name):
|
|
3395
|
+
guid = s_common.guid((pkgname, name))
|
|
3396
|
+
if not self.stormpkgqueue.exists(guid):
|
|
3397
|
+
return
|
|
3398
|
+
await self.stormpkgqueue.rem(guid)
|
|
3399
|
+
|
|
3400
|
+
async def stormPkgQueueGet(self, pkgname, name, offs=0, wait=False):
|
|
3401
|
+
guid = s_common.guid((pkgname, name))
|
|
3402
|
+
async for item in self.stormpkgqueue.gets(guid, offs, cull=False, wait=wait):
|
|
3403
|
+
return item
|
|
3404
|
+
|
|
3405
|
+
async def stormPkgQueueGets(self, pkgname, name, offs=0, wait=False, size=None):
|
|
3406
|
+
count = 0
|
|
3407
|
+
guid = s_common.guid((pkgname, name))
|
|
3408
|
+
async for item in self.stormpkgqueue.gets(guid, offs, cull=False, wait=wait):
|
|
3409
|
+
|
|
3410
|
+
yield item
|
|
3411
|
+
|
|
3412
|
+
count += 1
|
|
3413
|
+
if size is not None and count >= size:
|
|
3414
|
+
return
|
|
3415
|
+
|
|
3416
|
+
async def stormPkgQueuePuts(self, pkgname, name, items):
|
|
3417
|
+
return await self._push('storm:pkg:queue:puts', pkgname, name, items)
|
|
3418
|
+
|
|
3419
|
+
@s_nexus.Pusher.onPush('storm:pkg:queue:puts', passitem=True)
|
|
3420
|
+
async def _stormPkgQueuePuts(self, pkgname, name, items, nexsitem):
|
|
3421
|
+
nexsoff, nexsmesg = nexsitem
|
|
3422
|
+
guid = s_common.guid((pkgname, name))
|
|
3423
|
+
return await self.stormpkgqueue.puts(guid, items, reqid=nexsoff)
|
|
3424
|
+
|
|
3425
|
+
@s_nexus.Pusher.onPushAuto('storm:pkg:queue:cull')
|
|
3426
|
+
async def stormPkgQueueCull(self, pkgname, name, offs):
|
|
3427
|
+
guid = s_common.guid((pkgname, name))
|
|
3428
|
+
await self.stormpkgqueue.cull(guid, offs)
|
|
3429
|
+
|
|
3430
|
+
@s_nexus.Pusher.onPushAuto('storm:pkg:queue:pop')
|
|
3431
|
+
async def stormPkgQueuePop(self, pkgname, name, offs):
|
|
3432
|
+
guid = s_common.guid((pkgname, name))
|
|
3433
|
+
return await self.stormpkgqueue.pop(guid, offs)
|
|
3434
|
+
|
|
3435
|
+
async def stormPkgQueueSize(self, pkgname, name):
|
|
3436
|
+
guid = s_common.guid((pkgname, name))
|
|
3437
|
+
return self.stormpkgqueue.size(guid)
|
|
3438
|
+
|
|
3351
3439
|
async def _cortexHealth(self, health):
|
|
3352
3440
|
health.update('cortex', 'nominal')
|
|
3353
3441
|
|
|
@@ -4568,34 +4656,25 @@ class Cortex(s_oauth.OAuthMixin, s_cell.Cell): # type: ignore
|
|
|
4568
4656
|
self.addStormCmd(s_stormlib_cortex.StormPoolGetCmd)
|
|
4569
4657
|
self.addStormCmd(s_stormlib_cortex.StormPoolSetCmd)
|
|
4570
4658
|
|
|
4571
|
-
|
|
4572
|
-
|
|
4573
|
-
|
|
4574
|
-
|
|
4575
|
-
|
|
4576
|
-
|
|
4577
|
-
|
|
4578
|
-
|
|
4579
|
-
|
|
4580
|
-
|
|
4581
|
-
|
|
4582
|
-
|
|
4583
|
-
|
|
4584
|
-
|
|
4585
|
-
|
|
4586
|
-
|
|
4587
|
-
|
|
4588
|
-
|
|
4589
|
-
for cdef in
|
|
4590
|
-
await self._trySetStormCmd(cdef.get('name'), cdef)
|
|
4591
|
-
|
|
4592
|
-
for cdef in s_stormlib_cortex.stormcmds:
|
|
4593
|
-
await self._trySetStormCmd(cdef.get('name'), cdef)
|
|
4594
|
-
|
|
4595
|
-
for cdef in s_stormlib_vault.stormcmds:
|
|
4596
|
-
await self._trySetStormCmd(cdef.get('name'), cdef)
|
|
4597
|
-
|
|
4598
|
-
for cdef in s_stormlib_index.stormcmds:
|
|
4659
|
+
cmdmods = [
|
|
4660
|
+
s_storm,
|
|
4661
|
+
s_stormsvc,
|
|
4662
|
+
s_stormlib_aha,
|
|
4663
|
+
s_stormlib_auth,
|
|
4664
|
+
s_stormlib_cortex,
|
|
4665
|
+
s_stormlib_gen,
|
|
4666
|
+
s_stormlib_index,
|
|
4667
|
+
s_stormlib_macro,
|
|
4668
|
+
s_stormlib_model,
|
|
4669
|
+
s_stormlib_pkg,
|
|
4670
|
+
s_stormlib_vault,
|
|
4671
|
+
]
|
|
4672
|
+
|
|
4673
|
+
for cmod in cmdmods:
|
|
4674
|
+
for cdef in cmod.stormcmds:
|
|
4675
|
+
await self._trySetStormCmd(cdef.get('name'), cdef)
|
|
4676
|
+
|
|
4677
|
+
for cdef in s_stormlib_task.stormcmds:
|
|
4599
4678
|
await self._trySetStormCmd(cdef.get('name'), cdef)
|
|
4600
4679
|
|
|
4601
4680
|
async def _initPureStormCmds(self):
|
synapse/cryotank.py
CHANGED
|
@@ -39,7 +39,7 @@ class CryoTank(s_base.Base):
|
|
|
39
39
|
A CryoTank implements a stream of structured data.
|
|
40
40
|
'''
|
|
41
41
|
async def __anit__(self, dirn, iden, conf=None):
|
|
42
|
-
|
|
42
|
+
s_common.deprecated('synapse.cryotank.CryoTank', curv='2.223.0')
|
|
43
43
|
await s_base.Base.__anit__(self)
|
|
44
44
|
|
|
45
45
|
if conf is None:
|
synapse/lib/ast.py
CHANGED
|
@@ -4527,9 +4527,6 @@ class N1Walk(Oper):
|
|
|
4527
4527
|
|
|
4528
4528
|
def buildfilter(self, runt, destforms, cmpr):
|
|
4529
4529
|
|
|
4530
|
-
if not isinstance(destforms, (tuple, list)):
|
|
4531
|
-
destforms = (destforms,)
|
|
4532
|
-
|
|
4533
4530
|
if '*' in destforms:
|
|
4534
4531
|
if cmpr is not None:
|
|
4535
4532
|
mesg = 'Wild card walk operations do not support comparison.'
|
|
@@ -4614,6 +4611,11 @@ class N1Walk(Oper):
|
|
|
4614
4611
|
dest = await self.kids[1].compute(runt, path)
|
|
4615
4612
|
dest = await s_stormtypes.toprim(dest)
|
|
4616
4613
|
|
|
4614
|
+
if isinstance(dest, (tuple, list)):
|
|
4615
|
+
dest = [await s_stormtypes.tostr(form) for form in dest]
|
|
4616
|
+
else:
|
|
4617
|
+
dest = (await s_stormtypes.tostr(dest),)
|
|
4618
|
+
|
|
4617
4619
|
destfilt = self.buildfilter(runt, dest, cmpr)
|
|
4618
4620
|
|
|
4619
4621
|
for verb in verbs:
|
synapse/lib/nexus.py
CHANGED
|
@@ -572,7 +572,7 @@ class NexsRoot(s_base.Base):
|
|
|
572
572
|
|
|
573
573
|
offs, args = item
|
|
574
574
|
if offs != self.nexslog.index():
|
|
575
|
-
logger.error('Local Nexus offset is out of sync from remote cell! Aborting mirror sync')
|
|
575
|
+
logger.error(f'Local Nexus offset is out of sync from remote cell! Aborting mirror sync. Local offs={self.nexslog.index()}, Remote {offs=}')
|
|
576
576
|
await self.fini()
|
|
577
577
|
return
|
|
578
578
|
|
synapse/lib/snap.py
CHANGED
|
@@ -1305,6 +1305,11 @@ class Snap(s_base.Base):
|
|
|
1305
1305
|
mesg = 'The snapshot is in read-only mode.'
|
|
1306
1306
|
raise s_exc.IsReadOnly(mesg=mesg)
|
|
1307
1307
|
|
|
1308
|
+
useriden = meta.get('user')
|
|
1309
|
+
if useriden is None:
|
|
1310
|
+
mesg = 'meta is missing user key. Cannot process edits.'
|
|
1311
|
+
raise s_exc.BadArg(mesg=mesg, name='user')
|
|
1312
|
+
|
|
1308
1313
|
wlyr = self.wlyr
|
|
1309
1314
|
nodes = []
|
|
1310
1315
|
callbacks = []
|
|
@@ -1344,12 +1349,12 @@ class Snap(s_base.Base):
|
|
|
1344
1349
|
if etyp == s_layer.EDIT_NODE_ADD:
|
|
1345
1350
|
node.bylayer['ndef'] = wlyr.iden
|
|
1346
1351
|
callbacks.append((node.form.wasAdded, (node,)))
|
|
1347
|
-
callbacks.append((self.view.runNodeAdd, (node,)))
|
|
1352
|
+
callbacks.append((self.view.runNodeAdd, (node, useriden)))
|
|
1348
1353
|
continue
|
|
1349
1354
|
|
|
1350
1355
|
if etyp == s_layer.EDIT_NODE_DEL:
|
|
1351
1356
|
callbacks.append((node.form.wasDeleted, (node,)))
|
|
1352
|
-
callbacks.append((self.view.runNodeDel, (node,)))
|
|
1357
|
+
callbacks.append((self.view.runNodeDel, (node, useriden)))
|
|
1353
1358
|
continue
|
|
1354
1359
|
|
|
1355
1360
|
if etyp == s_layer.EDIT_PROP_SET:
|
|
@@ -1365,7 +1370,7 @@ class Snap(s_base.Base):
|
|
|
1365
1370
|
node.bylayer['props'][name] = wlyr.iden
|
|
1366
1371
|
|
|
1367
1372
|
callbacks.append((prop.wasSet, (node, oldv)))
|
|
1368
|
-
callbacks.append((self.view.runPropSet, (node, prop, oldv)))
|
|
1373
|
+
callbacks.append((self.view.runPropSet, (node, prop, oldv, useriden)))
|
|
1369
1374
|
continue
|
|
1370
1375
|
|
|
1371
1376
|
if etyp == s_layer.EDIT_PROP_DEL:
|
|
@@ -1381,7 +1386,7 @@ class Snap(s_base.Base):
|
|
|
1381
1386
|
node.bylayer['props'].pop(name, None)
|
|
1382
1387
|
|
|
1383
1388
|
callbacks.append((prop.wasDel, (node, oldv)))
|
|
1384
|
-
callbacks.append((self.view.runPropSet, (node, prop, oldv)))
|
|
1389
|
+
callbacks.append((self.view.runPropSet, (node, prop, oldv, useriden)))
|
|
1385
1390
|
continue
|
|
1386
1391
|
|
|
1387
1392
|
if etyp == s_layer.EDIT_TAG_SET:
|
|
@@ -1391,7 +1396,7 @@ class Snap(s_base.Base):
|
|
|
1391
1396
|
node.tags[tag] = valu
|
|
1392
1397
|
node.bylayer['tags'][tag] = wlyr.iden
|
|
1393
1398
|
|
|
1394
|
-
callbacks.append((self.view.runTagAdd, (node, tag, valu)))
|
|
1399
|
+
callbacks.append((self.view.runTagAdd, (node, tag, valu, useriden,)))
|
|
1395
1400
|
continue
|
|
1396
1401
|
|
|
1397
1402
|
if etyp == s_layer.EDIT_TAG_DEL:
|
|
@@ -1401,7 +1406,7 @@ class Snap(s_base.Base):
|
|
|
1401
1406
|
node.tags.pop(tag, None)
|
|
1402
1407
|
node.bylayer['tags'].pop(tag, None)
|
|
1403
1408
|
|
|
1404
|
-
callbacks.append((self.view.runTagDel, (node, tag, oldv)))
|
|
1409
|
+
callbacks.append((self.view.runTagDel, (node, tag, oldv, useriden)))
|
|
1405
1410
|
continue
|
|
1406
1411
|
|
|
1407
1412
|
if etyp == s_layer.EDIT_TAGPROP_SET:
|
|
@@ -1436,14 +1441,15 @@ class Snap(s_base.Base):
|
|
|
1436
1441
|
if etyp == s_layer.EDIT_EDGE_ADD:
|
|
1437
1442
|
verb, n2iden = parms
|
|
1438
1443
|
n2 = await self.getNodeByBuid(s_common.uhex(n2iden))
|
|
1439
|
-
callbacks.append((self.view.runEdgeAdd, (node, verb, n2)))
|
|
1444
|
+
callbacks.append((self.view.runEdgeAdd, (node, verb, n2, useriden)))
|
|
1440
1445
|
|
|
1441
1446
|
if etyp == s_layer.EDIT_EDGE_DEL:
|
|
1442
1447
|
verb, n2iden = parms
|
|
1443
1448
|
n2 = await self.getNodeByBuid(s_common.uhex(n2iden))
|
|
1444
|
-
callbacks.append((self.view.runEdgeDel, (node, verb, n2)))
|
|
1449
|
+
callbacks.append((self.view.runEdgeDel, (node, verb, n2, useriden)))
|
|
1445
1450
|
|
|
1446
|
-
|
|
1451
|
+
for func, args in callbacks:
|
|
1452
|
+
await func(*args)
|
|
1447
1453
|
|
|
1448
1454
|
if actualedits:
|
|
1449
1455
|
await self.fire('node:edits', edits=actualedits)
|
synapse/lib/storm.py
CHANGED
|
@@ -439,196 +439,6 @@ stormcmds = (
|
|
|
439
439
|
}
|
|
440
440
|
''',
|
|
441
441
|
},
|
|
442
|
-
{
|
|
443
|
-
'name': 'pkg.list',
|
|
444
|
-
'descr': 'List the storm packages loaded in the cortex.',
|
|
445
|
-
'cmdargs': (
|
|
446
|
-
('--verbose', {'default': False, 'action': 'store_true',
|
|
447
|
-
'help': 'Display build time for each package.'}),
|
|
448
|
-
),
|
|
449
|
-
'storm': '''
|
|
450
|
-
init {
|
|
451
|
-
$conf = ({
|
|
452
|
-
"columns": [
|
|
453
|
-
{"name": "name", "width": 40},
|
|
454
|
-
{"name": "vers", "width": 10},
|
|
455
|
-
],
|
|
456
|
-
"separators": {
|
|
457
|
-
"row:outline": false,
|
|
458
|
-
"column:outline": false,
|
|
459
|
-
"header:row": "#",
|
|
460
|
-
"data:row": "",
|
|
461
|
-
"column": "",
|
|
462
|
-
},
|
|
463
|
-
})
|
|
464
|
-
if $cmdopts.verbose {
|
|
465
|
-
$conf.columns.append(({"name": "time", "width": 20}))
|
|
466
|
-
}
|
|
467
|
-
$printer = $lib.tabular.printer($conf)
|
|
468
|
-
}
|
|
469
|
-
|
|
470
|
-
$pkgs = $lib.pkg.list()
|
|
471
|
-
|
|
472
|
-
if $($pkgs.size() > 0) {
|
|
473
|
-
$lib.print('Loaded storm packages:')
|
|
474
|
-
$lib.print($printer.header())
|
|
475
|
-
for $pkg in $pkgs {
|
|
476
|
-
$row = (
|
|
477
|
-
$pkg.name, $pkg.version,
|
|
478
|
-
)
|
|
479
|
-
if $cmdopts.verbose {
|
|
480
|
-
try {
|
|
481
|
-
$row.append($lib.time.format($pkg.build.time, '%Y-%m-%d %H:%M:%S'))
|
|
482
|
-
} catch StormRuntimeError as _ {
|
|
483
|
-
$row.append('not available')
|
|
484
|
-
}
|
|
485
|
-
}
|
|
486
|
-
$lib.print($printer.row($row))
|
|
487
|
-
}
|
|
488
|
-
} else {
|
|
489
|
-
$lib.print('No storm packages installed.')
|
|
490
|
-
}
|
|
491
|
-
'''
|
|
492
|
-
},
|
|
493
|
-
{
|
|
494
|
-
'name': 'pkg.perms.list',
|
|
495
|
-
'descr': 'List any permissions declared by the package.',
|
|
496
|
-
'cmdargs': (
|
|
497
|
-
('name', {'help': 'The name (or name prefix) of the package.', 'type': 'str'}),
|
|
498
|
-
),
|
|
499
|
-
'storm': '''
|
|
500
|
-
$pdef = $lib.null
|
|
501
|
-
for $pkg in $lib.pkg.list() {
|
|
502
|
-
if $pkg.name.startswith($cmdopts.name) {
|
|
503
|
-
$pdef = $pkg
|
|
504
|
-
break
|
|
505
|
-
}
|
|
506
|
-
}
|
|
507
|
-
|
|
508
|
-
if (not $pdef) {
|
|
509
|
-
$lib.warn(`Package ({$cmdopts.name}) not found!`)
|
|
510
|
-
} else {
|
|
511
|
-
if $pdef.perms {
|
|
512
|
-
$lib.print(`Package ({$cmdopts.name}) defines the following permissions:`)
|
|
513
|
-
for $permdef in $pdef.perms {
|
|
514
|
-
$defv = $permdef.default
|
|
515
|
-
if ( $defv = $lib.null ) {
|
|
516
|
-
$defv = $lib.false
|
|
517
|
-
}
|
|
518
|
-
$text = `{('.').join($permdef.perm).ljust(32)} : {$permdef.desc} ( default: {$defv} )`
|
|
519
|
-
$lib.print($text)
|
|
520
|
-
}
|
|
521
|
-
} else {
|
|
522
|
-
$lib.print(`Package ({$cmdopts.name}) contains no permissions definitions.`)
|
|
523
|
-
}
|
|
524
|
-
}
|
|
525
|
-
'''
|
|
526
|
-
},
|
|
527
|
-
{
|
|
528
|
-
'name': 'pkg.del',
|
|
529
|
-
'descr': 'Remove a storm package from the cortex.',
|
|
530
|
-
'cmdargs': (
|
|
531
|
-
('name', {'help': 'The name (or name prefix) of the package to remove.'}),
|
|
532
|
-
),
|
|
533
|
-
'storm': '''
|
|
534
|
-
|
|
535
|
-
$pkgs = $lib.set()
|
|
536
|
-
|
|
537
|
-
for $pkg in $lib.pkg.list() {
|
|
538
|
-
if $pkg.name.startswith($cmdopts.name) {
|
|
539
|
-
$pkgs.add($pkg.name)
|
|
540
|
-
}
|
|
541
|
-
}
|
|
542
|
-
|
|
543
|
-
if $($pkgs.size() = 0) {
|
|
544
|
-
|
|
545
|
-
$lib.print('No package names match "{name}". Aborting.', name=$cmdopts.name)
|
|
546
|
-
|
|
547
|
-
} elif $($pkgs.size() = 1) {
|
|
548
|
-
|
|
549
|
-
$name = $pkgs.list().index(0)
|
|
550
|
-
$lib.print('Removing package: {name}', name=$name)
|
|
551
|
-
$lib.pkg.del($name)
|
|
552
|
-
|
|
553
|
-
} else {
|
|
554
|
-
|
|
555
|
-
$lib.print('Multiple package names match "{name}". Aborting.', name=$cmdopts.name)
|
|
556
|
-
|
|
557
|
-
}
|
|
558
|
-
'''
|
|
559
|
-
},
|
|
560
|
-
{
|
|
561
|
-
'name': 'pkg.docs',
|
|
562
|
-
'descr': 'Display documentation included in a storm package.',
|
|
563
|
-
'cmdargs': (
|
|
564
|
-
('name', {'help': 'The name (or name prefix) of the package.'}),
|
|
565
|
-
),
|
|
566
|
-
'storm': '''
|
|
567
|
-
$pdef = $lib.null
|
|
568
|
-
for $pkg in $lib.pkg.list() {
|
|
569
|
-
if $pkg.name.startswith($cmdopts.name) {
|
|
570
|
-
$pdef = $pkg
|
|
571
|
-
break
|
|
572
|
-
}
|
|
573
|
-
}
|
|
574
|
-
|
|
575
|
-
if (not $pdef) {
|
|
576
|
-
$lib.warn("Package ({name}) not found!", name=$cmdopts.name)
|
|
577
|
-
} else {
|
|
578
|
-
if $pdef.docs {
|
|
579
|
-
for $doc in $pdef.docs {
|
|
580
|
-
$lib.print($doc.content)
|
|
581
|
-
}
|
|
582
|
-
} else {
|
|
583
|
-
$lib.print("Package ({name}) contains no documentation.", name=$cmdopts.name)
|
|
584
|
-
}
|
|
585
|
-
}
|
|
586
|
-
'''
|
|
587
|
-
},
|
|
588
|
-
{
|
|
589
|
-
'name': 'pkg.load',
|
|
590
|
-
'descr': 'Load a storm package from an HTTP URL.',
|
|
591
|
-
'cmdargs': (
|
|
592
|
-
('url', {'help': 'The HTTP URL to load the package from.'}),
|
|
593
|
-
('--raw', {'default': False, 'action': 'store_true',
|
|
594
|
-
'help': 'Response JSON is a raw package definition without an envelope.'}),
|
|
595
|
-
('--verify', {'default': False, 'action': 'store_true',
|
|
596
|
-
'help': 'Enforce code signature verification on the storm package.'}),
|
|
597
|
-
('--ssl-noverify', {'default': False, 'action': 'store_true',
|
|
598
|
-
'help': 'Specify to disable SSL verification of the server.'}),
|
|
599
|
-
),
|
|
600
|
-
'storm': '''
|
|
601
|
-
init {
|
|
602
|
-
$ssl = $lib.true
|
|
603
|
-
if $cmdopts.ssl_noverify { $ssl = $lib.false }
|
|
604
|
-
|
|
605
|
-
$headers = ({'X-Synapse-Version': ('.').join($lib.version.synapse())})
|
|
606
|
-
|
|
607
|
-
$resp = $lib.inet.http.get($cmdopts.url, ssl_verify=$ssl, headers=$headers)
|
|
608
|
-
|
|
609
|
-
if ($resp.code != 200) {
|
|
610
|
-
$lib.warn("pkg.load got HTTP code: {code} for URL: {url}", code=$resp.code, url=$cmdopts.url)
|
|
611
|
-
$lib.exit()
|
|
612
|
-
}
|
|
613
|
-
|
|
614
|
-
$reply = $resp.json()
|
|
615
|
-
if $cmdopts.raw {
|
|
616
|
-
$pkg = $reply
|
|
617
|
-
} else {
|
|
618
|
-
if ($reply.status != "ok") {
|
|
619
|
-
$lib.warn("pkg.load got JSON error: {code} for URL: {url}", code=$reply.code, url=$cmdopts.url)
|
|
620
|
-
$lib.exit()
|
|
621
|
-
}
|
|
622
|
-
|
|
623
|
-
$pkg = $reply.result
|
|
624
|
-
}
|
|
625
|
-
|
|
626
|
-
$pkd = $lib.pkg.add($pkg, verify=$cmdopts.verify)
|
|
627
|
-
|
|
628
|
-
$lib.print("Loaded Package: {name} @{version}", name=$pkg.name, version=$pkg.version)
|
|
629
|
-
}
|
|
630
|
-
''',
|
|
631
|
-
},
|
|
632
442
|
{
|
|
633
443
|
'name': 'version',
|
|
634
444
|
'descr': 'Show version metadata relating to Synapse.',
|
synapse/lib/stormlib/auth.py
CHANGED
|
@@ -1810,7 +1810,7 @@ class LibUser(s_stormtypes.Lib):
|
|
|
1810
1810
|
'returns': {'type': 'boolean',
|
|
1811
1811
|
'desc': 'True if the user has the requested permission, false otherwise.', }}},
|
|
1812
1812
|
{'name': 'vars', 'desc': "Get a dictionary representing the current user's persistent variables.",
|
|
1813
|
-
'type': '
|
|
1813
|
+
'type': 'user:vars:dict', },
|
|
1814
1814
|
{'name': 'profile', 'desc': "Get a dictionary representing the current user's profile information.",
|
|
1815
1815
|
'type': 'auth:user:profile', },
|
|
1816
1816
|
{'name': 'iden', 'desc': 'The user GUID for the current storm user.', 'type': 'str'},
|
synapse/lib/stormlib/mime.py
CHANGED
|
@@ -3,9 +3,9 @@ import bs4
|
|
|
3
3
|
import synapse.lib.coro as s_coro
|
|
4
4
|
import synapse.lib.stormtypes as s_stormtypes
|
|
5
5
|
|
|
6
|
-
def htmlToText(html):
|
|
6
|
+
def htmlToText(html, separator='\n', strip=True):
|
|
7
7
|
soup = bs4.BeautifulSoup(html, 'html5lib')
|
|
8
|
-
return soup.get_text(separator=
|
|
8
|
+
return soup.get_text(separator=separator, strip=strip)
|
|
9
9
|
|
|
10
10
|
@s_stormtypes.registry.registerLib
|
|
11
11
|
class LibMimeHtml(s_stormtypes.Lib):
|
|
@@ -17,8 +17,12 @@ class LibMimeHtml(s_stormtypes.Lib):
|
|
|
17
17
|
'type': {'type': 'function', '_funcname': 'totext',
|
|
18
18
|
'args': (
|
|
19
19
|
{'name': 'html', 'type': 'str', 'desc': 'The HTML text to be parsed.'},
|
|
20
|
+
{'name': 'separator', 'type': 'str', 'default': '\n',
|
|
21
|
+
'desc': 'The string used to join text.'},
|
|
22
|
+
{'name': 'strip', 'type': 'boolean', 'default': True,
|
|
23
|
+
'desc': 'Strip whitespace from the beginning and end of tag text.'},
|
|
20
24
|
),
|
|
21
|
-
'returns': {'type': 'str', 'desc': 'The
|
|
25
|
+
'returns': {'type': 'str', 'desc': 'The separator-joined inner HTML text.', }
|
|
22
26
|
}},
|
|
23
27
|
)
|
|
24
28
|
|
|
@@ -30,6 +34,12 @@ class LibMimeHtml(s_stormtypes.Lib):
|
|
|
30
34
|
}
|
|
31
35
|
|
|
32
36
|
@s_stormtypes.stormfunc(readonly=True)
|
|
33
|
-
async def totext(self, html):
|
|
37
|
+
async def totext(self, html, separator='\n', strip=True):
|
|
34
38
|
html = await s_stormtypes.tostr(html)
|
|
35
|
-
|
|
39
|
+
separator = await s_stormtypes.tostr(separator, noneok=True)
|
|
40
|
+
strip = await s_stormtypes.tobool(strip)
|
|
41
|
+
|
|
42
|
+
if separator is None:
|
|
43
|
+
separator = ''
|
|
44
|
+
|
|
45
|
+
return await s_coro.semafork(htmlToText, html, separator, strip)
|