synapse 2.187.0__py311-none-any.whl → 2.188.1__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 +131 -7
- synapse/datamodel.py +20 -4
- synapse/exc.py +14 -1
- synapse/lib/ast.py +6 -4
- synapse/lib/auth.py +9 -0
- synapse/lib/drive.py +1 -1
- synapse/lib/httpapi.py +2 -1
- synapse/lib/nexus.py +6 -0
- synapse/lib/node.py +5 -3
- synapse/lib/scrape.py +18 -104
- synapse/lib/storm.py +44 -28
- synapse/lib/stormlib/modelext.py +31 -0
- synapse/lib/stormlib/scrape.py +1 -4
- synapse/lib/stormtypes.py +17 -1
- synapse/lib/version.py +2 -2
- synapse/lib/view.py +9 -3
- synapse/models/base.py +27 -0
- synapse/models/files.py +22 -0
- synapse/models/inet.py +49 -4
- synapse/models/orgs.py +64 -2
- synapse/models/proj.py +1 -6
- synapse/models/risk.py +65 -0
- synapse/tests/test_cortex.py +21 -0
- synapse/tests/test_lib_agenda.py +13 -0
- synapse/tests/test_lib_auth.py +15 -0
- synapse/tests/test_lib_cell.py +170 -159
- synapse/tests/test_lib_httpapi.py +6 -0
- synapse/tests/test_lib_nexus.py +26 -0
- synapse/tests/test_lib_scrape.py +14 -6
- synapse/tests/test_lib_storm.py +48 -0
- synapse/tests/test_lib_stormlib_modelext.py +76 -1
- synapse/tests/test_lib_stormlib_scrape.py +0 -8
- synapse/tests/test_lib_stormtypes.py +1 -1
- synapse/tests/test_lib_trigger.py +8 -0
- synapse/tests/test_lib_view.py +24 -0
- synapse/tests/test_model_base.py +11 -0
- synapse/tests/test_model_files.py +19 -0
- synapse/tests/test_model_inet.py +33 -0
- synapse/tests/test_model_orgs.py +39 -0
- synapse/tests/test_model_proj.py +11 -1
- synapse/tests/test_model_risk.py +32 -0
- {synapse-2.187.0.dist-info → synapse-2.188.1.dist-info}/METADATA +1 -1
- {synapse-2.187.0.dist-info → synapse-2.188.1.dist-info}/RECORD +46 -46
- {synapse-2.187.0.dist-info → synapse-2.188.1.dist-info}/WHEEL +1 -1
- {synapse-2.187.0.dist-info → synapse-2.188.1.dist-info}/LICENSE +0 -0
- {synapse-2.187.0.dist-info → synapse-2.188.1.dist-info}/top_level.txt +0 -0
synapse/tests/test_lib_cell.py
CHANGED
|
@@ -29,6 +29,7 @@ import synapse.lib.coro as s_coro
|
|
|
29
29
|
import synapse.lib.link as s_link
|
|
30
30
|
import synapse.lib.drive as s_drive
|
|
31
31
|
import synapse.lib.nexus as s_nexus
|
|
32
|
+
import synapse.lib.config as s_config
|
|
32
33
|
import synapse.lib.certdir as s_certdir
|
|
33
34
|
import synapse.lib.msgpack as s_msgpack
|
|
34
35
|
import synapse.lib.version as s_version
|
|
@@ -160,8 +161,9 @@ testDataSchema_v0 = {
|
|
|
160
161
|
'properties': {
|
|
161
162
|
'type': {'type': 'string'},
|
|
162
163
|
'size': {'type': 'number'},
|
|
164
|
+
'stuff': {'type': ['number', 'null'], 'default': None}
|
|
163
165
|
},
|
|
164
|
-
'required': ['type', 'size'],
|
|
166
|
+
'required': ['type', 'size', 'stuff'],
|
|
165
167
|
'additionalProperties': False,
|
|
166
168
|
}
|
|
167
169
|
|
|
@@ -170,6 +172,7 @@ testDataSchema_v1 = {
|
|
|
170
172
|
'properties': {
|
|
171
173
|
'type': {'type': 'string'},
|
|
172
174
|
'size': {'type': 'number'},
|
|
175
|
+
'stuff': {'type': ['number', 'null'], 'default': None},
|
|
173
176
|
'woot': {'type': 'string'},
|
|
174
177
|
},
|
|
175
178
|
'required': ['type', 'size', 'woot'],
|
|
@@ -180,202 +183,210 @@ class CellTest(s_t_utils.SynTest):
|
|
|
180
183
|
|
|
181
184
|
async def test_cell_drive(self):
|
|
182
185
|
|
|
183
|
-
|
|
186
|
+
with self.getTestDir() as dirn:
|
|
187
|
+
async with self.getTestCell(dirn=dirn) as cell:
|
|
184
188
|
|
|
185
|
-
|
|
186
|
-
|
|
189
|
+
with self.raises(s_exc.BadName):
|
|
190
|
+
s_drive.reqValidName('A' * 512)
|
|
187
191
|
|
|
188
|
-
|
|
189
|
-
|
|
192
|
+
info = {'name': 'users'}
|
|
193
|
+
pathinfo = await cell.addDriveItem(info)
|
|
190
194
|
|
|
191
|
-
|
|
192
|
-
|
|
195
|
+
info = {'name': 'root'}
|
|
196
|
+
pathinfo = await cell.addDriveItem(info, path='users')
|
|
193
197
|
|
|
194
|
-
|
|
195
|
-
|
|
198
|
+
with self.raises(s_exc.DupIden):
|
|
199
|
+
await cell.drive.addItemInfo(pathinfo[-1], path='users')
|
|
196
200
|
|
|
197
|
-
|
|
198
|
-
|
|
201
|
+
rootdir = pathinfo[-1].get('iden')
|
|
202
|
+
self.eq(0, pathinfo[-1].get('kids'))
|
|
199
203
|
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
204
|
+
info = {'name': 'win32k.sys', 'type': 'hehe'}
|
|
205
|
+
with self.raises(s_exc.NoSuchType):
|
|
206
|
+
info = await cell.addDriveItem(info, reldir=rootdir)
|
|
207
|
+
|
|
208
|
+
infos = [i async for i in cell.getDriveKids(s_drive.rootdir)]
|
|
209
|
+
self.len(1, infos)
|
|
210
|
+
self.eq(1, infos[0].get('kids'))
|
|
211
|
+
self.eq('users', infos[0].get('name'))
|
|
212
|
+
|
|
213
|
+
# TODO how to handle iden match with additional property mismatch
|
|
203
214
|
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
self.eq('users', infos[0].get('name'))
|
|
215
|
+
self.true(await cell.drive.setTypeSchema('woot', testDataSchema_v0, vers=0))
|
|
216
|
+
self.true(await cell.drive.setTypeSchema('woot', testDataSchema_v0, vers=1))
|
|
217
|
+
self.false(await cell.drive.setTypeSchema('woot', testDataSchema_v0, vers=1))
|
|
208
218
|
|
|
209
|
-
|
|
219
|
+
with self.raises(s_exc.BadVersion):
|
|
220
|
+
await cell.drive.setTypeSchema('woot', testDataSchema_v0, vers=0)
|
|
210
221
|
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
self.false(await cell.drive.setTypeSchema('woot', testDataSchema_v0, vers=1))
|
|
222
|
+
info = {'name': 'win32k.sys', 'type': 'woot'}
|
|
223
|
+
info = await cell.addDriveItem(info, reldir=rootdir)
|
|
214
224
|
|
|
215
|
-
|
|
216
|
-
await cell.drive.setTypeSchema('woot', testDataSchema_v0, vers=0)
|
|
225
|
+
iden = info[-1].get('iden')
|
|
217
226
|
|
|
218
|
-
|
|
219
|
-
|
|
227
|
+
tick = s_common.now()
|
|
228
|
+
rootuser = cell.auth.rootuser.iden
|
|
220
229
|
|
|
221
|
-
|
|
230
|
+
with self.raises(s_exc.SchemaViolation):
|
|
231
|
+
versinfo = {'version': (1, 0, 0), 'updated': tick, 'updater': rootuser}
|
|
232
|
+
await cell.setDriveData(iden, versinfo, {'newp': 'newp'})
|
|
222
233
|
|
|
223
|
-
|
|
224
|
-
|
|
234
|
+
versinfo = {'version': (1, 1, 0), 'updated': tick + 10, 'updater': rootuser}
|
|
235
|
+
info, versinfo = await cell.setDriveData(iden, versinfo, {'type': 'haha', 'size': 20, 'stuff': 12})
|
|
236
|
+
self.eq(info.get('version'), (1, 1, 0))
|
|
237
|
+
self.eq(versinfo.get('version'), (1, 1, 0))
|
|
225
238
|
|
|
226
|
-
with self.raises(s_exc.SchemaViolation):
|
|
227
239
|
versinfo = {'version': (1, 0, 0), 'updated': tick, 'updater': rootuser}
|
|
228
|
-
await cell.setDriveData(iden, versinfo, {'
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
self.none(info.get('updater'))
|
|
271
|
-
|
|
272
|
-
# repopulate a couple data versions to test migration and delete
|
|
273
|
-
versinfo = {'version': (1, 0, 0), 'updated': tick, 'updater': rootuser}
|
|
274
|
-
info, versinfo = await cell.setDriveData(iden, versinfo, {'type': 'hehe', 'size': 0})
|
|
275
|
-
versinfo = {'version': (1, 1, 0), 'updated': tick + 10, 'updater': rootuser}
|
|
276
|
-
info, versinfo = await cell.setDriveData(iden, versinfo, {'type': 'haha', 'size': 17})
|
|
277
|
-
self.eq(versinfo, (await cell.getDriveData(iden))[0])
|
|
278
|
-
|
|
279
|
-
# This will be done by the cell in a cell storage version migration...
|
|
280
|
-
async def migrate_v1(info, versinfo, data):
|
|
281
|
-
data['woot'] = 'woot'
|
|
282
|
-
return data
|
|
283
|
-
|
|
284
|
-
await cell.drive.setTypeSchema('woot', testDataSchema_v1, migrate_v1)
|
|
285
|
-
|
|
286
|
-
versinfo, data = await cell.getDriveData(iden, vers=(1, 0, 0))
|
|
287
|
-
self.eq('woot', data.get('woot'))
|
|
288
|
-
|
|
289
|
-
versinfo, data = await cell.getDriveData(iden, vers=(1, 1, 0))
|
|
290
|
-
self.eq('woot', data.get('woot'))
|
|
240
|
+
info, versinfo = await cell.setDriveData(iden, versinfo, {'type': 'hehe', 'size': 0, 'stuff': 13})
|
|
241
|
+
self.eq(info.get('version'), (1, 1, 0))
|
|
242
|
+
self.eq(versinfo.get('version'), (1, 0, 0))
|
|
243
|
+
|
|
244
|
+
versinfo10, data10 = await cell.getDriveData(iden, vers=(1, 0, 0))
|
|
245
|
+
self.eq(versinfo10.get('updated'), tick)
|
|
246
|
+
self.eq(versinfo10.get('updater'), rootuser)
|
|
247
|
+
self.eq(versinfo10.get('version'), (1, 0, 0))
|
|
248
|
+
|
|
249
|
+
versinfo11, data11 = await cell.getDriveData(iden, vers=(1, 1, 0))
|
|
250
|
+
self.eq(versinfo11.get('updated'), tick + 10)
|
|
251
|
+
self.eq(versinfo11.get('updater'), rootuser)
|
|
252
|
+
self.eq(versinfo11.get('version'), (1, 1, 0))
|
|
253
|
+
|
|
254
|
+
versions = [vers async for vers in cell.getDriveDataVersions(iden)]
|
|
255
|
+
self.len(2, versions)
|
|
256
|
+
self.eq(versions[0], versinfo11)
|
|
257
|
+
self.eq(versions[1], versinfo10)
|
|
258
|
+
|
|
259
|
+
info = await cell.delDriveData(iden, vers=(0, 0, 0))
|
|
260
|
+
|
|
261
|
+
versions = [vers async for vers in cell.getDriveDataVersions(iden)]
|
|
262
|
+
self.len(2, versions)
|
|
263
|
+
self.eq(versions[0], versinfo11)
|
|
264
|
+
self.eq(versions[1], versinfo10)
|
|
265
|
+
|
|
266
|
+
info = await cell.delDriveData(iden, vers=(1, 1, 0))
|
|
267
|
+
self.eq(info.get('updated'), tick)
|
|
268
|
+
self.eq(info.get('version'), (1, 0, 0))
|
|
269
|
+
|
|
270
|
+
info = await cell.delDriveData(iden, vers=(1, 0, 0))
|
|
271
|
+
self.eq(info.get('size'), 0)
|
|
272
|
+
self.eq(info.get('version'), (0, 0, 0))
|
|
273
|
+
self.none(info.get('updated'))
|
|
274
|
+
self.none(info.get('updater'))
|
|
275
|
+
|
|
276
|
+
# repopulate a couple data versions to test migration and delete
|
|
277
|
+
versinfo = {'version': (1, 0, 0), 'updated': tick, 'updater': rootuser}
|
|
278
|
+
info, versinfo = await cell.setDriveData(iden, versinfo, {'type': 'hehe', 'size': 0, 'stuff': 14})
|
|
279
|
+
versinfo = {'version': (1, 1, 0), 'updated': tick + 10, 'updater': rootuser}
|
|
280
|
+
info, versinfo = await cell.setDriveData(iden, versinfo, {'type': 'haha', 'size': 17, 'stuff': 15})
|
|
281
|
+
self.eq(versinfo, (await cell.getDriveData(iden))[0])
|
|
291
282
|
|
|
292
|
-
|
|
293
|
-
|
|
283
|
+
# This will be done by the cell in a cell storage version migration...
|
|
284
|
+
async def migrate_v1(info, versinfo, data):
|
|
285
|
+
data['woot'] = 'woot'
|
|
286
|
+
return data
|
|
294
287
|
|
|
295
|
-
|
|
296
|
-
await cell.getDriveInfo(iden, typename='newp')
|
|
288
|
+
await cell.drive.setTypeSchema('woot', testDataSchema_v1, migrate_v1)
|
|
297
289
|
|
|
298
|
-
|
|
299
|
-
|
|
290
|
+
versinfo, data = await cell.getDriveData(iden, vers=(1, 0, 0))
|
|
291
|
+
self.eq('woot', data.get('woot'))
|
|
300
292
|
|
|
301
|
-
|
|
302
|
-
|
|
293
|
+
versinfo, data = await cell.getDriveData(iden, vers=(1, 1, 0))
|
|
294
|
+
self.eq('woot', data.get('woot'))
|
|
303
295
|
|
|
304
|
-
|
|
296
|
+
with self.raises(s_exc.NoSuchIden):
|
|
297
|
+
await cell.reqDriveInfo('d7d6107b200e2c039540fc627bc5537d')
|
|
305
298
|
|
|
306
|
-
|
|
307
|
-
|
|
299
|
+
with self.raises(s_exc.TypeMismatch):
|
|
300
|
+
await cell.getDriveInfo(iden, typename='newp')
|
|
308
301
|
|
|
309
|
-
|
|
310
|
-
|
|
302
|
+
self.nn(await cell.getDriveInfo(iden))
|
|
303
|
+
self.len(2, [vers async for vers in cell.getDriveDataVersions(iden)])
|
|
311
304
|
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
self.eq('foo', pathinfo[0].get('name'))
|
|
315
|
-
self.eq(1, pathinfo[0].get('kids'))
|
|
316
|
-
self.eq('bar', pathinfo[1].get('name'))
|
|
317
|
-
self.eq(1, pathinfo[1].get('kids'))
|
|
318
|
-
self.eq('baz', pathinfo[2].get('name'))
|
|
319
|
-
self.eq(0, pathinfo[2].get('kids'))
|
|
305
|
+
await cell.delDriveData(iden)
|
|
306
|
+
self.len(1, [vers async for vers in cell.getDriveDataVersions(iden)])
|
|
320
307
|
|
|
321
|
-
|
|
308
|
+
await cell.delDriveInfo(iden)
|
|
322
309
|
|
|
323
|
-
|
|
324
|
-
|
|
310
|
+
self.none(await cell.getDriveInfo(iden))
|
|
311
|
+
self.len(0, [vers async for vers in cell.getDriveDataVersions(iden)])
|
|
325
312
|
|
|
326
|
-
|
|
327
|
-
|
|
313
|
+
with self.raises(s_exc.NoSuchPath):
|
|
314
|
+
await cell.getDrivePath('users/root/win32k.sys')
|
|
328
315
|
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
316
|
+
pathinfo = await cell.addDrivePath('foo/bar/baz')
|
|
317
|
+
self.len(3, pathinfo)
|
|
318
|
+
self.eq('foo', pathinfo[0].get('name'))
|
|
319
|
+
self.eq(1, pathinfo[0].get('kids'))
|
|
320
|
+
self.eq('bar', pathinfo[1].get('name'))
|
|
321
|
+
self.eq(1, pathinfo[1].get('kids'))
|
|
322
|
+
self.eq('baz', pathinfo[2].get('name'))
|
|
323
|
+
self.eq(0, pathinfo[2].get('kids'))
|
|
324
|
+
|
|
325
|
+
self.eq(pathinfo, await cell.addDrivePath('foo/bar/baz'))
|
|
326
|
+
|
|
327
|
+
baziden = pathinfo[2].get('iden')
|
|
328
|
+
self.eq(pathinfo, await cell.drive.getItemPath(baziden))
|
|
329
|
+
|
|
330
|
+
info = await cell.setDriveInfoPerm(baziden, {'users': {rootuser: 3}, 'roles': {}})
|
|
331
|
+
self.eq(3, info['perm']['users'][rootuser])
|
|
332
|
+
|
|
333
|
+
with self.raises(s_exc.NoSuchIden):
|
|
334
|
+
# s_drive.rootdir is all 00s... ;)
|
|
335
|
+
await cell.setDriveInfoPerm(s_drive.rootdir, {'users': {}, 'roles': {}})
|
|
336
|
+
|
|
337
|
+
await cell.addDrivePath('hehe/haha')
|
|
338
|
+
pathinfo = await cell.setDriveInfoPath(baziden, 'hehe/haha/hoho')
|
|
332
339
|
|
|
333
|
-
|
|
334
|
-
|
|
340
|
+
self.eq('hoho', pathinfo[-1].get('name'))
|
|
341
|
+
self.eq(baziden, pathinfo[-1].get('iden'))
|
|
335
342
|
|
|
336
|
-
|
|
337
|
-
|
|
343
|
+
self.true(await cell.drive.hasPathInfo('hehe/haha/hoho'))
|
|
344
|
+
self.false(await cell.drive.hasPathInfo('foo/bar/baz'))
|
|
338
345
|
|
|
339
|
-
|
|
340
|
-
|
|
346
|
+
pathinfo = await cell.getDrivePath('foo/bar')
|
|
347
|
+
self.eq(0, pathinfo[-1].get('kids'))
|
|
341
348
|
|
|
342
|
-
|
|
343
|
-
|
|
349
|
+
pathinfo = await cell.getDrivePath('hehe/haha')
|
|
350
|
+
self.eq(1, pathinfo[-1].get('kids'))
|
|
344
351
|
|
|
345
|
-
|
|
346
|
-
|
|
352
|
+
with self.raises(s_exc.DupName):
|
|
353
|
+
iden = pathinfo[-2].get('iden')
|
|
354
|
+
name = pathinfo[-1].get('name')
|
|
355
|
+
cell.drive.reqFreeStep(iden, name)
|
|
347
356
|
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
357
|
+
walks = [item async for item in cell.drive.walkPathInfo('hehe')]
|
|
358
|
+
self.len(3, walks)
|
|
359
|
+
# confirm walked paths are yielded depth first...
|
|
360
|
+
self.eq('hoho', walks[0].get('name'))
|
|
361
|
+
self.eq('haha', walks[1].get('name'))
|
|
362
|
+
self.eq('hehe', walks[2].get('name'))
|
|
352
363
|
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
364
|
+
iden = walks[2].get('iden')
|
|
365
|
+
walks = [item async for item in cell.drive.walkItemInfo(iden)]
|
|
366
|
+
self.len(3, walks)
|
|
367
|
+
self.eq('hoho', walks[0].get('name'))
|
|
368
|
+
self.eq('haha', walks[1].get('name'))
|
|
369
|
+
self.eq('hehe', walks[2].get('name'))
|
|
359
370
|
|
|
360
|
-
|
|
361
|
-
walks = [item async for item in cell.drive.walkItemInfo(iden)]
|
|
362
|
-
self.len(3, walks)
|
|
363
|
-
self.eq('hoho', walks[0].get('name'))
|
|
364
|
-
self.eq('haha', walks[1].get('name'))
|
|
365
|
-
self.eq('hehe', walks[2].get('name'))
|
|
371
|
+
self.none(cell.drive.getTypeSchema('newp'))
|
|
366
372
|
|
|
367
|
-
|
|
373
|
+
cell.drive.validators.pop('woot')
|
|
374
|
+
self.nn(cell.drive.getTypeValidator('woot'))
|
|
368
375
|
|
|
369
|
-
|
|
370
|
-
|
|
376
|
+
# move to root dir
|
|
377
|
+
pathinfo = await cell.setDriveInfoPath(baziden, 'zipzop')
|
|
378
|
+
self.len(1, pathinfo)
|
|
379
|
+
self.eq(s_drive.rootdir, pathinfo[-1].get('parent'))
|
|
371
380
|
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
self.len(1, pathinfo)
|
|
375
|
-
self.eq(s_drive.rootdir, pathinfo[-1].get('parent'))
|
|
381
|
+
pathinfo = await cell.setDriveInfoPath(baziden, 'hehe/haha/hoho')
|
|
382
|
+
self.len(3, pathinfo)
|
|
376
383
|
|
|
377
|
-
|
|
378
|
-
|
|
384
|
+
async with self.getTestCell(dirn=dirn) as cell:
|
|
385
|
+
data = {'type': 'woot', 'size': 20, 'stuff': 12, 'woot': 'woot'}
|
|
386
|
+
# explicitly clear out the cache JsValidators, otherwise we get the cached, pre-msgpack
|
|
387
|
+
# version of the validator, which will be correct and skip the point of this test.
|
|
388
|
+
s_config._JsValidators.clear()
|
|
389
|
+
cell.drive.reqValidData('woot', data)
|
|
379
390
|
|
|
380
391
|
async def test_cell_auth(self):
|
|
381
392
|
|
|
@@ -2993,7 +3004,7 @@ class CellTest(s_t_utils.SynTest):
|
|
|
2993
3004
|
self.eq('barprof', valu)
|
|
2994
3005
|
|
|
2995
3006
|
msgs = await core.stormlist('cron.list')
|
|
2996
|
-
self.stormIsInPrint('visi
|
|
3007
|
+
self.stormIsInPrint(' visi 8437c35a.. ', msgs)
|
|
2997
3008
|
self.stormIsInPrint('[tel:mob:telem=*]', msgs)
|
|
2998
3009
|
|
|
2999
3010
|
msgs = await core.stormlist('dmon.list')
|
|
@@ -777,6 +777,12 @@ class HttpApiTest(s_tests.SynTest):
|
|
|
777
777
|
retn = await resp.json()
|
|
778
778
|
self.eq('MissingField', retn.get('code'))
|
|
779
779
|
|
|
780
|
+
body = {'prop': 'test:comp', 'value': '3^foobar', 'typeopts': {'sepr': '^'}}
|
|
781
|
+
async with sess.get(f'https://localhost:{port}/api/v1/model/norm', json=body) as resp:
|
|
782
|
+
retn = await resp.json()
|
|
783
|
+
self.eq('ok', retn.get('status'))
|
|
784
|
+
self.eq([3, 'foobar'], retn['result']['norm'])
|
|
785
|
+
|
|
780
786
|
# Norm via POST
|
|
781
787
|
body = {'prop': 'inet:ipv4', 'value': '1.2.3.4'}
|
|
782
788
|
async with sess.post(f'https://localhost:{port}/api/v1/model/norm', json=body) as resp:
|
synapse/tests/test_lib_nexus.py
CHANGED
|
@@ -310,6 +310,32 @@ class NexusTest(s_t_utils.SynTest):
|
|
|
310
310
|
await cell01.sync()
|
|
311
311
|
self.isin(s_nexus.leaderversion, cell01.nexsroot.writeholds)
|
|
312
312
|
|
|
313
|
+
cell00.getCellInfo = getCellInfo
|
|
314
|
+
|
|
315
|
+
# test case where a mirror which is updated first may push events
|
|
316
|
+
# the leader does not yet have handlers for
|
|
317
|
+
async with await s_cell.Cell.anit(dirn=path) as cell01:
|
|
318
|
+
cell01.nexsiden = 'newp'
|
|
319
|
+
with self.raises(s_exc.NoSuchIden) as cm:
|
|
320
|
+
await cell01.sync()
|
|
321
|
+
self.eq(cm.exception.get('mesg'), 'No Nexus Pusher with iden newp.')
|
|
322
|
+
|
|
323
|
+
self.none(await cell00.nexsroot.nexslog.last())
|
|
324
|
+
self.none(await cell01.nexsroot.nexslog.last())
|
|
325
|
+
|
|
326
|
+
cell01.nexsiden = cell00.nexsiden
|
|
327
|
+
await cell01.sync()
|
|
328
|
+
|
|
329
|
+
self.eq(0, (await cell00.nexsroot.nexslog.last())[0])
|
|
330
|
+
self.eq(0, (await cell01.nexsroot.nexslog.last())[0])
|
|
331
|
+
|
|
332
|
+
with self.raises(s_exc.NoSuchName) as cm:
|
|
333
|
+
await cell01._push('newp')
|
|
334
|
+
self.eq(cm.exception.get('mesg'), 'No Nexus handler for event newp.')
|
|
335
|
+
|
|
336
|
+
self.eq(0, (await cell00.nexsroot.nexslog.last())[0])
|
|
337
|
+
self.eq(0, (await cell01.nexsroot.nexslog.last())[0])
|
|
338
|
+
|
|
313
339
|
async def test_mirror_nexus_loop_failure(self):
|
|
314
340
|
with self.getTestDir() as dirn:
|
|
315
341
|
|
synapse/tests/test_lib_scrape.py
CHANGED
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
from unittest import mock
|
|
2
2
|
|
|
3
|
+
import regex
|
|
4
|
+
|
|
3
5
|
import synapse.exc as s_exc
|
|
4
6
|
|
|
5
7
|
import synapse.lib.scrape as s_scrape
|
|
@@ -889,14 +891,20 @@ class ScrapeTest(s_t_utils.SynTest):
|
|
|
889
891
|
nodes.remove(('inet:url', 'smb://1:2:3:4:5:6:7:8/share'))
|
|
890
892
|
|
|
891
893
|
async def test_scrape_async(self):
|
|
894
|
+
text = 'log4j vuln CVE-2021-44228 is pervasive'
|
|
895
|
+
ndefs = await s_t_utils.alist(s_scrape.scrapeAsync(text))
|
|
896
|
+
self.eq(ndefs, (('it:sec:cve', 'CVE-2021-44228'),))
|
|
892
897
|
|
|
893
|
-
|
|
894
|
-
|
|
895
|
-
|
|
898
|
+
regx = regex.compile('(?P<valu>CVE-[0-9]{4}-[0-9]{4,})(?:[^a-z0-9]|$)')
|
|
899
|
+
infos = s_scrape._genMatchList(text, regx, {})
|
|
900
|
+
self.eq(infos, [{'match': 'CVE-2021-44228', 'offset': 11, 'valu': 'CVE-2021-44228'}])
|
|
896
901
|
|
|
897
|
-
|
|
898
|
-
|
|
899
|
-
|
|
902
|
+
text = 'endashs are a vulnerability CVE\u20132022\u20131138 '
|
|
903
|
+
infos = await s_t_utils.alist(s_scrape.contextScrapeAsync(text))
|
|
904
|
+
self.eq(infos, [{'match': 'CVE–2022–1138', 'offset': 29, 'valu': 'CVE-2022-1138', 'form': 'it:sec:cve'}])
|
|
905
|
+
|
|
906
|
+
infos = s_scrape._contextScrapeList(text)
|
|
907
|
+
self.eq(infos, [{'match': 'CVE–2022–1138', 'offset': 29, 'valu': 'CVE-2022-1138', 'form': 'it:sec:cve'}])
|
|
900
908
|
|
|
901
909
|
def test_scrape_sequential(self):
|
|
902
910
|
md5 = ('a' * 32, 'b' * 32,)
|
synapse/tests/test_lib_storm.py
CHANGED
|
@@ -638,6 +638,8 @@ class StormTest(s_t_utils.SynTest):
|
|
|
638
638
|
with self.raises(s_exc.NoSuchVar):
|
|
639
639
|
await core.nodes('background { $lib.print($foo) }')
|
|
640
640
|
|
|
641
|
+
await core.nodes('background ${ $foo=test $lib.print($foo) }')
|
|
642
|
+
|
|
641
643
|
await core.nodes('background { $lib.time.sleep(4) }')
|
|
642
644
|
task = await core.callStorm('for $t in $lib.ps.list() { if $t.info.background { return($t) } }')
|
|
643
645
|
self.nn(task)
|
|
@@ -667,6 +669,9 @@ class StormTest(s_t_utils.SynTest):
|
|
|
667
669
|
q = '[ inet:fqdn=www.vertex.link ] $q=:domain | parallel $q'
|
|
668
670
|
await self.asyncraises(s_exc.StormRuntimeError, core.nodes(q))
|
|
669
671
|
|
|
672
|
+
nodes = await core.nodes('ou:org | parallel ${ $foo=bar [ :name=$foo ]}')
|
|
673
|
+
self.true(all([n.get('name') == 'bar' for n in nodes]))
|
|
674
|
+
|
|
670
675
|
# test $lib.exit() and the StormExit handlers
|
|
671
676
|
msgs = [m async for m in core.view.storm('$lib.exit()')]
|
|
672
677
|
self.eq(msgs[-1][0], 'fini')
|
|
@@ -2137,6 +2142,49 @@ class StormTest(s_t_utils.SynTest):
|
|
|
2137
2142
|
self.nn(bot.get('country::flag::md5'))
|
|
2138
2143
|
self.eq(bot['country::flag::md5'][0], 'fa818a259cbed7ce8bc2a22d35a464fc')
|
|
2139
2144
|
|
|
2145
|
+
await core.nodes('''
|
|
2146
|
+
[( risk:vulnerable=*
|
|
2147
|
+
:mitigated=true
|
|
2148
|
+
:node={ [ it:prod:hardware=* :name=foohw ] return($node.ndef()) }
|
|
2149
|
+
:vuln={[ risk:vuln=* :name=barvuln ]}
|
|
2150
|
+
+#test
|
|
2151
|
+
)]
|
|
2152
|
+
[( inet:service:rule=*
|
|
2153
|
+
:object={ risk:vulnerable#test return($node.ndef()) }
|
|
2154
|
+
:grantee={ [ inet:service:account=* :id=foocon ] return($node.ndef()) }
|
|
2155
|
+
+#test
|
|
2156
|
+
)]
|
|
2157
|
+
''')
|
|
2158
|
+
|
|
2159
|
+
opts = {
|
|
2160
|
+
'embeds': {
|
|
2161
|
+
'risk:vulnerable': {
|
|
2162
|
+
'vuln': ['name'],
|
|
2163
|
+
'node': ['name'],
|
|
2164
|
+
},
|
|
2165
|
+
'inet:service:rule': {
|
|
2166
|
+
'object': ['mitigated', 'newp'],
|
|
2167
|
+
'object::node': ['name', 'newp'],
|
|
2168
|
+
'grantee': ['id', 'newp'],
|
|
2169
|
+
}
|
|
2170
|
+
}
|
|
2171
|
+
}
|
|
2172
|
+
msgs = await core.stormlist('inet:service:rule#test :object -+> risk:vulnerable', opts=opts)
|
|
2173
|
+
nodes = sorted([m[1] for m in msgs if m[0] == 'node'], key=lambda p: p[0][0])
|
|
2174
|
+
self.eq(['inet:service:rule', 'risk:vulnerable'], [n[0][0] for n in nodes])
|
|
2175
|
+
|
|
2176
|
+
embeds = nodes[0][1]['embeds']
|
|
2177
|
+
self.eq(1, embeds['object']['mitigated'])
|
|
2178
|
+
self.eq(None, embeds['object']['newp'])
|
|
2179
|
+
self.eq('foohw', embeds['object::node']['name'])
|
|
2180
|
+
self.eq(None, embeds['object::node']['newp'])
|
|
2181
|
+
self.eq('foocon', embeds['grantee']['id'])
|
|
2182
|
+
self.eq(None, embeds['grantee']['newp'])
|
|
2183
|
+
|
|
2184
|
+
embeds = nodes[1][1]['embeds']
|
|
2185
|
+
self.eq('barvuln', embeds['vuln']['name'])
|
|
2186
|
+
self.eq('foohw', embeds['node']['name'])
|
|
2187
|
+
|
|
2140
2188
|
async def test_storm_wget(self):
|
|
2141
2189
|
|
|
2142
2190
|
async def _getRespFromSha(core, mesgs):
|