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
|
@@ -692,6 +692,9 @@ class StormHttpTest(s_test.SynTest):
|
|
|
692
692
|
tlscadir = s_common.gendir(dirn, 'cadir')
|
|
693
693
|
cacertpath = shutil.copyfile(os.path.join(cadir, 'somelocalca.crt'), os.path.join(tlscadir, 'somelocalca.crt'))
|
|
694
694
|
|
|
695
|
+
with s_common.genfile(cacertpath) as fd:
|
|
696
|
+
ca_cert = fd.read().decode()
|
|
697
|
+
|
|
695
698
|
pkey, cert = tdir.genUserCert('someuser', signas='somelocalca')
|
|
696
699
|
user_pkey = tdir._pkeyToByts(pkey).decode()
|
|
697
700
|
user_cert = tdir._certToByts(cert).decode()
|
|
@@ -835,3 +838,40 @@ class StormHttpTest(s_test.SynTest):
|
|
|
835
838
|
## bad cert
|
|
836
839
|
sslopts['client_cert'] = 'not-gonna-work'
|
|
837
840
|
await self.asyncraises(s_exc.BadArg, core.callStorm(q, opts=opts))
|
|
841
|
+
|
|
842
|
+
# Provide a CA certificate directly
|
|
843
|
+
async with self.getTestCore(dirn=dirn) as core:
|
|
844
|
+
|
|
845
|
+
sslctx = core.initSslCtx(certpath, pkeypath)
|
|
846
|
+
sslctx.load_verify_locations(cafile=cacertpath)
|
|
847
|
+
|
|
848
|
+
addr, port = await core.addHttpsPort(0, sslctx=sslctx)
|
|
849
|
+
root = await core.auth.getUserByName('root')
|
|
850
|
+
await root.setPasswd('root')
|
|
851
|
+
|
|
852
|
+
core.addHttpApi('/api/v0/test', s_test.HttpReflector, {'cell': core})
|
|
853
|
+
|
|
854
|
+
sslopts = {}
|
|
855
|
+
|
|
856
|
+
opts = {
|
|
857
|
+
'vars': {
|
|
858
|
+
'url': f'https://root:root@localhost:{port}/api/v0/test',
|
|
859
|
+
'verify': True,
|
|
860
|
+
'sslopts': sslopts,
|
|
861
|
+
},
|
|
862
|
+
}
|
|
863
|
+
|
|
864
|
+
q = 'return($lib.inet.http.get($url, ssl_verify=$verify, ssl_opts=$sslopts))'
|
|
865
|
+
|
|
866
|
+
size, sha256 = await core.callStorm('return($lib.bytes.put($lib.base64.decode(Zm9v)))')
|
|
867
|
+
opts['vars']['sha256'] = sha256
|
|
868
|
+
|
|
869
|
+
## no cert provided
|
|
870
|
+
resp = await core.callStorm(q, opts=opts)
|
|
871
|
+
self.eq(-1, resp['code'])
|
|
872
|
+
self.isin('certificate verify failed', resp['reason'])
|
|
873
|
+
|
|
874
|
+
## provide just the CA Certificate
|
|
875
|
+
sslopts['ca_cert'] = ca_cert
|
|
876
|
+
resp = await core.callStorm(q, opts=opts)
|
|
877
|
+
self.eq(200, resp['code'])
|
|
@@ -57,12 +57,24 @@ class StormtypesModelextTest(s_test.SynTest):
|
|
|
57
57
|
model_defs = await core.callStorm('return ( $lib.model.ext.getExtModel() )')
|
|
58
58
|
self.isinstance(model_defs, dict)
|
|
59
59
|
|
|
60
|
+
self.len(1, await core.nodes('_visi:int:tick'))
|
|
61
|
+
await core._delAllFormProp('_visi:int', 'tick', {})
|
|
62
|
+
self.len(0, await core.nodes('_visi:int:tick'))
|
|
63
|
+
|
|
64
|
+
self.len(1, await core.nodes('._woot'))
|
|
65
|
+
await core._delAllUnivProp('_woot', {})
|
|
66
|
+
self.len(0, await core.nodes('._woot'))
|
|
67
|
+
|
|
68
|
+
self.len(1, await core.nodes('#lol:score'))
|
|
69
|
+
await core._delAllTagProp('score', {})
|
|
70
|
+
self.len(0, await core.nodes('#lol:score'))
|
|
71
|
+
|
|
60
72
|
await core.callStorm('_visi:int=10 test:int=1234 | delnode')
|
|
61
73
|
await core.callStorm('''
|
|
62
|
-
$lib.model.ext.delTagProp(score)
|
|
63
|
-
$lib.model.ext.delUnivProp(_woot)
|
|
74
|
+
$lib.model.ext.delTagProp(score, force=(true))
|
|
75
|
+
$lib.model.ext.delUnivProp(_woot, force=(true))
|
|
64
76
|
$lib.model.ext.delFormProp(_visi:int, tick)
|
|
65
|
-
$lib.model.ext.delFormProp(test:int, _tick)
|
|
77
|
+
$lib.model.ext.delFormProp(test:int, _tick, force=(true))
|
|
66
78
|
$lib.model.ext.delForm(_visi:int)
|
|
67
79
|
$lib.model.ext.delEdge(inet:user, _copies, *)
|
|
68
80
|
''')
|
|
@@ -276,6 +288,46 @@ class StormtypesModelextTest(s_test.SynTest):
|
|
|
276
288
|
|
|
277
289
|
self.nn(core.model.edge(('inet:user', '_copies', None)))
|
|
278
290
|
|
|
291
|
+
# Property values left behind in layers are cleanly removed
|
|
292
|
+
async with self.getTestCore() as core:
|
|
293
|
+
await core.callStorm('''
|
|
294
|
+
$typeinfo = ({})
|
|
295
|
+
$docinfo = ({"doc": "NEWP"})
|
|
296
|
+
$lib.model.ext.addUnivProp(_woot, (int, ({})), $docinfo)
|
|
297
|
+
$lib.model.ext.addTagProp(score, (int, ({})), $docinfo)
|
|
298
|
+
$lib.model.ext.addFormProp(test:int, _tick, (time, ({})), $docinfo)
|
|
299
|
+
''')
|
|
300
|
+
fork = await core.callStorm('return ( $lib.view.get().fork().iden ) ')
|
|
301
|
+
nodes = await core.nodes('[test:int=1234 :_tick=2024 ._woot=1 +#hehe:score=10]')
|
|
302
|
+
self.len(1, nodes)
|
|
303
|
+
self.eq(nodes[0].get('._woot'), 1)
|
|
304
|
+
|
|
305
|
+
nodes = await core.nodes('test:int=1234 [:_tick=2023 ._woot=2 +#hehe:score=9]',
|
|
306
|
+
opts={'view': fork})
|
|
307
|
+
self.len(1, nodes)
|
|
308
|
+
self.eq(nodes[0].get('._woot'), 2)
|
|
309
|
+
|
|
310
|
+
self.len(0, await core.nodes('test:int | delnode'))
|
|
311
|
+
|
|
312
|
+
with self.raises(s_exc.CantDelUniv):
|
|
313
|
+
await core.callStorm('$lib.model.ext.delUnivProp(_woot)')
|
|
314
|
+
with self.raises(s_exc.CantDelProp):
|
|
315
|
+
await core.callStorm('$lib.model.ext.delFormProp(test:int, _tick)')
|
|
316
|
+
with self.raises(s_exc.CantDelProp):
|
|
317
|
+
await core.callStorm('$lib.model.ext.delTagProp(score)')
|
|
318
|
+
|
|
319
|
+
await core.callStorm('$lib.model.ext.delUnivProp(_woot, force=(true))')
|
|
320
|
+
await core.callStorm('$lib.model.ext.delFormProp(test:int, _tick, force=(true))')
|
|
321
|
+
await core.callStorm('$lib.model.ext.delTagProp(score, force=(true))')
|
|
322
|
+
|
|
323
|
+
nodes = await core.nodes('[test:int=1234]')
|
|
324
|
+
self.len(1, nodes)
|
|
325
|
+
self.none(nodes[0].get('._woot'))
|
|
326
|
+
self.none(nodes[0].get('_tick'))
|
|
327
|
+
nodes = await core.nodes('test:int=1234', opts={'view': fork})
|
|
328
|
+
self.none(nodes[0].get('._woot'))
|
|
329
|
+
self.none(nodes[0].get('_tick'))
|
|
330
|
+
|
|
279
331
|
async def test_lib_stormlib_behold_modelext(self):
|
|
280
332
|
self.skipIfNexusReplay()
|
|
281
333
|
async with self.getTestCore() as core:
|
|
@@ -410,6 +410,21 @@ class StormLibStixTest(s_test.SynTest):
|
|
|
410
410
|
self.len(1, [n for n in nodes if n[0][0] == 'it:cmd'])
|
|
411
411
|
self.stormIsInWarn("STIX bundle ingest has no relationship definition for: ('threat-actor', 'gronks', 'threat-actor')", msgs)
|
|
412
412
|
|
|
413
|
+
msgs = await core.stormlist('yield $lib.stix.import.ingest(({}), newp)')
|
|
414
|
+
self.stormIsInErr('config must be a dictionary', msgs)
|
|
415
|
+
|
|
416
|
+
msgs = await core.stormlist('yield $lib.stix.import.ingest(({}), ({"relationships": 5}))')
|
|
417
|
+
self.stormIsInErr('Error processing relationships', msgs)
|
|
418
|
+
|
|
419
|
+
msgs = await core.stormlist('yield $lib.stix.import.ingest(({}), ({"bundle": 3}))')
|
|
420
|
+
self.stormIsInErr('bundle value must be a dictionary', msgs)
|
|
421
|
+
|
|
422
|
+
msgs = await core.stormlist('yield $lib.stix.import.ingest(({}), ({"bundle": {"storm": 3}}))')
|
|
423
|
+
self.stormIsInErr('storm query must be a string', msgs)
|
|
424
|
+
|
|
425
|
+
msgs = await core.stormlist('yield $lib.stix.import.ingest(({"objects": 3}), ({}))')
|
|
426
|
+
self.stormIsInErr('data.objects must be array', msgs)
|
|
427
|
+
|
|
413
428
|
async def test_stix_export_custom(self):
|
|
414
429
|
|
|
415
430
|
async with self.getTestCore() as core:
|
|
@@ -159,10 +159,13 @@ class StormlibVaultTest(s_test.SynTest):
|
|
|
159
159
|
|
|
160
160
|
# Rename vault
|
|
161
161
|
opts = {'vars': {'giden': giden}}
|
|
162
|
+
self.eq('gvault', await core.callStorm('return($lib.vault.get($giden).name)', opts=opts))
|
|
162
163
|
q = '$lib.vault.get($giden).name = foobar'
|
|
163
164
|
await core.callStorm(q, opts=opts)
|
|
164
165
|
vault = core.getVault(giden)
|
|
165
166
|
self.eq(vault.get('name'), 'foobar')
|
|
167
|
+
self.nn(await core.callStorm('return($lib.vault.byname(foobar))'))
|
|
168
|
+
await self.asyncraises(s_exc.NoSuchName, core.callStorm('return($lib.vault.byname(gvault))'))
|
|
166
169
|
|
|
167
170
|
# Get secrets without EDIT perms
|
|
168
171
|
opts = {'vars': {'giden': giden}, 'user': visi1.iden}
|
|
@@ -222,10 +225,17 @@ class StormlibVaultTest(s_test.SynTest):
|
|
|
222
225
|
q = '$vault = $lib.vault.get($giden) return($vault.setPerm($iden, $lib.auth.easyperm.level.deny))'
|
|
223
226
|
self.true(await core.callStorm(q, opts=opts))
|
|
224
227
|
|
|
225
|
-
# List vaults again
|
|
226
228
|
opts = {'user': visi1.iden}
|
|
227
229
|
self.eq(0, await core.callStorm('return($lib.len($lib.vault.list()))', opts=opts))
|
|
228
230
|
|
|
231
|
+
# Remove permission on global vault
|
|
232
|
+
opts = {'vars': {'iden': visi1.iden, 'giden': giden}}
|
|
233
|
+
q = '$vault = $lib.vault.get($giden) return($vault.setPerm($iden, $lib.null))'
|
|
234
|
+
self.true(await core.callStorm(q, opts=opts))
|
|
235
|
+
|
|
236
|
+
opts = {'user': visi1.iden}
|
|
237
|
+
self.eq(1, await core.callStorm('return($lib.len($lib.vault.list()))', opts=opts))
|
|
238
|
+
|
|
229
239
|
# Runtime asroot
|
|
230
240
|
|
|
231
241
|
await core.addStormPkg({
|
|
@@ -6388,6 +6388,11 @@ words\tword\twrd'''
|
|
|
6388
6388
|
self.eq(1, await core.callStorm('return($lib.math.number(1.23).toint())'))
|
|
6389
6389
|
self.eq(2, await core.callStorm('return($lib.math.number(1.23).toint(rounding=ROUND_UP))'))
|
|
6390
6390
|
|
|
6391
|
+
with self.raises(s_exc.BadCast):
|
|
6392
|
+
await core.callStorm('return($lib.math.number((null)))')
|
|
6393
|
+
with self.raises(s_exc.BadCast):
|
|
6394
|
+
await core.callStorm('return($lib.math.number(newp))')
|
|
6395
|
+
|
|
6391
6396
|
with self.raises(s_exc.StormRuntimeError):
|
|
6392
6397
|
await core.callStorm('return($lib.math.number(1.23).toint(rounding=NEWP))')
|
|
6393
6398
|
|
synapse/tests/test_lib_types.py
CHANGED
|
@@ -1606,3 +1606,12 @@ class TypesTest(s_t_utils.SynTest):
|
|
|
1606
1606
|
|
|
1607
1607
|
core.getLayer()._testAddPropArrayIndx(buid, 'test:int', '_hehe', ('newp' * 100,))
|
|
1608
1608
|
self.len(0, await core.nodes('test:int:_hehe*[~=newp]'))
|
|
1609
|
+
|
|
1610
|
+
async def test_types_typehash(self):
|
|
1611
|
+
async with self.getTestCore() as core:
|
|
1612
|
+
self.true(core.model.form('inet:fqdn').type.typehash is core.model.prop('inet:dns:a:fqdn').type.typehash)
|
|
1613
|
+
self.true(core.model.form('it:prod:softname').type.typehash is core.model.prop('it:network:name').type.typehash)
|
|
1614
|
+
self.true(core.model.form('inet:asn').type.typehash is not core.model.prop('inet:proto:port').type.typehash)
|
|
1615
|
+
|
|
1616
|
+
self.true(s_common.isguid(core.model.form('inet:fqdn').type.typehash))
|
|
1617
|
+
self.true(s_common.isguid(core.model.form('inet:fqdn').typehash))
|
synapse/tests/test_model_dns.py
CHANGED
|
@@ -108,6 +108,14 @@ class DnsModelTest(s_t_utils.SynTest):
|
|
|
108
108
|
self.eq(node.get('name:fqdn'), 'vertex.link')
|
|
109
109
|
self.eq(node.get('type'), 255)
|
|
110
110
|
|
|
111
|
+
nodes = await core.nodes('[inet:dns:request=* :reply:code=NXDOMAIN]')
|
|
112
|
+
self.eq(nodes[0].get('reply:code'), 3)
|
|
113
|
+
self.eq(nodes[0].repr('reply:code'), 'NXDOMAIN')
|
|
114
|
+
|
|
115
|
+
nodes = await core.nodes('[inet:dns:request=* :reply:code=1138]')
|
|
116
|
+
self.eq(nodes[0].get('reply:code'), 1138)
|
|
117
|
+
self.eq(nodes[0].repr('reply:code'), '1138')
|
|
118
|
+
|
|
111
119
|
nodes = await core.nodes('[inet:dns:query=("tcp://1.2.3.4", 4.3.2.1.in-addr.arpa, 255)]')
|
|
112
120
|
self.len(1, nodes)
|
|
113
121
|
node = nodes[0]
|
|
@@ -108,6 +108,7 @@ class GeoPolModelTest(s_t_utils.SynTest):
|
|
|
108
108
|
|
|
109
109
|
nodes = await core.nodes('''
|
|
110
110
|
[ pol:candidate=*
|
|
111
|
+
:id=" P00009423"
|
|
111
112
|
:race={pol:race}
|
|
112
113
|
:contact={[ps:contact=* :name=whippit]}
|
|
113
114
|
:winner=$lib.true
|
|
@@ -116,6 +117,7 @@ class GeoPolModelTest(s_t_utils.SynTest):
|
|
|
116
117
|
]
|
|
117
118
|
''')
|
|
118
119
|
self.eq(1, nodes[0].get('winner'))
|
|
120
|
+
self.eq('P00009423', nodes[0].get('id'))
|
|
119
121
|
self.len(1, await core.nodes('pol:candidate -> pol:race'))
|
|
120
122
|
self.len(1, await core.nodes('pol:candidate -> ou:org +:name=vertex'))
|
|
121
123
|
self.len(1, await core.nodes('pol:candidate -> ps:contact +:name=whippit'))
|
|
@@ -2,7 +2,6 @@ import synapse.exc as s_exc
|
|
|
2
2
|
import synapse.common as s_common
|
|
3
3
|
|
|
4
4
|
import synapse.tests.utils as s_t_utils
|
|
5
|
-
from synapse.tests.utils import alist
|
|
6
5
|
|
|
7
6
|
import synapse.lib.module as s_module
|
|
8
7
|
|
|
@@ -499,6 +498,7 @@ class GeoTest(s_t_utils.SynTest):
|
|
|
499
498
|
:place:name=woot
|
|
500
499
|
:place={[geo:place=* :name=woot]}
|
|
501
500
|
:accuracy=10m
|
|
501
|
+
:node=(test:int, 1234)
|
|
502
502
|
]
|
|
503
503
|
''')
|
|
504
504
|
self.eq(1655510400000, nodes[0].get('time'))
|
|
@@ -507,6 +507,8 @@ class GeoTest(s_t_utils.SynTest):
|
|
|
507
507
|
self.eq('woot', nodes[0].get('place:name'))
|
|
508
508
|
self.eq(10000, nodes[0].get('accuracy'))
|
|
509
509
|
self.len(1, await core.nodes('geo:telem -> geo:place +:name=woot'))
|
|
510
|
+
self.eq(('test:int', 1234), nodes[0].get('node'))
|
|
511
|
+
self.len(1, await core.nodes('test:int=1234'))
|
|
510
512
|
|
|
511
513
|
async def test_model_geospace_area(self):
|
|
512
514
|
|
synapse/tests/test_model_inet.py
CHANGED
|
@@ -2684,7 +2684,15 @@ class InetModelTest(s_t_utils.SynTest):
|
|
|
2684
2684
|
'acct': 'vertex.link/visi',
|
|
2685
2685
|
}
|
|
2686
2686
|
|
|
2687
|
-
q = '[
|
|
2687
|
+
q = '''[
|
|
2688
|
+
inet:search:query=$valu
|
|
2689
|
+
:time=$p.time
|
|
2690
|
+
:text=$p.text
|
|
2691
|
+
:engine=$p.engine
|
|
2692
|
+
:acct=$p.acct
|
|
2693
|
+
:host=$p.host
|
|
2694
|
+
:account=*
|
|
2695
|
+
]'''
|
|
2688
2696
|
nodes = await core.nodes(q, opts={'vars': {'valu': iden, 'p': props}})
|
|
2689
2697
|
self.len(1, nodes)
|
|
2690
2698
|
node = nodes[0]
|
|
@@ -2694,6 +2702,7 @@ class InetModelTest(s_t_utils.SynTest):
|
|
|
2694
2702
|
self.eq(node.get('engine'), 'roofroof')
|
|
2695
2703
|
self.eq(node.get('host'), host)
|
|
2696
2704
|
self.eq(node.get('acct'), ('vertex.link', 'visi'))
|
|
2705
|
+
self.len(1, await core.nodes('inet:search:query :account -> inet:service:account'))
|
|
2697
2706
|
|
|
2698
2707
|
residen = s_common.guid()
|
|
2699
2708
|
props = {
|
|
@@ -407,6 +407,35 @@ class InfotechModelTest(s_t_utils.SynTest):
|
|
|
407
407
|
self.eq(nodes[0].get('net6'), ('fe80::', 'fe80::ffff:ffff:ffff:ffff'))
|
|
408
408
|
self.eq(nodes[0].get('type'), 'virtual.sdn.')
|
|
409
409
|
|
|
410
|
+
nodes = await core.nodes('''[
|
|
411
|
+
it:sec:stix:indicator=*
|
|
412
|
+
:id=zoinks
|
|
413
|
+
:name=woot
|
|
414
|
+
:confidence=90
|
|
415
|
+
:revoked=(false)
|
|
416
|
+
:description="my neato indicator"
|
|
417
|
+
:pattern="some rule text"
|
|
418
|
+
:pattern_type=yara
|
|
419
|
+
:created=20240815
|
|
420
|
+
:updated=20240815
|
|
421
|
+
:labels=(hehe, haha)
|
|
422
|
+
:valid_from=20240815
|
|
423
|
+
:valid_until=20240815
|
|
424
|
+
]''')
|
|
425
|
+
self.len(1, nodes)
|
|
426
|
+
self.eq('zoinks', nodes[0].get('id'))
|
|
427
|
+
self.eq('woot', nodes[0].get('name'))
|
|
428
|
+
self.eq(90, nodes[0].get('confidence'))
|
|
429
|
+
self.eq(False, nodes[0].get('revoked'))
|
|
430
|
+
self.eq('my neato indicator', nodes[0].get('description'))
|
|
431
|
+
self.eq('some rule text', nodes[0].get('pattern'))
|
|
432
|
+
self.eq('yara', nodes[0].get('pattern_type'))
|
|
433
|
+
self.eq(('haha', 'hehe'), nodes[0].get('labels'))
|
|
434
|
+
self.eq(1723680000000, nodes[0].get('created'))
|
|
435
|
+
self.eq(1723680000000, nodes[0].get('updated'))
|
|
436
|
+
self.eq(1723680000000, nodes[0].get('valid_from'))
|
|
437
|
+
self.eq(1723680000000, nodes[0].get('valid_until'))
|
|
438
|
+
|
|
410
439
|
async def test_infotech_ios(self):
|
|
411
440
|
|
|
412
441
|
async with self.getTestCore() as core:
|
|
@@ -1553,6 +1582,24 @@ class InfotechModelTest(s_t_utils.SynTest):
|
|
|
1553
1582
|
self.eq(rule, nodes[0].get('rule'))
|
|
1554
1583
|
self.eq(0x10000200003, nodes[0].get('version'))
|
|
1555
1584
|
|
|
1585
|
+
nodes = await core.nodes('''[
|
|
1586
|
+
(it:app:yara:netmatch=* :node=(inet:fqdn, foo.com))
|
|
1587
|
+
(it:app:yara:netmatch=* :node=(inet:ipv4, 1.2.3.4))
|
|
1588
|
+
(it:app:yara:netmatch=* :node=(inet:ipv6, "::ffff"))
|
|
1589
|
+
(it:app:yara:netmatch=* :node=(inet:url, "http://foo.com"))
|
|
1590
|
+
:rule=$rule
|
|
1591
|
+
:version=1.2.3
|
|
1592
|
+
]''', opts=opts)
|
|
1593
|
+
self.len(4, nodes)
|
|
1594
|
+
for node in nodes:
|
|
1595
|
+
self.nn(node.get('node'))
|
|
1596
|
+
self.nn(node.get('version'))
|
|
1597
|
+
|
|
1598
|
+
self.len(4, await core.nodes('it:app:yara:rule=$rule -> it:app:yara:netmatch', opts=opts))
|
|
1599
|
+
|
|
1600
|
+
with self.raises(s_exc.BadTypeValu):
|
|
1601
|
+
await core.nodes('[it:app:yara:netmatch=* :node=(it:dev:str, foo)]')
|
|
1602
|
+
|
|
1556
1603
|
async def test_it_app_snort(self):
|
|
1557
1604
|
|
|
1558
1605
|
async with self.getTestCore() as core:
|
|
@@ -165,6 +165,7 @@ class PsModelTest(s_t_utils.SynTest):
|
|
|
165
165
|
:birth:place:name=$p."birth:place:name"
|
|
166
166
|
:death:place=$p."death:place" :death:place:loc=$p."death:place:loc"
|
|
167
167
|
:death:place:name=$p."death:place:name"
|
|
168
|
+
:service:accounts=(*, *)
|
|
168
169
|
)]'''
|
|
169
170
|
nodes = await core.nodes(q, opts=opts)
|
|
170
171
|
self.len(1, nodes)
|
|
@@ -208,6 +209,7 @@ class PsModelTest(s_t_utils.SynTest):
|
|
|
208
209
|
self.eq(node.get('death:place:name'), 'reston, va, usa, earth, sol, milkyway')
|
|
209
210
|
self.len(1, await core.nodes('ps:contact :birth:place -> geo:place'))
|
|
210
211
|
self.len(1, await core.nodes('ps:contact :death:place -> geo:place'))
|
|
212
|
+
self.len(2, await core.nodes('ps:contact :service:accounts -> inet:service:account'))
|
|
211
213
|
|
|
212
214
|
nodes = await core.nodes('''[
|
|
213
215
|
ps:achievement=*
|
synapse/tests/test_model_syn.py
CHANGED
|
@@ -340,11 +340,22 @@ class SynModelTest(s_t_utils.SynTest):
|
|
|
340
340
|
nodes = await core.nodes(f'syn:trigger={iden}')
|
|
341
341
|
self.len(1, nodes)
|
|
342
342
|
|
|
343
|
+
indx = await core.getNexsIndx()
|
|
344
|
+
|
|
343
345
|
# set the trigger doc
|
|
344
346
|
nodes = await core.nodes(f'syn:trigger={iden} [ :doc=hehe ]')
|
|
345
347
|
self.len(1, nodes)
|
|
346
348
|
self.eq('hehe', nodes[0].get('doc'))
|
|
347
349
|
|
|
350
|
+
self.eq(await core.getNexsIndx(), indx + 1)
|
|
351
|
+
|
|
352
|
+
# set the trigger name
|
|
353
|
+
nodes = await core.nodes(f'syn:trigger={iden} [ :name=trigname ]')
|
|
354
|
+
self.len(1, nodes)
|
|
355
|
+
self.eq('trigname', nodes[0].get('name'))
|
|
356
|
+
|
|
357
|
+
self.eq(await core.getNexsIndx(), indx + 2)
|
|
358
|
+
|
|
348
359
|
# Trigger reloads and make some more triggers to play with
|
|
349
360
|
tdef = {'cond': 'prop:set', 'prop': 'inet:ipv4:asn', 'storm': '[inet:user=1] | testcmd'}
|
|
350
361
|
await core.view.addTrigger(tdef)
|
|
@@ -112,7 +112,7 @@ class TelcoModelTest(s_t_utils.SynTest):
|
|
|
112
112
|
q = '''[(tel:mob:telem=$valu :time=$p.time :latlong=$p.latlong :place=$p.place :host=$p.host
|
|
113
113
|
:loc=$p.loc :accuracy=$p.accuracy :cell=$p.cell :imsi=$p.imsi :imei=$p.imei :phone=$p.phone
|
|
114
114
|
:mac=$p.mac :ipv4=$p.ipv4 :ipv6=$p.ipv6 :wifi=$p.wifi :adid=$p.adid :aaid=$p.aaid :idfa=$p.idfa
|
|
115
|
-
:name=$p.name :email=$p.email :acct=$p.acct :app=$p.app :data=$p.data)]'''
|
|
115
|
+
:name=$p.name :email=$p.email :acct=$p.acct :app=$p.app :data=$p.data :account=*)]'''
|
|
116
116
|
nodes = await core.nodes(q, opts={'vars': {'valu': guid, 'p': props}})
|
|
117
117
|
self.len(1, nodes)
|
|
118
118
|
node = nodes[0]
|
|
@@ -142,6 +142,7 @@ class TelcoModelTest(s_t_utils.SynTest):
|
|
|
142
142
|
self.eq(node.get('acct'), ('vertex.link', 'clown'))
|
|
143
143
|
self.eq(node.get('app'), softguid)
|
|
144
144
|
self.eq(node.get('data'), {'some key': 'some valu', 'BEEP': 1})
|
|
145
|
+
self.len(1, await core.nodes('tel:mob:telem :account -> inet:service:account'))
|
|
145
146
|
|
|
146
147
|
async def test_telco_imei(self):
|
|
147
148
|
async with self.getTestCore() as core:
|
|
@@ -78,7 +78,7 @@ class TestUtilsStormcov(s_utils.SynTest):
|
|
|
78
78
|
await core.stormlist(s_files.getAssetStr('stormcov/lookup.storm'), opts={'mode': 'lookup'})
|
|
79
79
|
|
|
80
80
|
orig = s_snap.Snap.nodesByPropValu
|
|
81
|
-
async def nodesByPropValu(self, full, cmpr, valu):
|
|
81
|
+
async def nodesByPropValu(self, full, cmpr, valu, norm=True):
|
|
82
82
|
frame = inspect.currentframe()
|
|
83
83
|
if pivotracer.dynamic_source_filename(None, frame) is not None:
|
|
84
84
|
assert (2, 2) == pivotracer.line_number_range(frame)
|
synapse/tools/changelog.py
CHANGED
|
@@ -109,6 +109,8 @@ class ModelDiffer:
|
|
|
109
109
|
changes['new_edges'] = {k: _curv.get(k) for k in new_edges}
|
|
110
110
|
|
|
111
111
|
updated_edges = collections.defaultdict(dict)
|
|
112
|
+
deprecated_edges = {}
|
|
113
|
+
|
|
112
114
|
for edge, curinfo in _curv.items():
|
|
113
115
|
if edge in new_edges:
|
|
114
116
|
continue
|
|
@@ -116,12 +118,19 @@ class ModelDiffer:
|
|
|
116
118
|
if curinfo == oldinfo:
|
|
117
119
|
continue
|
|
118
120
|
|
|
121
|
+
if curinfo.get('deprecated') and not oldinfo.get('deprecated'):
|
|
122
|
+
deprecated_edges[edge] = curinfo
|
|
123
|
+
continue
|
|
124
|
+
|
|
119
125
|
# TODO - Support changes to the edges?
|
|
120
126
|
assert False, f'A change was found for the edge: {edge}'
|
|
121
127
|
|
|
122
128
|
if updated_edges:
|
|
123
129
|
changes['updated_edges'] = dict(updated_edges)
|
|
124
130
|
|
|
131
|
+
if deprecated_edges:
|
|
132
|
+
changes['deprecated_edges'] = deprecated_edges
|
|
133
|
+
|
|
125
134
|
return changes
|
|
126
135
|
|
|
127
136
|
def _compareForms(self, curv, oldv, outp: s_output.OutPut) -> dict:
|
|
@@ -723,6 +732,25 @@ def _gen_model_rst(version, model_ref, changes, current_model, outp: s_output.Ou
|
|
|
723
732
|
]
|
|
724
733
|
rst.addLines(*lines)
|
|
725
734
|
|
|
735
|
+
if dep_edges := changes.get('edges').get('deprecated_edges'):
|
|
736
|
+
|
|
737
|
+
rst.addHead('Deprecated Edges', lvl=1)
|
|
738
|
+
for (n1, name, n2), info in dep_edges.items():
|
|
739
|
+
if n1 is not None and n2 is not None:
|
|
740
|
+
mesg = f'''The edge has been deprecated when used with a ``{n1}`` and an ``{n2}`` node. {info.get('doc')}'''
|
|
741
|
+
elif n1 is None and n2 is not None:
|
|
742
|
+
mesg = f'''The edge has been deprecated when used with a ``{n2}`` target node. {info.get('doc')}'''
|
|
743
|
+
elif n1 is not None and n2 is None:
|
|
744
|
+
mesg = f'''The edge has been deprecated when used with a ``{n1}`` node. {info.get('doc')}'''
|
|
745
|
+
else:
|
|
746
|
+
mesg = f'''The edge has been deprecated. {info.get('doc')}'''
|
|
747
|
+
|
|
748
|
+
rst.addLines(
|
|
749
|
+
f'``{name}``',
|
|
750
|
+
*textwrap.wrap(mesg, initial_indent=' ', subsequent_indent=' ', width=width),
|
|
751
|
+
'\n',
|
|
752
|
+
)
|
|
753
|
+
|
|
726
754
|
return rst
|
|
727
755
|
|
|
728
756
|
|