synapse 2.178.0__py311-none-any.whl → 2.180.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 +166 -31
- synapse/datamodel.py +47 -1
- synapse/exc.py +1 -0
- synapse/lib/aha.py +2 -1
- synapse/lib/ast.py +110 -76
- synapse/lib/base.py +12 -3
- synapse/lib/cell.py +150 -11
- synapse/lib/coro.py +14 -0
- synapse/lib/drive.py +551 -0
- synapse/lib/layer.py +1 -1
- synapse/lib/lmdbslab.py +2 -0
- synapse/lib/modelrev.py +5 -1
- synapse/lib/node.py +14 -4
- synapse/lib/schemas.py +97 -0
- synapse/lib/snap.py +36 -11
- synapse/lib/storm.py +9 -5
- synapse/lib/stormhttp.py +1 -0
- synapse/lib/stormlib/modelext.py +29 -3
- synapse/lib/stormlib/stix.py +44 -17
- synapse/lib/stormlib/vault.py +2 -2
- synapse/lib/stormtypes.py +1 -1
- synapse/lib/types.py +9 -0
- synapse/lib/version.py +2 -2
- synapse/lookup/pe.py +303 -38
- synapse/models/auth.py +2 -0
- synapse/models/dns.py +24 -1
- synapse/models/geopol.py +3 -0
- synapse/models/geospace.py +4 -1
- synapse/models/inet.py +1 -0
- synapse/models/infotech.py +135 -92
- synapse/models/person.py +5 -2
- synapse/models/telco.py +3 -0
- synapse/tests/test_cortex.py +45 -1
- synapse/tests/test_lib_aha.py +17 -0
- synapse/tests/test_lib_ast.py +231 -0
- synapse/tests/test_lib_cell.py +225 -0
- synapse/tests/test_lib_coro.py +12 -0
- synapse/tests/test_lib_layer.py +22 -0
- synapse/tests/test_lib_modelrev.py +7 -0
- synapse/tests/test_lib_node.py +12 -1
- synapse/tests/test_lib_storm.py +32 -7
- synapse/tests/test_lib_stormhttp.py +40 -0
- synapse/tests/test_lib_stormlib_modelext.py +55 -3
- synapse/tests/test_lib_stormlib_stix.py +15 -0
- synapse/tests/test_lib_stormlib_vault.py +11 -1
- synapse/tests/test_lib_stormtypes.py +5 -0
- synapse/tests/test_lib_types.py +9 -0
- synapse/tests/test_model_dns.py +8 -0
- synapse/tests/test_model_geopol.py +2 -0
- synapse/tests/test_model_geospace.py +3 -1
- synapse/tests/test_model_inet.py +10 -1
- synapse/tests/test_model_infotech.py +47 -0
- synapse/tests/test_model_person.py +2 -0
- synapse/tests/test_model_syn.py +11 -0
- synapse/tests/test_model_telco.py +2 -1
- synapse/tests/test_utils_stormcov.py +1 -1
- synapse/tools/changelog.py +28 -0
- {synapse-2.178.0.dist-info → synapse-2.180.0.dist-info}/METADATA +1 -1
- {synapse-2.178.0.dist-info → synapse-2.180.0.dist-info}/RECORD +62 -61
- {synapse-2.178.0.dist-info → synapse-2.180.0.dist-info}/WHEEL +1 -1
- {synapse-2.178.0.dist-info → synapse-2.180.0.dist-info}/LICENSE +0 -0
- {synapse-2.178.0.dist-info → synapse-2.180.0.dist-info}/top_level.txt +0 -0
synapse/lib/schemas.py
CHANGED
|
@@ -274,6 +274,7 @@ reqValidSslCtxOpts = s_config.getJsValidator({
|
|
|
274
274
|
'verify': {'type': 'boolean', 'default': True},
|
|
275
275
|
'client_cert': {'type': ['string', 'null'], 'default': None},
|
|
276
276
|
'client_key': {'type': ['string', 'null'], 'default': None},
|
|
277
|
+
'ca_cert': {'type': ['string', 'null'], 'default': None},
|
|
277
278
|
},
|
|
278
279
|
'additionalProperties': False,
|
|
279
280
|
})
|
|
@@ -454,3 +455,99 @@ tabularConfSchema = {
|
|
|
454
455
|
}
|
|
455
456
|
|
|
456
457
|
reqValidTabularConf = s_config.getJsValidator(tabularConfSchema)
|
|
458
|
+
|
|
459
|
+
emptySchema = {'object': {}, 'additionalProperties': False}
|
|
460
|
+
re_drivename = r'^[\w_.-]{1,128}$'
|
|
461
|
+
|
|
462
|
+
driveInfoSchema = {
|
|
463
|
+
'type': 'object',
|
|
464
|
+
'properties': {
|
|
465
|
+
'iden': {'type': 'string', 'pattern': s_config.re_iden},
|
|
466
|
+
'parent': {'type': 'string', 'pattern': s_config.re_iden},
|
|
467
|
+
'type': {'type': 'string', 'pattern': re_drivename},
|
|
468
|
+
'name': {'type': 'string', 'pattern': re_drivename},
|
|
469
|
+
'perm': s_msgpack.deepcopy(easyPermSchema),
|
|
470
|
+
'kids': {'type': 'number', 'minimum': 0},
|
|
471
|
+
'created': {'type': 'number'},
|
|
472
|
+
'creator': {'type': 'string', 'pattern': s_config.re_iden},
|
|
473
|
+
# these are also data version info...
|
|
474
|
+
'size': {'type': 'number', 'minimum': 0},
|
|
475
|
+
'updated': {'type': 'number'},
|
|
476
|
+
'updater': {'type': 'string', 'pattern': s_config.re_iden},
|
|
477
|
+
'version': {'type': 'array', 'items': {'type': 'number', 'minItems': 3, 'maxItems': 3}},
|
|
478
|
+
},
|
|
479
|
+
'required': ('iden', 'parent', 'name', 'created', 'creator', 'kids'),
|
|
480
|
+
'additionalProperties': False,
|
|
481
|
+
}
|
|
482
|
+
reqValidDriveInfo = s_config.getJsValidator(driveInfoSchema)
|
|
483
|
+
|
|
484
|
+
driveDataVersSchema = {
|
|
485
|
+
'type': 'object',
|
|
486
|
+
'properties': {
|
|
487
|
+
'size': {'type': 'number', 'minimum': 0},
|
|
488
|
+
'updated': {'type': 'number'},
|
|
489
|
+
'updater': {'type': 'string', 'pattern': s_config.re_iden},
|
|
490
|
+
'version': {'type': 'array', 'items': {'type': 'number', 'minItems': 3, 'maxItems': 3}},
|
|
491
|
+
},
|
|
492
|
+
'required': ('size', 'version', 'updated', 'updater'),
|
|
493
|
+
'additionalProperties': False,
|
|
494
|
+
}
|
|
495
|
+
reqValidDriveDataVers = s_config.getJsValidator(driveDataVersSchema)
|
|
496
|
+
|
|
497
|
+
stixIngestConfigSchema = {
|
|
498
|
+
'type': 'object',
|
|
499
|
+
'properties': {
|
|
500
|
+
'bundle': {
|
|
501
|
+
'type': ['object', 'null'],
|
|
502
|
+
'properties': {'storm': {'type': 'string'}},
|
|
503
|
+
},
|
|
504
|
+
'objects': {
|
|
505
|
+
'type': 'object',
|
|
506
|
+
'properties': {'storm': {'type': 'string'}},
|
|
507
|
+
},
|
|
508
|
+
'relationships': {
|
|
509
|
+
'type': 'array',
|
|
510
|
+
'items': {
|
|
511
|
+
'type': 'object',
|
|
512
|
+
'properties': {
|
|
513
|
+
'type': {
|
|
514
|
+
'type': 'array',
|
|
515
|
+
'items': {
|
|
516
|
+
'type': ['string', 'null'],
|
|
517
|
+
'minItems': 3,
|
|
518
|
+
'maxItems': 3,
|
|
519
|
+
},
|
|
520
|
+
},
|
|
521
|
+
'storm': {'type': 'string'},
|
|
522
|
+
},
|
|
523
|
+
'required': ['type'],
|
|
524
|
+
},
|
|
525
|
+
},
|
|
526
|
+
},
|
|
527
|
+
'required': ['bundle', 'objects'],
|
|
528
|
+
}
|
|
529
|
+
reqValidStixIngestConfig = s_config.getJsValidator(stixIngestConfigSchema)
|
|
530
|
+
|
|
531
|
+
stixIngestBundleSchema = {
|
|
532
|
+
'type': 'object',
|
|
533
|
+
'properties': {
|
|
534
|
+
'objects': {
|
|
535
|
+
'type': 'array',
|
|
536
|
+
'items': {
|
|
537
|
+
'type': 'object',
|
|
538
|
+
'properties': {
|
|
539
|
+
'id': {'type': 'string'},
|
|
540
|
+
'type': {'type': 'string'},
|
|
541
|
+
'object_refs': {'type': 'array', 'items': {'type': 'string'}},
|
|
542
|
+
'relationship_type': {'type': 'string'},
|
|
543
|
+
'source_ref': {'type': 'string'},
|
|
544
|
+
'target_ref': {'type': 'string'},
|
|
545
|
+
},
|
|
546
|
+
'required': ['id', 'type'],
|
|
547
|
+
'if': {'properties': {'type': {'const': 'relationship'}}},
|
|
548
|
+
'then': {'required': ['source_ref', 'target_ref']},
|
|
549
|
+
}
|
|
550
|
+
},
|
|
551
|
+
},
|
|
552
|
+
}
|
|
553
|
+
reqValidStixIngestBundle = s_config.getJsValidator(stixIngestBundleSchema)
|
synapse/lib/snap.py
CHANGED
|
@@ -316,6 +316,10 @@ class ProtoNode:
|
|
|
316
316
|
mesg = f'Tagprop {name} does not exist in this Cortex.'
|
|
317
317
|
return await self.ctx.snap._raiseOnStrict(s_exc.NoSuchTagProp, mesg)
|
|
318
318
|
|
|
319
|
+
if prop.locked:
|
|
320
|
+
mesg = f'Tagprop {name} is locked.'
|
|
321
|
+
return await self.ctx.snap._raiseOnStrict(s_exc.IsDeprLocked, mesg)
|
|
322
|
+
|
|
319
323
|
try:
|
|
320
324
|
norm, info = prop.type.norm(valu)
|
|
321
325
|
except s_exc.BadTypeValu as e:
|
|
@@ -732,6 +736,7 @@ class Snap(s_base.Base):
|
|
|
732
736
|
|
|
733
737
|
dorepr = False
|
|
734
738
|
dopath = False
|
|
739
|
+
dolink = False
|
|
735
740
|
|
|
736
741
|
show_storage = False
|
|
737
742
|
|
|
@@ -750,6 +755,7 @@ class Snap(s_base.Base):
|
|
|
750
755
|
if opts is not None:
|
|
751
756
|
dorepr = opts.get('repr', False)
|
|
752
757
|
dopath = opts.get('path', False)
|
|
758
|
+
dolink = opts.get('links', False)
|
|
753
759
|
show_storage = opts.get('show:storage', False)
|
|
754
760
|
|
|
755
761
|
async for node, path in self.storm(text, opts=opts, user=user):
|
|
@@ -757,6 +763,9 @@ class Snap(s_base.Base):
|
|
|
757
763
|
pode = node.pack(dorepr=dorepr)
|
|
758
764
|
pode[1]['path'] = await path.pack(path=dopath)
|
|
759
765
|
|
|
766
|
+
if dolink:
|
|
767
|
+
pode[1]['links'] = path.links
|
|
768
|
+
|
|
760
769
|
if show_storage:
|
|
761
770
|
pode[1]['storage'] = await node.getStorNodes()
|
|
762
771
|
|
|
@@ -1029,7 +1038,7 @@ class Snap(s_base.Base):
|
|
|
1029
1038
|
if node is not None:
|
|
1030
1039
|
yield node
|
|
1031
1040
|
|
|
1032
|
-
async def nodesByPropValu(self, full, cmpr, valu, reverse=False):
|
|
1041
|
+
async def nodesByPropValu(self, full, cmpr, valu, reverse=False, norm=True):
|
|
1033
1042
|
if cmpr == 'type=':
|
|
1034
1043
|
if reverse:
|
|
1035
1044
|
async for node in self.nodesByPropTypeValu(full, valu, reverse=reverse):
|
|
@@ -1050,10 +1059,13 @@ class Snap(s_base.Base):
|
|
|
1050
1059
|
mesg = f'No property named "{full}".'
|
|
1051
1060
|
raise s_exc.NoSuchProp(mesg=mesg)
|
|
1052
1061
|
|
|
1053
|
-
|
|
1054
|
-
|
|
1055
|
-
|
|
1056
|
-
|
|
1062
|
+
if norm:
|
|
1063
|
+
cmprvals = prop.type.getStorCmprs(cmpr, valu)
|
|
1064
|
+
# an empty return probably means ?= with invalid value
|
|
1065
|
+
if not cmprvals:
|
|
1066
|
+
return
|
|
1067
|
+
else:
|
|
1068
|
+
cmprvals = ((cmpr, valu, prop.type.stortype),)
|
|
1057
1069
|
|
|
1058
1070
|
if prop.isrunt:
|
|
1059
1071
|
for storcmpr, storvalu, _ in cmprvals:
|
|
@@ -1108,7 +1120,7 @@ class Snap(s_base.Base):
|
|
|
1108
1120
|
async for node in self.nodesByPropArray(prop.full, '=', valu, reverse=reverse):
|
|
1109
1121
|
yield node
|
|
1110
1122
|
|
|
1111
|
-
async def nodesByPropArray(self, full, cmpr, valu, reverse=False):
|
|
1123
|
+
async def nodesByPropArray(self, full, cmpr, valu, reverse=False, norm=True):
|
|
1112
1124
|
|
|
1113
1125
|
prop = self.core.model.prop(full)
|
|
1114
1126
|
if prop is None:
|
|
@@ -1119,7 +1131,10 @@ class Snap(s_base.Base):
|
|
|
1119
1131
|
mesg = f'Array syntax is invalid on non array type: {prop.type.name}.'
|
|
1120
1132
|
raise s_exc.BadTypeValu(mesg=mesg)
|
|
1121
1133
|
|
|
1122
|
-
|
|
1134
|
+
if norm:
|
|
1135
|
+
cmprvals = prop.type.arraytype.getStorCmprs(cmpr, valu)
|
|
1136
|
+
else:
|
|
1137
|
+
cmprvals = ((cmpr, valu, prop.type.arraytype.stortype),)
|
|
1123
1138
|
|
|
1124
1139
|
if prop.isform:
|
|
1125
1140
|
async for (buid, sodes) in self.core._liftByPropArray(prop.name, None, cmprvals, self.layers, reverse=reverse):
|
|
@@ -1602,18 +1617,28 @@ class Snap(s_base.Base):
|
|
|
1602
1617
|
last = verb
|
|
1603
1618
|
yield verb
|
|
1604
1619
|
|
|
1605
|
-
async def
|
|
1620
|
+
async def _getLayrNdefProp(self, layr, buid):
|
|
1621
|
+
async for refsbuid, refsabrv in layr.getNdefRefs(buid):
|
|
1622
|
+
yield refsbuid, layr.getAbrvProp(refsabrv)
|
|
1623
|
+
|
|
1624
|
+
async def getNdefRefs(self, buid, props=False):
|
|
1606
1625
|
last = None
|
|
1607
|
-
|
|
1626
|
+
if props:
|
|
1627
|
+
gens = [self._getLayrNdefProp(layr, buid) for layr in self.layers]
|
|
1628
|
+
else:
|
|
1629
|
+
gens = [layr.getNdefRefs(buid) for layr in self.layers]
|
|
1608
1630
|
|
|
1609
|
-
async for refsbuid,
|
|
1631
|
+
async for refsbuid, xtra in s_common.merggenr2(gens):
|
|
1610
1632
|
if refsbuid == last:
|
|
1611
1633
|
continue
|
|
1612
1634
|
|
|
1613
1635
|
await asyncio.sleep(0)
|
|
1614
1636
|
last = refsbuid
|
|
1615
1637
|
|
|
1616
|
-
|
|
1638
|
+
if props:
|
|
1639
|
+
yield refsbuid, xtra[1]
|
|
1640
|
+
else:
|
|
1641
|
+
yield refsbuid
|
|
1617
1642
|
|
|
1618
1643
|
async def hasNodeData(self, buid, name):
|
|
1619
1644
|
'''
|
synapse/lib/storm.py
CHANGED
|
@@ -53,7 +53,9 @@ When condition is tag:add or tag:del, you may optionally provide a form name
|
|
|
53
53
|
to restrict the trigger to fire only on tags added or deleted from nodes of
|
|
54
54
|
those forms.
|
|
55
55
|
|
|
56
|
-
The added tag is provided to the query
|
|
56
|
+
The added tag is provided to the query in the ``$auto`` dictionary variable under
|
|
57
|
+
``$auto.opts.tag``. Usage of the ``$tag`` variable is deprecated and it will no longer
|
|
58
|
+
be populated in Synapse v3.0.0.
|
|
57
59
|
|
|
58
60
|
Simple one level tag globbing is supported, only at the end after a period,
|
|
59
61
|
that is aka.* matches aka.foo and aka.bar but not aka.foo.bar. aka* is not
|
|
@@ -5375,7 +5377,7 @@ class TeeCmd(Cmd):
|
|
|
5375
5377
|
|
|
5376
5378
|
outq = asyncio.Queue(maxsize=outq_size)
|
|
5377
5379
|
for subr in runts:
|
|
5378
|
-
subg = s_common.agen((node, path.fork(node)))
|
|
5380
|
+
subg = s_common.agen((node, path.fork(node, None)))
|
|
5379
5381
|
self.runt.snap.schedCoro(self.pipeline(subr, outq, genr=subg))
|
|
5380
5382
|
|
|
5381
5383
|
exited = 0
|
|
@@ -5397,7 +5399,7 @@ class TeeCmd(Cmd):
|
|
|
5397
5399
|
else:
|
|
5398
5400
|
|
|
5399
5401
|
for subr in runts:
|
|
5400
|
-
subg = s_common.agen((node, path.fork(node)))
|
|
5402
|
+
subg = s_common.agen((node, path.fork(node, None)))
|
|
5401
5403
|
async for subitem in subr.execute(genr=subg):
|
|
5402
5404
|
yield subitem
|
|
5403
5405
|
|
|
@@ -5551,6 +5553,7 @@ class ScrapeCmd(Cmd):
|
|
|
5551
5553
|
if not todo:
|
|
5552
5554
|
todo = list(node.props.values())
|
|
5553
5555
|
|
|
5556
|
+
link = {'type': 'scrape'}
|
|
5554
5557
|
for text in todo:
|
|
5555
5558
|
|
|
5556
5559
|
text = str(text)
|
|
@@ -5560,7 +5563,7 @@ class ScrapeCmd(Cmd):
|
|
|
5560
5563
|
continue
|
|
5561
5564
|
|
|
5562
5565
|
nnode = await node.snap.addNode(form, valu)
|
|
5563
|
-
npath = path.fork(nnode)
|
|
5566
|
+
npath = path.fork(nnode, link)
|
|
5564
5567
|
|
|
5565
5568
|
if refs:
|
|
5566
5569
|
if node.form.isrunt:
|
|
@@ -5664,8 +5667,9 @@ class LiftByVerb(Cmd):
|
|
|
5664
5667
|
|
|
5665
5668
|
yield _node, _path
|
|
5666
5669
|
|
|
5670
|
+
link = {'type': 'runtime'}
|
|
5667
5671
|
async for node in self.iterEdgeNodes(verb, idenset, n2):
|
|
5668
|
-
yield node, _path.fork(node)
|
|
5672
|
+
yield node, _path.fork(node, link)
|
|
5669
5673
|
|
|
5670
5674
|
class EdgesDelCmd(Cmd):
|
|
5671
5675
|
'''
|
synapse/lib/stormhttp.py
CHANGED
|
@@ -95,6 +95,7 @@ class LibHttp(s_stormtypes.Lib):
|
|
|
95
95
|
'verify': <bool> - Perform SSL/TLS verification. Is overridden by the ssl_verify argument.
|
|
96
96
|
'client_cert': <str> - PEM encoded full chain certificate for use in mTLS.
|
|
97
97
|
'client_key': <str> - PEM encoded key for use in mTLS. Alternatively, can be included in client_cert.
|
|
98
|
+
'ca_cert': <str> - A PEM encoded full chain CA certificate for use when verifying the request.
|
|
98
99
|
}
|
|
99
100
|
'''
|
|
100
101
|
_storm_locals = (
|
synapse/lib/stormlib/modelext.py
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import synapse.exc as s_exc
|
|
2
|
+
import synapse.common as s_common
|
|
2
3
|
import synapse.lib.grammar as s_grammar
|
|
3
4
|
|
|
4
5
|
import synapse.lib.stormtypes as s_stormtypes
|
|
@@ -54,6 +55,8 @@ class LibModelExt(s_stormtypes.Lib):
|
|
|
54
55
|
'args': (
|
|
55
56
|
{'name': 'formname', 'type': 'str', 'desc': 'The form with the extended property.', },
|
|
56
57
|
{'name': 'propname', 'type': 'str', 'desc': 'The extended property to remove.', },
|
|
58
|
+
{'name': 'force', 'type': 'boolean', 'default': False,
|
|
59
|
+
'desc': 'Delete the property from all nodes before removing the definition.', },
|
|
57
60
|
),
|
|
58
61
|
'returns': {'type': 'null', }}},
|
|
59
62
|
{'name': 'delUnivProp',
|
|
@@ -61,12 +64,16 @@ class LibModelExt(s_stormtypes.Lib):
|
|
|
61
64
|
'type': {'type': 'function', '_funcname': 'delUnivProp',
|
|
62
65
|
'args': (
|
|
63
66
|
{'name': 'propname', 'type': 'str', 'desc': 'Name of the universal property to remove.', },
|
|
67
|
+
{'name': 'force', 'type': 'boolean', 'default': False,
|
|
68
|
+
'desc': 'Delete the property from all nodes before removing the definition.', },
|
|
64
69
|
),
|
|
65
70
|
'returns': {'type': 'null', }}},
|
|
66
71
|
{'name': 'delTagProp', 'desc': 'Remove an extended tag property definition from the model.',
|
|
67
72
|
'type': {'type': 'function', '_funcname': 'delTagProp',
|
|
68
73
|
'args': (
|
|
69
74
|
{'name': 'propname', 'type': 'str', 'desc': 'Name of the tag property to remove.', },
|
|
75
|
+
{'name': 'force', 'type': 'boolean', 'default': False,
|
|
76
|
+
'desc': 'Delete the tag property from all nodes before removing the definition.', },
|
|
70
77
|
),
|
|
71
78
|
'returns': {'type': 'null', }}},
|
|
72
79
|
{'name': 'getExtModel', 'desc': 'Get all extended model elements.',
|
|
@@ -163,20 +170,39 @@ class LibModelExt(s_stormtypes.Lib):
|
|
|
163
170
|
s_stormtypes.confirm(('model', 'form', 'del', formname))
|
|
164
171
|
await self.runt.snap.core.delForm(formname)
|
|
165
172
|
|
|
166
|
-
async def delFormProp(self, formname, propname):
|
|
173
|
+
async def delFormProp(self, formname, propname, force=False):
|
|
167
174
|
formname = await s_stormtypes.tostr(formname)
|
|
168
175
|
propname = await s_stormtypes.tostr(propname)
|
|
176
|
+
force = await s_stormtypes.tobool(force)
|
|
169
177
|
s_stormtypes.confirm(('model', 'prop', 'del', formname))
|
|
178
|
+
|
|
179
|
+
if force is True:
|
|
180
|
+
meta = {'user': self.runt.snap.user.iden, 'time': s_common.now()}
|
|
181
|
+
await self.runt.snap.core._delAllFormProp(formname, propname, meta)
|
|
182
|
+
|
|
170
183
|
await self.runt.snap.core.delFormProp(formname, propname)
|
|
171
184
|
|
|
172
|
-
async def delUnivProp(self, propname):
|
|
185
|
+
async def delUnivProp(self, propname, force=False):
|
|
173
186
|
propname = await s_stormtypes.tostr(propname)
|
|
187
|
+
force = await s_stormtypes.tobool(force)
|
|
174
188
|
s_stormtypes.confirm(('model', 'univ', 'del'))
|
|
189
|
+
|
|
190
|
+
if force:
|
|
191
|
+
meta = {'user': self.runt.snap.user.iden, 'time': s_common.now()}
|
|
192
|
+
await self.runt.snap.core._delAllUnivProp(propname, meta)
|
|
193
|
+
|
|
175
194
|
await self.runt.snap.core.delUnivProp(propname)
|
|
176
195
|
|
|
177
|
-
async def delTagProp(self, propname):
|
|
196
|
+
async def delTagProp(self, propname, force=False):
|
|
178
197
|
propname = await s_stormtypes.tostr(propname)
|
|
198
|
+
force = await s_stormtypes.tobool(force)
|
|
199
|
+
|
|
179
200
|
s_stormtypes.confirm(('model', 'tagprop', 'del'))
|
|
201
|
+
|
|
202
|
+
if force:
|
|
203
|
+
meta = {'user': self.runt.snap.user.iden, 'time': s_common.now()}
|
|
204
|
+
await self.runt.snap.core._delAllTagProp(propname, meta)
|
|
205
|
+
|
|
180
206
|
await self.runt.snap.core.delTagProp(propname)
|
|
181
207
|
|
|
182
208
|
@s_stormtypes.stormfunc(readonly=True)
|
synapse/lib/stormlib/stix.py
CHANGED
|
@@ -11,6 +11,7 @@ import synapse.common as s_common
|
|
|
11
11
|
import synapse.lib.coro as s_coro
|
|
12
12
|
import synapse.lib.node as s_node
|
|
13
13
|
import synapse.lib.msgpack as s_msgpack
|
|
14
|
+
import synapse.lib.schemas as s_schemas
|
|
14
15
|
import synapse.lib.stormctrl as s_stormctrl
|
|
15
16
|
import synapse.lib.stormtypes as s_stormtypes
|
|
16
17
|
|
|
@@ -875,14 +876,19 @@ class LibStixImport(s_stormtypes.Lib):
|
|
|
875
876
|
bundle = await s_stormtypes.toprim(bundle)
|
|
876
877
|
config = await s_stormtypes.toprim(config)
|
|
877
878
|
|
|
879
|
+
if not isinstance(config, dict):
|
|
880
|
+
mesg = 'STIX ingest config must be a dictionary.'
|
|
881
|
+
raise s_exc.BadArg(mesg=mesg)
|
|
882
|
+
|
|
878
883
|
config.setdefault('bundle', {})
|
|
879
884
|
config.setdefault('objects', {})
|
|
880
885
|
config.setdefault('relationships', [])
|
|
881
886
|
|
|
882
|
-
|
|
883
|
-
|
|
884
|
-
|
|
885
|
-
|
|
887
|
+
try:
|
|
888
|
+
rellook = {r['type']: r for r in config.get('relationships', ())}
|
|
889
|
+
except Exception as e:
|
|
890
|
+
mesg = f'Error processing relationships in STIX bundle ingest config: {e}.'
|
|
891
|
+
raise s_exc.BadArg(mesg=mesg)
|
|
886
892
|
|
|
887
893
|
bundlenode = None
|
|
888
894
|
|
|
@@ -890,13 +896,44 @@ class LibStixImport(s_stormtypes.Lib):
|
|
|
890
896
|
if bundleconf is None:
|
|
891
897
|
bundleconf = {}
|
|
892
898
|
|
|
899
|
+
if not isinstance(bundleconf, dict):
|
|
900
|
+
mesg = 'STIX ingest config bundle value must be a dictionary.'
|
|
901
|
+
raise s_exc.BadArg(mesg=mesg)
|
|
902
|
+
|
|
893
903
|
bundlestorm = bundleconf.get('storm')
|
|
894
904
|
if bundlestorm:
|
|
905
|
+
if not isinstance(bundlestorm, str):
|
|
906
|
+
mesg = 'STIX ingest config storm query must be a string.'
|
|
907
|
+
raise s_exc.BadArg(mesg=mesg)
|
|
908
|
+
|
|
895
909
|
bundlenode = await self._callStorm(bundlestorm, {'bundle': bundle})
|
|
896
910
|
|
|
897
911
|
self.runt.layerConfirm(('node', 'edge', 'add', 'refs'))
|
|
898
912
|
|
|
899
|
-
|
|
913
|
+
config = s_schemas.reqValidStixIngestConfig(config)
|
|
914
|
+
bundle = s_schemas.reqValidStixIngestBundle(bundle)
|
|
915
|
+
|
|
916
|
+
try:
|
|
917
|
+
nodesbyid = await self._ingestObjects(bundle, config, rellook)
|
|
918
|
+
except Exception as e:
|
|
919
|
+
mesg = f'Error processing objects in STIX bundle ingest: {e}.'
|
|
920
|
+
raise s_exc.BadArg(mesg=mesg)
|
|
921
|
+
|
|
922
|
+
if bundlenode is not None:
|
|
923
|
+
for node in nodesbyid.values():
|
|
924
|
+
await bundlenode.addEdge('refs', node.iden())
|
|
925
|
+
await asyncio.sleep(0)
|
|
926
|
+
yield bundlenode
|
|
927
|
+
|
|
928
|
+
for node in nodesbyid.values():
|
|
929
|
+
yield node
|
|
930
|
+
|
|
931
|
+
async def _ingestObjects(self, bundle, config, rellook):
|
|
932
|
+
|
|
933
|
+
nodesbyid = {}
|
|
934
|
+
relationships = []
|
|
935
|
+
|
|
936
|
+
for obj in bundle.get('objects', ()):
|
|
900
937
|
|
|
901
938
|
objtype = obj.get('type')
|
|
902
939
|
|
|
@@ -971,7 +1008,7 @@ class LibStixImport(s_stormtypes.Lib):
|
|
|
971
1008
|
await self.runt.snap.warnonce(f'STIX bundle ingest has no relationship definition for: {reltype}.')
|
|
972
1009
|
|
|
973
1010
|
# attempt to resolve object_refs
|
|
974
|
-
for obj in bundle.get('objects'):
|
|
1011
|
+
for obj in bundle.get('objects', ()):
|
|
975
1012
|
|
|
976
1013
|
node = nodesbyid.get(obj.get('id'))
|
|
977
1014
|
if node is None:
|
|
@@ -984,17 +1021,7 @@ class LibStixImport(s_stormtypes.Lib):
|
|
|
984
1021
|
|
|
985
1022
|
await node.addEdge('refs', refsnode.iden())
|
|
986
1023
|
|
|
987
|
-
|
|
988
|
-
for node in nodesbyid.values():
|
|
989
|
-
await bundlenode.addEdge('refs', node.iden())
|
|
990
|
-
await asyncio.sleep(0)
|
|
991
|
-
yield bundlenode
|
|
992
|
-
|
|
993
|
-
for node in nodesbyid.values():
|
|
994
|
-
yield node
|
|
995
|
-
|
|
996
|
-
if bundlenode:
|
|
997
|
-
yield bundlenode
|
|
1024
|
+
return nodesbyid
|
|
998
1025
|
|
|
999
1026
|
async def _callStorm(self, text, varz):
|
|
1000
1027
|
|
synapse/lib/stormlib/vault.py
CHANGED
|
@@ -649,7 +649,7 @@ class Vault(s_stormtypes.Prim):
|
|
|
649
649
|
'type': {'type': 'function', '_funcname': '_methSetPerm',
|
|
650
650
|
'args': (
|
|
651
651
|
{'name': 'iden', 'type': 'str', 'desc': 'The user or role to modify.'},
|
|
652
|
-
{'name': 'level', 'type': 'str', 'desc': 'The easyperm level for the iden. $lib.
|
|
652
|
+
{'name': 'level', 'type': 'str', 'desc': 'The easyperm level for the iden. $lib.null to remove an existing permission.'},
|
|
653
653
|
),
|
|
654
654
|
'returns': {'type': 'boolean', 'desc': '$lib.true if the permission was set, $lib.false otherwise.', }}},
|
|
655
655
|
|
|
@@ -744,7 +744,7 @@ class Vault(s_stormtypes.Prim):
|
|
|
744
744
|
s_stormtypes.confirmEasyPerm(vault, s_cell.PERM_ADMIN, mesg=mesg)
|
|
745
745
|
|
|
746
746
|
iden = await s_stormtypes.tostr(iden)
|
|
747
|
-
level = await s_stormtypes.toint(level)
|
|
747
|
+
level = await s_stormtypes.toint(level, noneok=True)
|
|
748
748
|
|
|
749
749
|
return await self.runt.snap.core.setVaultPerm(self.valu, iden, level)
|
|
750
750
|
|
synapse/lib/stormtypes.py
CHANGED
|
@@ -5277,7 +5277,7 @@ class Number(Prim):
|
|
|
5277
5277
|
def __init__(self, valu, path=None):
|
|
5278
5278
|
try:
|
|
5279
5279
|
valu = s_common.hugenum(valu)
|
|
5280
|
-
except decimal.DecimalException as e:
|
|
5280
|
+
except (TypeError, decimal.DecimalException) as e:
|
|
5281
5281
|
mesg = f'Failed to make number from {valu!r}'
|
|
5282
5282
|
raise s_exc.BadCast(mesg=mesg) from e
|
|
5283
5283
|
|
synapse/lib/types.py
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import sys
|
|
1
2
|
import asyncio
|
|
2
3
|
import decimal
|
|
3
4
|
import logging
|
|
@@ -78,6 +79,14 @@ class Type:
|
|
|
78
79
|
|
|
79
80
|
self.postTypeInit()
|
|
80
81
|
|
|
82
|
+
normopts = dict(self.opts)
|
|
83
|
+
for optn, valu in normopts.items():
|
|
84
|
+
if isinstance(valu, float):
|
|
85
|
+
normopts[optn] = str(valu)
|
|
86
|
+
|
|
87
|
+
ctor = '.'.join([self.__class__.__module__, self.__class__.__qualname__])
|
|
88
|
+
self.typehash = sys.intern(s_common.guid((ctor, s_common.flatten(normopts))))
|
|
89
|
+
|
|
81
90
|
def _storLiftSafe(self, cmpr, valu):
|
|
82
91
|
try:
|
|
83
92
|
return self.storlifts['=']('=', valu)
|
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, 180, 0)
|
|
227
227
|
verstring = '.'.join([str(x) for x in version])
|
|
228
|
-
commit = '
|
|
228
|
+
commit = 'aecbb8c0839f3ad763076dd7acae968fae6ba8b7'
|