synapse 2.201.0__py311-none-any.whl → 2.203.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.

Files changed (106) hide show
  1. synapse/axon.py +4 -4
  2. synapse/cmds/cortex.py +4 -6
  3. synapse/cmds/hive.py +10 -10
  4. synapse/common.py +17 -58
  5. synapse/cortex.py +36 -29
  6. synapse/data/__init__.py +3 -2
  7. synapse/data/iana.uris.mpk +1 -0
  8. synapse/lib/autodoc.py +3 -3
  9. synapse/lib/base.py +2 -12
  10. synapse/lib/cell.py +9 -13
  11. synapse/lib/cli.py +2 -2
  12. synapse/lib/config.py +2 -2
  13. synapse/lib/encoding.py +4 -3
  14. synapse/lib/httpapi.py +7 -11
  15. synapse/lib/json.py +224 -0
  16. synapse/lib/lmdbslab.py +1 -1
  17. synapse/lib/oauth.py +176 -54
  18. synapse/lib/parser.py +2 -1
  19. synapse/lib/rstorm.py +18 -14
  20. synapse/lib/schemas.py +87 -1
  21. synapse/lib/scrape.py +35 -13
  22. synapse/lib/snap.py +2 -1
  23. synapse/lib/storm.lark +5 -4
  24. synapse/lib/storm.py +2 -2
  25. synapse/lib/storm_format.py +2 -1
  26. synapse/lib/stormhttp.py +11 -13
  27. synapse/lib/stormlib/aha.py +4 -4
  28. synapse/lib/stormlib/auth.py +1 -1
  29. synapse/lib/stormlib/cache.py +2 -2
  30. synapse/lib/stormlib/cortex.py +5 -5
  31. synapse/lib/stormlib/graph.py +1 -1
  32. synapse/lib/stormlib/imap.py +1 -1
  33. synapse/lib/stormlib/json.py +8 -11
  34. synapse/lib/stormlib/model.py +1 -1
  35. synapse/lib/stormlib/notifications.py +2 -2
  36. synapse/lib/stormlib/oauth.py +105 -2
  37. synapse/lib/stormlib/stats.py +4 -0
  38. synapse/lib/stormlib/stix.py +3 -4
  39. synapse/lib/stormlib/vault.py +6 -6
  40. synapse/lib/stormlib/xml.py +2 -2
  41. synapse/lib/stormtypes.py +19 -28
  42. synapse/lib/structlog.py +3 -3
  43. synapse/lib/types.py +2 -1
  44. synapse/lib/version.py +2 -2
  45. synapse/lib/view.py +7 -3
  46. synapse/models/base.py +51 -2
  47. synapse/telepath.py +79 -18
  48. synapse/tests/files/__init__.py +0 -1
  49. synapse/tests/test_axon.py +1 -1
  50. synapse/tests/test_cmds_cortex.py +3 -2
  51. synapse/tests/test_cmds_hive.py +4 -4
  52. synapse/tests/test_common.py +29 -19
  53. synapse/tests/test_cortex.py +28 -8
  54. synapse/tests/test_lib_ast.py +3 -3
  55. synapse/tests/test_lib_autodoc.py +5 -5
  56. synapse/tests/test_lib_base.py +1 -1
  57. synapse/tests/test_lib_cell.py +24 -7
  58. synapse/tests/test_lib_config.py +2 -2
  59. synapse/tests/test_lib_encoding.py +2 -2
  60. synapse/tests/test_lib_grammar.py +68 -64
  61. synapse/tests/test_lib_httpapi.py +13 -13
  62. synapse/tests/test_lib_json.py +219 -0
  63. synapse/tests/test_lib_multislabseqn.py +2 -1
  64. synapse/tests/test_lib_node.py +2 -2
  65. synapse/tests/test_lib_scrape.py +50 -0
  66. synapse/tests/test_lib_storm.py +12 -6
  67. synapse/tests/test_lib_stormhttp.py +4 -4
  68. synapse/tests/test_lib_stormlib_auth.py +3 -2
  69. synapse/tests/test_lib_stormlib_cortex.py +10 -12
  70. synapse/tests/test_lib_stormlib_infosec.py +2 -3
  71. synapse/tests/test_lib_stormlib_json.py +18 -21
  72. synapse/tests/test_lib_stormlib_log.py +1 -1
  73. synapse/tests/test_lib_stormlib_oauth.py +603 -1
  74. synapse/tests/test_lib_stormlib_stats.py +13 -3
  75. synapse/tests/test_lib_stormlib_stix.py +5 -5
  76. synapse/tests/test_lib_stormtypes.py +4 -4
  77. synapse/tests/test_lib_structlog.py +5 -6
  78. synapse/tests/test_lib_view.py +8 -0
  79. synapse/tests/test_model_base.py +32 -0
  80. synapse/tests/test_model_infotech.py +2 -2
  81. synapse/tests/test_telepath.py +56 -35
  82. synapse/tests/test_tools_cryo_cat.py +4 -3
  83. synapse/tests/test_tools_docker_validate.py +4 -2
  84. synapse/tests/test_tools_feed.py +30 -2
  85. synapse/tests/test_tools_genpkg.py +1 -1
  86. synapse/tests/test_tools_healthcheck.py +8 -7
  87. synapse/tests/test_utils.py +2 -2
  88. synapse/tests/test_utils_getrefs.py +35 -28
  89. synapse/tests/utils.py +3 -3
  90. synapse/tools/autodoc.py +3 -3
  91. synapse/tools/changelog.py +2 -2
  92. synapse/tools/cryo/cat.py +3 -3
  93. synapse/tools/csvtool.py +2 -3
  94. synapse/tools/docker/validate.py +5 -5
  95. synapse/tools/feed.py +2 -1
  96. synapse/tools/genpkg.py +3 -2
  97. synapse/tools/healthcheck.py +2 -3
  98. synapse/tools/json2mpk.py +2 -2
  99. synapse/utils/getrefs.py +10 -8
  100. synapse/vendor/cpython/lib/json.py +35 -0
  101. synapse/vendor/cpython/lib/test/test_json.py +22 -0
  102. {synapse-2.201.0.dist-info → synapse-2.203.0.dist-info}/METADATA +2 -1
  103. {synapse-2.201.0.dist-info → synapse-2.203.0.dist-info}/RECORD +106 -101
  104. {synapse-2.201.0.dist-info → synapse-2.203.0.dist-info}/WHEEL +1 -1
  105. {synapse-2.201.0.dist-info → synapse-2.203.0.dist-info}/LICENSE +0 -0
  106. {synapse-2.201.0.dist-info → synapse-2.203.0.dist-info}/top_level.txt +0 -0
@@ -242,7 +242,7 @@ class StatsTest(s_test.SynTest):
242
242
  $tally.inc(foo, 1)
243
243
  $tally.inc(bar, 2)
244
244
  $tally.inc(baz, 3)
245
- return($tally.sorted(reverse=$lib.true))
245
+ return($tally.sorted(reverse=(true)))
246
246
  '''
247
247
  vals = await core.callStorm(q)
248
248
  self.eq(vals, [('baz', 3), ('bar', 2), ('foo', 1)])
@@ -252,7 +252,7 @@ class StatsTest(s_test.SynTest):
252
252
  $tally.inc(foo, 1)
253
253
  $tally.inc(bar, 2)
254
254
  $tally.inc(baz, 3)
255
- return($tally.sorted(byname=$lib.true))
255
+ return($tally.sorted(byname=(true)))
256
256
  '''
257
257
  vals = await core.callStorm(q)
258
258
  self.eq(vals, [('bar', 2), ('baz', 3), ('foo', 1)])
@@ -262,11 +262,21 @@ class StatsTest(s_test.SynTest):
262
262
  $tally.inc(foo, 1)
263
263
  $tally.inc(bar, 2)
264
264
  $tally.inc(baz, 3)
265
- return($tally.sorted(byname=$lib.true, reverse=$lib.true))
265
+ return($tally.sorted(byname=(true), reverse=(true)))
266
266
  '''
267
267
  vals = await core.callStorm(q)
268
268
  self.eq(vals, [('foo', 1), ('baz', 3), ('bar', 2)])
269
269
 
270
+ q = '''
271
+ $tally = $lib.stats.tally()
272
+ $tally.inc(foo, 1)
273
+ $tally.inc(bar, 1)
274
+ $tally.inc(foo, 1)
275
+ return($tally.sorted(reverse=true)) // String coercion to true
276
+ '''
277
+ vals = await core.callStorm(q)
278
+ self.eq(vals, [('foo', 2), ('bar', 1)])
279
+
270
280
  tally = s_stormlib_stats.StatTally()
271
281
  await tally.inc('foo')
272
282
 
@@ -1,9 +1,9 @@
1
1
  import copy
2
- import json
3
2
 
4
3
  import synapse.exc as s_exc
5
4
  import synapse.common as s_common
6
5
 
6
+ import synapse.lib.json as s_json
7
7
  import synapse.lib.stormlib.stix as s_stix
8
8
 
9
9
  import synapse.tests.utils as s_test
@@ -39,12 +39,12 @@ class StormLibStixTest(s_test.SynTest):
39
39
  def getTestBundle(self, name):
40
40
  path = self.getTestFilePath('stix_export', name)
41
41
  with open(path, 'r') as fd:
42
- return json.load(fd)
42
+ return s_json.load(fd)
43
43
 
44
44
  def setTestBundle(self, name, bund):
45
45
  path = self.getTestFilePath('stix_export', name)
46
46
  with open(path, 'w') as fd:
47
- json.dump(bund, fd, sort_keys=True, indent=2)
47
+ s_json.dump(bund, fd, sort_keys=True, indent=True)
48
48
 
49
49
  def reqValidStix(self, item):
50
50
  resp = s_stix.validateStix(item)
@@ -188,7 +188,7 @@ class StormLibStixTest(s_test.SynTest):
188
188
  self.isin('Error validating bundle', resp.get('mesg'))
189
189
 
190
190
  self.len(14, bund.get('objects'))
191
- self.isin(s_stix.SYN_STIX_EXTENSION_ID, json.dumps(bund))
191
+ self.isin(s_stix.SYN_STIX_EXTENSION_ID, s_json.dumps(bund).decode())
192
192
  nodes = await core.nodes('yield $lib.stix.lift($bundle)', {'vars': {'bundle': bund}})
193
193
  self.len(10, nodes)
194
194
 
@@ -217,7 +217,7 @@ class StormLibStixTest(s_test.SynTest):
217
217
  self.reqValidStix(bund_noext)
218
218
  nodes = await core.nodes('yield $lib.stix.lift($bundle)', {'vars': {'bundle': bund_noext}})
219
219
  self.len(0, nodes)
220
- self.notin(s_stix.SYN_STIX_EXTENSION_ID, json.dumps(bund_noext))
220
+ self.notin(s_stix.SYN_STIX_EXTENSION_ID, s_json.dumps(bund_noext).decode())
221
221
 
222
222
  # test some sad paths...
223
223
  self.none(await core.callStorm('return($lib.stix.export.bundle().add($lib.true))'))
@@ -1,7 +1,6 @@
1
1
  import re
2
2
  import bz2
3
3
  import gzip
4
- import json
5
4
  import base64
6
5
  import struct
7
6
  import asyncio
@@ -16,6 +15,7 @@ from unittest import mock
16
15
  import synapse.exc as s_exc
17
16
  import synapse.common as s_common
18
17
 
18
+ import synapse.lib.json as s_json
19
19
  import synapse.lib.time as s_time
20
20
  import synapse.lib.storm as s_storm
21
21
  import synapse.lib.hashset as s_hashset
@@ -585,7 +585,7 @@ class StormTypesTest(s_test.SynTest):
585
585
  self.eq(0x01020304, await core.callStorm('return($lib.trycast(inet:ipv4, 1.2.3.4).1)'))
586
586
 
587
587
  # trycast/cast a property instead of a form/type
588
- flow = json.loads(s_test_files.getAssetStr('attack_flow/CISA AA22-138B VMWare Workspace (Alt).json'))
588
+ flow = s_json.loads(s_test_files.getAssetStr('attack_flow/CISA AA22-138B VMWare Workspace (Alt).json'))
589
589
  opts = {'vars': {'flow': flow}}
590
590
  self.true(await core.callStorm('return($lib.trycast(it:mitre:attack:flow:data, $flow).0)', opts=opts))
591
591
  self.false(await core.callStorm('return($lib.trycast(it:mitre:attack:flow:data, {}).0)'))
@@ -1502,7 +1502,7 @@ class StormTypesTest(s_test.SynTest):
1502
1502
  async with self.getTestCore() as core:
1503
1503
 
1504
1504
  foo = {'a': 'ohhai'}
1505
- ghstr = json.dumps(foo)
1505
+ ghstr = s_json.dumps(foo).decode()
1506
1506
  valu = s_common.guid()
1507
1507
  n2 = s_common.guid()
1508
1508
 
@@ -6232,7 +6232,7 @@ words\tword\twrd'''
6232
6232
 
6233
6233
  self.eq({
6234
6234
  'file:count': 9,
6235
- 'size:bytes': 651,
6235
+ 'size:bytes': 646,
6236
6236
  }, await core.callStorm('return($lib.axon.metrics())'))
6237
6237
 
6238
6238
  bin_buf = b'\xbb/$\xc0A\xf1\xbf\xbc\x00_\x82v4\xf6\xbd\x1b'
@@ -1,9 +1,10 @@
1
1
  import io
2
- import json
3
2
  import time
4
3
  import logging
5
4
 
6
5
  import synapse.common as s_common
6
+
7
+ import synapse.lib.json as s_json
7
8
  import synapse.lib.structlog as s_structlog
8
9
 
9
10
  import synapse.tests.utils as s_test
@@ -46,7 +47,7 @@ class StructLogTest(s_test.SynTest):
46
47
 
47
48
  # There is a trailing \n on the stream
48
49
  raw_mesgs = [m for m in data.split('\n') if m]
49
- mesgs = [json.loads(m) for m in raw_mesgs]
50
+ mesgs = [s_json.loads(m) for m in raw_mesgs]
50
51
  self.len(5, mesgs)
51
52
 
52
53
  mesg = mesgs[0]
@@ -83,10 +84,8 @@ class StructLogTest(s_test.SynTest):
83
84
  self.eq(erfo.get('args'), (1, 0))
84
85
  self.eq(erfo.get('buffer'), "b'vertex'")
85
86
 
86
- mesg = mesgs[4]
87
87
  rawm = raw_mesgs[4]
88
- self.isin(r'Unicode is cool for \u7a0b\u5e8f\u5458!', rawm)
89
- self.eq(mesg.get('message'), 'Unicode is cool for 程序员!')
88
+ self.isin('"message":"Unicode is cool for 程序员!"', rawm)
90
89
 
91
90
  logger.removeHandler(handler)
92
91
 
@@ -105,7 +104,7 @@ class StructLogTest(s_test.SynTest):
105
104
 
106
105
  # There is a trailing \n on the stream
107
106
  raw_mesgs = [m for m in data.split('\n') if m]
108
- mesgs = [json.loads(m) for m in raw_mesgs]
107
+ mesgs = [s_json.loads(m) for m in raw_mesgs]
109
108
  self.len(1, mesgs)
110
109
  ptime = time.strptime(mesgs[0].get('time'), datefmt)
111
110
  self.eq(now.tm_year, ptime.tm_year)
@@ -906,6 +906,14 @@ class ViewTest(s_t_utils.SynTest):
906
906
  with self.raises(s_exc.BadState):
907
907
  await core.callStorm('return($lib.view.get().insertParentFork().iden)')
908
908
 
909
+ pname = view01.parent.info.get('name')
910
+ vdef = await view01.insertParentFork(visi.iden)
911
+ self.eq(vdef.get('name'), f'inserted fork of {pname}')
912
+
913
+ piden = view03.parent.iden
914
+ vdef = await view03.insertParentFork(visi.iden)
915
+ self.eq(vdef.get('name'), f'inserted fork of {piden}')
916
+
909
917
  async def test_view_children(self):
910
918
 
911
919
  async with self.getTestCore() as core:
@@ -413,3 +413,35 @@ class BaseTest(s_t_utils.SynTest):
413
413
  self.eq('bottles.', nodes[0].get('type'))
414
414
  self.eq(1706832000000, nodes[0].get('time'))
415
415
  self.len(1, await core.nodes('meta:aggregate -> meta:aggregate:type:taxonomy'))
416
+
417
+ async def test_model_feed(self):
418
+
419
+ async with self.getTestCore() as core:
420
+ nodes = await core.nodes('''[
421
+ meta:feed=*
422
+ :name="woot (foo bar baz)"
423
+ :type=foo.bar.baz
424
+ :source={[ meta:source=* :name=woot ]}
425
+ :url=https://v.vtx.lk/slack
426
+ :query="Hi There"
427
+ :opts=({"foo": "bar"})
428
+ :period=(2024,2025)
429
+ :latest=2025
430
+ :offset=17
431
+ :cursor=FooBar
432
+ ]''')
433
+ self.len(1, nodes)
434
+ self.nn(nodes[0].get('source'))
435
+
436
+ self.eq(nodes[0].get('name'), 'woot (foo bar baz)')
437
+ self.eq(nodes[0].get('type'), 'foo.bar.baz.')
438
+ self.eq(nodes[0].get('url'), 'https://v.vtx.lk/slack')
439
+ self.eq(nodes[0].get('query'), 'Hi There')
440
+ self.eq(nodes[0].get('opts'), {"foo": "bar"})
441
+ self.eq(nodes[0].get('period'), (1704067200000, 1735689600000))
442
+ self.eq(nodes[0].get('latest'), 1735689600000)
443
+ self.eq(nodes[0].get('offset'), 17)
444
+ self.eq(nodes[0].get('cursor'), 'FooBar')
445
+
446
+ self.len(1, await core.nodes('meta:feed -> meta:source +:name=woot'))
447
+ self.len(1, await core.nodes('meta:feed -> meta:feed:type:taxonomy'))
@@ -1,9 +1,9 @@
1
- import json
2
1
  import hashlib
3
2
 
4
3
  import synapse.exc as s_exc
5
4
  import synapse.common as s_common
6
5
 
6
+ import synapse.lib.json as s_json
7
7
  import synapse.lib.const as s_const
8
8
  import synapse.lib.scrape as s_scrape
9
9
 
@@ -1954,7 +1954,7 @@ class InfotechModelTest(s_t_utils.SynTest):
1954
1954
  # Test 2.2->2.3 and 2.3->2.2 conversions
1955
1955
  filename = s_t_files.getAssetPath('cpedata.json')
1956
1956
  with open(filename, 'r') as fp:
1957
- cpedata = json.load(fp)
1957
+ cpedata = s_json.load(fp)
1958
1958
 
1959
1959
  for (_cpe22, _cpe23) in cpedata:
1960
1960
  # Convert cpe22 -> cpe23
@@ -1,6 +1,5 @@
1
1
  import os
2
2
  import ssl
3
- import json
4
3
  import socket
5
4
  import asyncio
6
5
  import logging
@@ -318,6 +317,10 @@ class TeleTest(s_t_utils.SynTest):
318
317
  link.onfini(evt.set)
319
318
  s_glob.sync(proxy._putPoolLink(link))
320
319
 
320
+ # Grab the fresh link from the pool so our original link is up next again
321
+ link2 = s_glob.sync(proxy.getPoolLink())
322
+ s_glob.sync(proxy._putPoolLink(link2))
323
+
321
324
  q = f'{form} | sleep 0.1'
322
325
 
323
326
  # Break from the generator right away, causing a
@@ -935,7 +938,6 @@ class TeleTest(s_t_utils.SynTest):
935
938
 
936
939
  # Validate the Proxy behavior then the client override
937
940
  prox = await s_telepath.openurl(url) # type: Foo
938
- prox._link_poolsize = 2
939
941
 
940
942
  # Start with no links
941
943
  self.len(0, prox.links)
@@ -947,53 +949,72 @@ class TeleTest(s_t_utils.SynTest):
947
949
  genr = await prox.genr() # type: s_coro.GenrHelp
948
950
  self.eq(await genr.genr.__anext__(), 10)
949
951
 
950
- # The link is being used by the genr
951
- self.len(0, prox.links)
952
-
953
- # and upon exhuastion, that link is put back
954
- self.eq(await genr.list(), (20, 30))
952
+ # A new link is in the pool
955
953
  self.len(1, prox.links)
956
- self.true(prox.links[0] is l0)
957
954
 
958
- # Grab the existing link, then do two more calls
959
- genr0 = await prox.genr() # contains l0
960
- genr1 = await prox.genr()
961
- genr2 = await prox.genr()
962
- self.len(0, prox.links)
963
- # Consume two of the three generators
964
- self.eq(await genr2.list(), (10, 20, 30))
965
- self.len(1, prox.links)
966
- self.eq(await genr1.list(), (10, 20, 30))
955
+ # and upon exhuastion, the first link is put back
956
+ self.eq(await genr.list(), (20, 30))
967
957
  self.len(2, prox.links)
968
- # Exhausting the lsat generator results in his
969
- # link not being placed back into the pool
970
- self.eq(await genr0.list(), (10, 20, 30))
958
+ self.true(prox.links[1] is l0)
959
+
960
+ # Grabbing a link will still spin up another since we are below low watermark
961
+ genr = await prox.genr() # type: s_coro.GenrHelp
962
+ self.eq(await genr.genr.__anext__(), 10)
963
+
971
964
  self.len(2, prox.links)
972
- links = set(lnk for lnk in prox.links)
973
- self.notin(l0, links)
974
- # And that link l0 has been fini'd
975
- self.true(l0.isfini)
965
+
966
+ self.eq(await genr.list(), (20, 30))
967
+ self.len(3, prox.links)
968
+
969
+ # Fill up pool above low watermark
970
+ genrs = [await prox.genr() for _ in range(2)]
971
+ [await genr.list() for genr in genrs]
972
+ self.len(5, prox.links)
973
+
974
+ # Grabbing a link no longer spins up a replacement
975
+ genr = await prox.genr() # type: s_coro.GenrHelp
976
+ self.eq(await genr.genr.__anext__(), 10)
977
+ self.len(4, prox.links)
978
+
979
+ self.eq(await genr.list(), (20, 30))
980
+ self.len(5, prox.links)
976
981
 
977
982
  # Tear down a link by hand and place it back
978
983
  # into the pool - that will fail b/c the link
979
984
  # has been down down.
980
985
  l1 = await prox.getPoolLink()
981
- self.len(1, prox.links)
986
+ self.len(4, prox.links)
982
987
  await l1.fini()
983
988
  await prox._putPoolLink(l1)
984
- self.len(1, prox.links)
989
+ self.len(4, prox.links)
985
990
 
986
991
  # And all our links are torn down on fini
987
992
  await prox.fini()
988
- self.len(1, prox.links)
989
- for link in prox.links:
990
- self.true(link.isfini)
993
+ self.len(4, prox.links)
994
+ for link in list(prox.links):
995
+ self.true(await link.waitfini(1))
996
+ self.len(0, prox.links)
997
+
998
+ with mock.patch('synapse.telepath.LINK_CULL_INTERVAL', 1):
999
+ async with self.getTestDmon() as dmon:
1000
+ dmon.share('foo', foo)
1001
+ url = f'tcp://127.0.0.1:{dmon.addr[1]}/foo'
1002
+
1003
+ prox = await s_telepath.openurl(url)
991
1004
 
992
- # The telepath Client passes through this value as a configuration parameter
993
- conf = {'link_poolsize': 2, 'timeout': 2}
994
- async with await s_telepath.Client.anit(url, conf=conf) as client:
995
- await client.waitready()
996
- self.true(client._t_proxy._link_poolsize, 2)
1005
+ # Fill up pool above high watermark
1006
+ genrs = [await prox.genr() for _ in range(13)]
1007
+ [await genr.list() for genr in genrs]
1008
+ self.len(13, prox.links)
1009
+
1010
+ # Add a fini'd proxy for coverage
1011
+ prox2 = await s_telepath.openurl(url)
1012
+ await prox2.fini()
1013
+ prox2._all_proxies.add(prox2)
1014
+
1015
+ wait = prox.waiter(1, 'pool:link:fini')
1016
+ self.len(1, await wait.wait(timeout=5))
1017
+ self.len(12, prox.links)
997
1018
 
998
1019
  async def test_link_fini_breaking_tasks(self):
999
1020
  foo = Foo()
@@ -1062,7 +1083,7 @@ class TeleTest(s_t_utils.SynTest):
1062
1083
 
1063
1084
  self.eq(vals, (40, 50, 60))
1064
1085
 
1065
- self.eq(1, len(proxy.links))
1086
+ self.eq(2, len(proxy.links))
1066
1087
  self.eq(160, await proxy.bar(80, 80))
1067
1088
 
1068
1089
  async def boomgenr():
@@ -1,10 +1,11 @@
1
1
  import io
2
- import json
3
2
 
4
3
  import msgpack
5
4
 
6
5
  import unittest.mock as mock
7
6
 
7
+ import synapse.exc as s_exc
8
+
8
9
  import synapse.lib.msgpack as s_msgpack
9
10
  import synapse.tests.utils as s_t_utils
10
11
  import synapse.tools.cryo.cat as s_cryocat
@@ -34,7 +35,7 @@ class CryoCatTest(s_t_utils.SynTest):
34
35
  argv = ['--ingest', '--jsonl', cryourl]
35
36
  inp = io.StringIO('{"foo: "bar"}\n[]\n')
36
37
  with self.redirectStdin(inp):
37
- with self.raises(json.decoder.JSONDecodeError):
38
+ with self.raises(s_exc.BadJsonText):
38
39
  retn, outp = await self.execToolMain(s_cryocat.main, argv)
39
40
 
40
41
  # Happy path msgpack ingest
@@ -74,7 +75,7 @@ class CryoCatTest(s_t_utils.SynTest):
74
75
 
75
76
  argv = ['--offset', '0', '--jsonl', '--size', '2', '--omit-offset', cryourl]
76
77
  retn, outp = await self.execToolMain(s_cryocat.main, argv)
77
- self.true(outp.expect('[null, {"key": 0}]\n[null, {"key": 1}]\n'))
78
+ self.true(outp.expect('[null,{"key":0}]\n[null,{"key":1}]\n'))
78
79
 
79
80
  argv = ['--offset', '0', '--size', '20', cryourl]
80
81
  retn, outp = await self.execToolMain(s_cryocat.main, argv)
@@ -1,10 +1,12 @@
1
1
  import base64
2
- import json
2
+
3
3
  import unittest.mock as mock
4
4
 
5
5
  import cryptography.hazmat.primitives.serialization as c_serialization
6
6
 
7
+ import synapse.lib.json as s_json
7
8
  import synapse.lib.certdir as s_certdir
9
+
8
10
  import synapse.tests.utils as s_t_utils
9
11
  import synapse.tools.docker.validate as s_t_d_validate
10
12
 
@@ -48,7 +50,7 @@ class TestDockerValidate(s_t_utils.SynTest):
48
50
  # getCosignSignature
49
51
  outp = self.getTestOutp()
50
52
  with mock.patch('subprocess.run') as patch:
51
- test_stdout = json.dumps(test_resp).encode()
53
+ test_stdout = s_json.dumps(test_resp)
52
54
  mock_stdout = mock.MagicMock(stdout=test_stdout)
53
55
  patch.return_value = mock_stdout
54
56
  ret = s_t_d_validate.getCosignSignature(outp, 'hehe/haha:tag')
@@ -1,4 +1,3 @@
1
- import json
2
1
  import hashlib
3
2
 
4
3
  from unittest import mock
@@ -6,6 +5,7 @@ from unittest import mock
6
5
  import synapse.exc as s_exc
7
6
  import synapse.common as s_common
8
7
 
8
+ import synapse.lib.json as s_json
9
9
  import synapse.lib.msgpack as s_msgpack
10
10
 
11
11
  import synapse.tools.feed as s_feed
@@ -33,7 +33,7 @@ class FeedTest(s_t_utils.SynTest):
33
33
  with s_common.genfile(jsonlfp) as fd:
34
34
  for i in range(20):
35
35
  pode = (('test:int', i), {})
36
- _ = fd.write(json.dumps(pode).encode() + b'\n')
36
+ _ = fd.write(s_json.dumps(pode, newline=True))
37
37
 
38
38
  argv = ['--cortex', curl,
39
39
  '--format', 'syn.nodes',
@@ -138,3 +138,31 @@ class FeedTest(s_t_utils.SynTest):
138
138
 
139
139
  nodes = await core.nodes('test:int', opts={'view': oldview})
140
140
  self.len(0, nodes)
141
+
142
+ async def test_synnodes_json(self):
143
+ async with self.getTestCore() as core:
144
+
145
+ await self.addCreatorDeleterRoles(core)
146
+
147
+ host, port = await core.dmon.listen('tcp://127.0.0.1:0/')
148
+
149
+ curl = f'tcp://icanadd:secret@{host}:{port}/'
150
+
151
+ with self.getTestDir() as dirn:
152
+
153
+ jsonfp = s_common.genpath(dirn, 'podes.json')
154
+ with s_common.genfile(jsonfp) as fd:
155
+ podes = [(('test:int', ii), {}) for ii in range(20)]
156
+ s_json.dump(podes, fd)
157
+
158
+ argv = ['--cortex', curl,
159
+ '--format', 'syn.nodes',
160
+ '--modules', 'synapse.tests.utils.TestModule',
161
+ '--chunksize', '3',
162
+ jsonfp]
163
+
164
+ outp = self.getTestOutp()
165
+ self.eq(await s_feed.main(argv, outp=outp), 0)
166
+
167
+ nodes = await core.nodes('test:int')
168
+ self.len(20, nodes)
@@ -65,7 +65,7 @@ class GenPkgTest(s_test.SynTest):
65
65
  ymlpath = s_common.genpath(dirname, 'files', 'stormpkg', 'badcmdname.yaml')
66
66
  await s_genpkg.main((ymlpath,))
67
67
 
68
- with self.raises(s_exc.BadArg):
68
+ with self.raises(s_exc.MustBeJsonSafe):
69
69
  ymlpath = s_common.genpath(dirname, 'files', 'stormpkg', 'badjsonpkg.yaml')
70
70
  await s_genpkg.main((ymlpath,))
71
71
 
@@ -1,9 +1,10 @@
1
- import json
2
1
  import asyncio
3
2
  import logging
4
3
 
5
4
  import unittest.mock as mock
6
5
 
6
+ import synapse.lib.json as s_json
7
+
7
8
  import synapse.tests.utils as s_t_utils
8
9
 
9
10
  import synapse.tools.healthcheck as s_t_healthcheck
@@ -25,7 +26,7 @@ class HealthcheckTest(s_t_utils.SynTest):
25
26
 
26
27
  retn = await s_t_healthcheck.main(argv, outp)
27
28
  self.eq(retn, 0)
28
- resp = json.loads(str(outp))
29
+ resp = s_json.loads(str(outp))
29
30
  self.isinstance(resp, dict)
30
31
 
31
32
  mod = core.modules.get('synapse.tests.utils.TestModule') # type: s_t_utils.TestModule
@@ -34,7 +35,7 @@ class HealthcheckTest(s_t_utils.SynTest):
34
35
  outp.clear()
35
36
  retn = await s_t_healthcheck.main(argv, outp)
36
37
  self.eq(retn, 1)
37
- resp = json.loads(str(outp))
38
+ resp = s_json.loads(str(outp))
38
39
  self.isinstance(resp, dict)
39
40
 
40
41
  # Sad paths
@@ -47,7 +48,7 @@ class HealthcheckTest(s_t_utils.SynTest):
47
48
  outp.clear()
48
49
  retn = await s_t_healthcheck.main(['-c', curl, '-t', '0.4'], outp)
49
50
  self.eq(retn, 1)
50
- resp = json.loads(str(outp))
51
+ resp = s_json.loads(str(outp))
51
52
  self.eq(resp.get('components')[0].get('name'), 'error')
52
53
  m = 'Timeout getting health information from cell.'
53
54
  self.eq(resp.get('components')[0].get('mesg'), m)
@@ -60,7 +61,7 @@ class HealthcheckTest(s_t_utils.SynTest):
60
61
  await root.setPasswd('secret')
61
62
  retn = await s_t_healthcheck.main(['-c', f'tcp://root:newp@127.0.0.1:{port}/cortex', '-t', '0.4'], outp)
62
63
  self.eq(retn, 1)
63
- resp = json.loads(str(outp))
64
+ resp = s_json.loads(str(outp))
64
65
  self.eq(resp.get('components')[0].get('name'), 'error')
65
66
  m = 'Synapse error encountered.'
66
67
  self.eq(resp.get('components')[0].get('mesg'), m)
@@ -72,7 +73,7 @@ class HealthcheckTest(s_t_utils.SynTest):
72
73
  outp.clear()
73
74
  retn = await s_t_healthcheck.main(['-c', f'tcp://visi:secret@127.0.0.1:{port}/cortex', '-t', '0.4'], outp)
74
75
  self.eq(retn, 1)
75
- resp = json.loads(str(outp))
76
+ resp = s_json.loads(str(outp))
76
77
  self.eq(resp.get('components')[0].get('name'), 'error')
77
78
  m = 'Synapse error encountered.'
78
79
  self.eq(resp.get('components')[0].get('mesg'), m)
@@ -85,7 +86,7 @@ class HealthcheckTest(s_t_utils.SynTest):
85
86
  outp.clear()
86
87
  retn = await s_t_healthcheck.main(['-c', curl, '-t', '0.4'], outp)
87
88
  self.eq(retn, 1)
88
- resp = json.loads(str(outp))
89
+ resp = s_json.loads(str(outp))
89
90
  self.eq(resp.get('components')[0].get('name'), 'error')
90
91
  m = 'Unable to connect to cell'
91
92
  self.isin(m, resp.get('components')[0].get('mesg'))
@@ -1,12 +1,12 @@
1
1
  import os
2
2
  import time
3
- import json
4
3
  import logging
5
4
  import unittest
6
5
 
7
6
  import synapse.common as s_common
8
7
 
9
8
  import synapse.lib.base as s_base
9
+ import synapse.lib.json as s_json
10
10
  import synapse.lib.output as s_output
11
11
  import synapse.lib.certdir as s_certdir
12
12
 
@@ -126,7 +126,7 @@ class TestUtils(s_t_utils.SynTest):
126
126
  self.notin('notthere', mesgs)
127
127
 
128
128
  with self.getLoggerStream('synapse.tests.test_utils', 'Test Message') as stream:
129
- thr = logathing(json.dumps({'mesg': 'Test Message'}))
129
+ thr = logathing(s_json.dumps({'mesg': 'Test Message'}).decode())
130
130
  self.true(stream.wait(10))
131
131
  thr.join()
132
132
 
@@ -1,10 +1,13 @@
1
- import os.path
1
+ import os
2
2
  import pathlib
3
3
 
4
4
  import vcr
5
5
 
6
+ from unittest import mock
7
+
6
8
  import synapse.exc as s_exc
7
9
  import synapse.data as s_data
10
+ import synapse.common as s_common
8
11
 
9
12
  import synapse.lib.config as s_config
10
13
 
@@ -45,30 +48,34 @@ class TestUtilsGetrefs(s_utils.SynTest):
45
48
  with self.raises(s_exc.BadArg):
46
49
  s_getrefs.download_refs_handler('http://raw.githubusercontent.com/../../attack-flow/attack-flow-schema-2.0.0.json')
47
50
 
48
- filename = pathlib.Path(s_data.path(
49
- 'jsonschemas',
50
- 'raw.githubusercontent.com',
51
- 'oasis-open',
52
- 'cti-stix2-json-schemas',
53
- 'stix2.1',
54
- 'schemas',
55
- 'common',
56
- 'core.json'
57
- ))
58
-
59
- self.true(filename.exists())
60
- filename.unlink()
61
-
62
- # Clear the cached validator funcs so the ref handlers in s_getrefs get called
63
- s_config._JsValidators = {}
64
-
65
- with self.getLoggerStream('synapse.utils.getrefs') as stream:
66
- with self.getVcr() as cass:
67
- s_getrefs.main(args)
68
-
69
- stream.seek(0)
70
- mesgs = stream.read()
71
- mesg = f'Downloading schema from {CORE_URL}.'
72
- self.true(filename.exists())
73
- self.isin(mesg, mesgs)
74
- self.notin(f'Schema {CORE_URL} already exists in local cache, skipping.', mesgs)
51
+ with self.getTestDir(copyfrom=s_getrefs.BASEDIR) as dirn:
52
+
53
+ filename = pathlib.Path(s_common.genpath(
54
+ dirn,
55
+ 'raw.githubusercontent.com',
56
+ 'oasis-open',
57
+ 'cti-stix2-json-schemas',
58
+ 'stix2.1',
59
+ 'schemas',
60
+ 'common',
61
+ 'core.json'
62
+ ))
63
+
64
+ self.true(filename.exists())
65
+ filename.unlink()
66
+ self.false(filename.exists())
67
+
68
+ # Clear the cached validator funcs so the ref handlers in s_getrefs get called
69
+ s_config._JsValidators = {}
70
+
71
+ with self.getLoggerStream('synapse.utils.getrefs') as stream:
72
+ with mock.patch('synapse.utils.getrefs.BASEDIR', dirn):
73
+ with self.getVcr():
74
+ s_getrefs.main(args)
75
+
76
+ stream.seek(0)
77
+ mesgs = stream.read()
78
+ mesg = f'Downloading schema from {CORE_URL}.'
79
+ self.true(filename.exists())
80
+ self.isin(mesg, mesgs)
81
+ self.notin(f'Schema {CORE_URL} already exists in local cache, skipping.', mesgs)