synapse 2.222.0__py311-none-any.whl → 2.224.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 (49) hide show
  1. synapse/common.py +2 -2
  2. synapse/cortex.py +159 -31
  3. synapse/cryotank.py +1 -1
  4. synapse/datamodel.py +1 -1
  5. synapse/lib/ast.py +5 -3
  6. synapse/lib/layer.py +6 -6
  7. synapse/lib/nexus.py +1 -1
  8. synapse/lib/schemas.py +2 -0
  9. synapse/lib/snap.py +15 -9
  10. synapse/lib/storm.py +35 -191
  11. synapse/lib/stormlib/auth.py +1 -1
  12. synapse/lib/stormlib/imap.py +12 -4
  13. synapse/lib/stormlib/mime.py +15 -5
  14. synapse/lib/stormlib/pkg.py +598 -0
  15. synapse/lib/stormlib/task.py +114 -0
  16. synapse/lib/stormtypes.py +43 -175
  17. synapse/lib/trigger.py +16 -14
  18. synapse/lib/version.py +2 -2
  19. synapse/lib/view.py +17 -14
  20. synapse/models/files.py +1 -1
  21. synapse/models/inet.py +25 -0
  22. synapse/models/proj.py +3 -0
  23. synapse/models/risk.py +6 -0
  24. synapse/models/syn.py +8 -0
  25. synapse/tests/test_common.py +4 -0
  26. synapse/tests/test_cortex.py +52 -1
  27. synapse/tests/test_lib_aha.py +68 -53
  28. synapse/tests/test_lib_ast.py +3 -0
  29. synapse/tests/test_lib_cell.py +12 -12
  30. synapse/tests/test_lib_storm.py +128 -248
  31. synapse/tests/test_lib_stormlib_imap.py +14 -0
  32. synapse/tests/test_lib_stormlib_mime.py +24 -0
  33. synapse/tests/test_lib_stormlib_pkg.py +456 -0
  34. synapse/tests/test_lib_stormlib_task.py +98 -0
  35. synapse/tests/test_lib_stormtypes.py +12 -100
  36. synapse/tests/test_lib_trigger.py +66 -3
  37. synapse/tests/test_lib_view.py +53 -0
  38. synapse/tests/test_model_files.py +11 -0
  39. synapse/tests/test_model_inet.py +23 -0
  40. synapse/tests/test_model_proj.py +3 -1
  41. synapse/tests/test_model_risk.py +10 -0
  42. synapse/tests/test_model_syn.py +54 -2
  43. synapse/tools/cryo/cat.py +2 -1
  44. synapse/tools/cryo/list.py +2 -0
  45. {synapse-2.222.0.dist-info → synapse-2.224.0.dist-info}/METADATA +1 -1
  46. {synapse-2.222.0.dist-info → synapse-2.224.0.dist-info}/RECORD +49 -45
  47. {synapse-2.222.0.dist-info → synapse-2.224.0.dist-info}/WHEEL +0 -0
  48. {synapse-2.222.0.dist-info → synapse-2.224.0.dist-info}/licenses/LICENSE +0 -0
  49. {synapse-2.222.0.dist-info → synapse-2.224.0.dist-info}/top_level.txt +0 -0
synapse/lib/storm.py CHANGED
@@ -439,196 +439,6 @@ stormcmds = (
439
439
  }
440
440
  ''',
441
441
  },
442
- {
443
- 'name': 'pkg.list',
444
- 'descr': 'List the storm packages loaded in the cortex.',
445
- 'cmdargs': (
446
- ('--verbose', {'default': False, 'action': 'store_true',
447
- 'help': 'Display build time for each package.'}),
448
- ),
449
- 'storm': '''
450
- init {
451
- $conf = ({
452
- "columns": [
453
- {"name": "name", "width": 40},
454
- {"name": "vers", "width": 10},
455
- ],
456
- "separators": {
457
- "row:outline": false,
458
- "column:outline": false,
459
- "header:row": "#",
460
- "data:row": "",
461
- "column": "",
462
- },
463
- })
464
- if $cmdopts.verbose {
465
- $conf.columns.append(({"name": "time", "width": 20}))
466
- }
467
- $printer = $lib.tabular.printer($conf)
468
- }
469
-
470
- $pkgs = $lib.pkg.list()
471
-
472
- if $($pkgs.size() > 0) {
473
- $lib.print('Loaded storm packages:')
474
- $lib.print($printer.header())
475
- for $pkg in $pkgs {
476
- $row = (
477
- $pkg.name, $pkg.version,
478
- )
479
- if $cmdopts.verbose {
480
- try {
481
- $row.append($lib.time.format($pkg.build.time, '%Y-%m-%d %H:%M:%S'))
482
- } catch StormRuntimeError as _ {
483
- $row.append('not available')
484
- }
485
- }
486
- $lib.print($printer.row($row))
487
- }
488
- } else {
489
- $lib.print('No storm packages installed.')
490
- }
491
- '''
492
- },
493
- {
494
- 'name': 'pkg.perms.list',
495
- 'descr': 'List any permissions declared by the package.',
496
- 'cmdargs': (
497
- ('name', {'help': 'The name (or name prefix) of the package.', 'type': 'str'}),
498
- ),
499
- 'storm': '''
500
- $pdef = $lib.null
501
- for $pkg in $lib.pkg.list() {
502
- if $pkg.name.startswith($cmdopts.name) {
503
- $pdef = $pkg
504
- break
505
- }
506
- }
507
-
508
- if (not $pdef) {
509
- $lib.warn(`Package ({$cmdopts.name}) not found!`)
510
- } else {
511
- if $pdef.perms {
512
- $lib.print(`Package ({$cmdopts.name}) defines the following permissions:`)
513
- for $permdef in $pdef.perms {
514
- $defv = $permdef.default
515
- if ( $defv = $lib.null ) {
516
- $defv = $lib.false
517
- }
518
- $text = `{('.').join($permdef.perm).ljust(32)} : {$permdef.desc} ( default: {$defv} )`
519
- $lib.print($text)
520
- }
521
- } else {
522
- $lib.print(`Package ({$cmdopts.name}) contains no permissions definitions.`)
523
- }
524
- }
525
- '''
526
- },
527
- {
528
- 'name': 'pkg.del',
529
- 'descr': 'Remove a storm package from the cortex.',
530
- 'cmdargs': (
531
- ('name', {'help': 'The name (or name prefix) of the package to remove.'}),
532
- ),
533
- 'storm': '''
534
-
535
- $pkgs = $lib.set()
536
-
537
- for $pkg in $lib.pkg.list() {
538
- if $pkg.name.startswith($cmdopts.name) {
539
- $pkgs.add($pkg.name)
540
- }
541
- }
542
-
543
- if $($pkgs.size() = 0) {
544
-
545
- $lib.print('No package names match "{name}". Aborting.', name=$cmdopts.name)
546
-
547
- } elif $($pkgs.size() = 1) {
548
-
549
- $name = $pkgs.list().index(0)
550
- $lib.print('Removing package: {name}', name=$name)
551
- $lib.pkg.del($name)
552
-
553
- } else {
554
-
555
- $lib.print('Multiple package names match "{name}". Aborting.', name=$cmdopts.name)
556
-
557
- }
558
- '''
559
- },
560
- {
561
- 'name': 'pkg.docs',
562
- 'descr': 'Display documentation included in a storm package.',
563
- 'cmdargs': (
564
- ('name', {'help': 'The name (or name prefix) of the package.'}),
565
- ),
566
- 'storm': '''
567
- $pdef = $lib.null
568
- for $pkg in $lib.pkg.list() {
569
- if $pkg.name.startswith($cmdopts.name) {
570
- $pdef = $pkg
571
- break
572
- }
573
- }
574
-
575
- if (not $pdef) {
576
- $lib.warn("Package ({name}) not found!", name=$cmdopts.name)
577
- } else {
578
- if $pdef.docs {
579
- for $doc in $pdef.docs {
580
- $lib.print($doc.content)
581
- }
582
- } else {
583
- $lib.print("Package ({name}) contains no documentation.", name=$cmdopts.name)
584
- }
585
- }
586
- '''
587
- },
588
- {
589
- 'name': 'pkg.load',
590
- 'descr': 'Load a storm package from an HTTP URL.',
591
- 'cmdargs': (
592
- ('url', {'help': 'The HTTP URL to load the package from.'}),
593
- ('--raw', {'default': False, 'action': 'store_true',
594
- 'help': 'Response JSON is a raw package definition without an envelope.'}),
595
- ('--verify', {'default': False, 'action': 'store_true',
596
- 'help': 'Enforce code signature verification on the storm package.'}),
597
- ('--ssl-noverify', {'default': False, 'action': 'store_true',
598
- 'help': 'Specify to disable SSL verification of the server.'}),
599
- ),
600
- 'storm': '''
601
- init {
602
- $ssl = $lib.true
603
- if $cmdopts.ssl_noverify { $ssl = $lib.false }
604
-
605
- $headers = ({'X-Synapse-Version': ('.').join($lib.version.synapse())})
606
-
607
- $resp = $lib.inet.http.get($cmdopts.url, ssl_verify=$ssl, headers=$headers)
608
-
609
- if ($resp.code != 200) {
610
- $lib.warn("pkg.load got HTTP code: {code} for URL: {url}", code=$resp.code, url=$cmdopts.url)
611
- $lib.exit()
612
- }
613
-
614
- $reply = $resp.json()
615
- if $cmdopts.raw {
616
- $pkg = $reply
617
- } else {
618
- if ($reply.status != "ok") {
619
- $lib.warn("pkg.load got JSON error: {code} for URL: {url}", code=$reply.code, url=$cmdopts.url)
620
- $lib.exit()
621
- }
622
-
623
- $pkg = $reply.result
624
- }
625
-
626
- $pkd = $lib.pkg.add($pkg, verify=$cmdopts.verify)
627
-
628
- $lib.print("Loaded Package: {name} @{version}", name=$pkg.name, version=$pkg.version)
629
- }
630
- ''',
631
- },
632
442
  {
633
443
  'name': 'version',
634
444
  'descr': 'Show version metadata relating to Synapse.',
@@ -1122,6 +932,7 @@ stormcmds = (
1122
932
  },
1123
933
  {
1124
934
  'name': 'ps.list',
935
+ 'deprecated': {'eolvers': 'v3.0.0', 'mesg': 'Use ``task.list`` instead.'},
1125
936
  'descr': 'List running tasks in the cortex.',
1126
937
  'cmdargs': (
1127
938
  ('--verbose', {'default': False, 'action': 'store_true', 'help': 'Enable verbose output.'}),
@@ -1148,6 +959,7 @@ stormcmds = (
1148
959
  },
1149
960
  {
1150
961
  'name': 'ps.kill',
962
+ 'deprecated': {'eolvers': 'v3.0.0', 'mesg': 'Use ``task.kill`` instead.'},
1151
963
  'descr': 'Kill a running task/query within the cortex.',
1152
964
  'cmdargs': (
1153
965
  ('iden', {'help': 'Any prefix that matches exactly one valid process iden is accepted.'}),
@@ -1301,6 +1113,16 @@ stormcmds = (
1301
1113
  },
1302
1114
  )
1303
1115
 
1116
+ def deprmesg(name, depritem):
1117
+ if (mesg := depritem.get('mesg')) is not None:
1118
+ return f'"{name}" is deprecated: {mesg}'
1119
+
1120
+ if (eolvers := depritem.get('eolvers')) is not None:
1121
+ return f'"{name}" is deprecated and will be removed in {eolvers}.'
1122
+
1123
+ eoldate = depritem.get('eoldate')
1124
+ return f'"{name}" is deprecated and will be removed on {eoldate}.'
1125
+
1304
1126
  @s_cache.memoize(size=1024)
1305
1127
  def queryhash(text):
1306
1128
  return s_common.queryhash(text)
@@ -2096,6 +1918,7 @@ class Parser:
2096
1918
  self.root = root
2097
1919
  self.exited = False
2098
1920
  self.mesgs = []
1921
+ self.deprs = {}
2099
1922
 
2100
1923
  self.optargs = {}
2101
1924
  self.posargs = []
@@ -2121,7 +1944,7 @@ class Parser:
2121
1944
 
2122
1945
  choices = opts.get('choices')
2123
1946
  if choices is not None and opts.get('action') in ('store_true', 'store_false'):
2124
- mesg = f'Argument choices are not supported when action is store_true or store_false'
1947
+ mesg = 'Argument choices are not supported when action is store_true or store_false'
2125
1948
  raise s_exc.BadArg(mesg=mesg, argtype=str(argtype))
2126
1949
 
2127
1950
  dest = self._get_dest(names)
@@ -2178,6 +2001,9 @@ class Parser:
2178
2001
 
2179
2002
  dest = argdef.get('dest')
2180
2003
 
2004
+ if (deprecated := argdef.get('deprecated')) is not None:
2005
+ self.deprs[item] = deprecated
2006
+
2181
2007
  oact = argdef.get('action', 'store')
2182
2008
  if oact == 'store_true':
2183
2009
  opts[dest] = True
@@ -2367,6 +2193,12 @@ class Parser:
2367
2193
 
2368
2194
  self._printf(f'Usage: {self.prog} [options] {posargs}')
2369
2195
 
2196
+ if self.cdef is not None and (deprecated := self.cdef.get('deprecated')) is not None:
2197
+ dmsg = deprmesg(self.prog, deprecated)
2198
+ self._printf('')
2199
+ self._printf(f'Deprecated: {dmsg}')
2200
+ self._printf('')
2201
+
2370
2202
  if self.cdef is not None and (endpoints := self.cdef.get('endpoints')):
2371
2203
  self._printf('')
2372
2204
  self._printf('Endpoints:')
@@ -2476,6 +2308,10 @@ class Parser:
2476
2308
  wrap_first = self._wrap_text(first, wrap_w)
2477
2309
  self._printf(f'{base:<{base_w-2}}: {wrap_first[0]}')
2478
2310
 
2311
+ if (deprecated := argdef.get('deprecated')) is not None:
2312
+ mesg = deprmesg(names[0], deprecated)
2313
+ self._printf(f'{"":<{base_w-2}} Deprecated: {mesg}')
2314
+
2479
2315
  for ln in wrap_first[1:]: self._printf(f'{"":<{base_w}}{ln}')
2480
2316
  for ln in helplst[1:]:
2481
2317
  lead_s = len(ln) - len(ln.lstrip())
@@ -2591,6 +2427,10 @@ class Cmd:
2591
2427
  except s_exc.BadSyntax: # pragma: no cover
2592
2428
  pass
2593
2429
 
2430
+ for item, depr in self.pars.deprs.items():
2431
+ mesg = deprmesg(item, depr)
2432
+ await self.runt.snap.warnonce(mesg)
2433
+
2594
2434
  for line in self.pars.mesgs:
2595
2435
  await self.runt.snap.printf(line)
2596
2436
 
@@ -2712,6 +2552,10 @@ class PureCmd(Cmd):
2712
2552
  }
2713
2553
  }
2714
2554
 
2555
+ if (deprecated := self.cdef.get('deprecated')) is not None:
2556
+ mesg = deprmesg(name, deprecated)
2557
+ await self.runt.warnonce(mesg)
2558
+
2715
2559
  if self.runtsafe:
2716
2560
  data = {'pathvars': {}}
2717
2561
  async def genx():
@@ -1810,7 +1810,7 @@ class LibUser(s_stormtypes.Lib):
1810
1810
  'returns': {'type': 'boolean',
1811
1811
  'desc': 'True if the user has the requested permission, false otherwise.', }}},
1812
1812
  {'name': 'vars', 'desc': "Get a dictionary representing the current user's persistent variables.",
1813
- 'type': 'auth:user:vars', },
1813
+ 'type': 'user:vars:dict', },
1814
1814
  {'name': 'profile', 'desc': "Get a dictionary representing the current user's profile information.",
1815
1815
  'type': 'auth:user:profile', },
1816
1816
  {'name': 'iden', 'desc': 'The user GUID for the current storm user.', 'type': 'str'},
@@ -526,14 +526,22 @@ class ImapLib(s_stormtypes.Lib):
526
526
 
527
527
  try:
528
528
  imap = await s_common.wait_for(coro, timeout)
529
- except asyncio.TimeoutError:
529
+ except TimeoutError:
530
530
  raise s_exc.TimeOut(mesg='Timed out waiting for IMAP server hello.') from None
531
531
 
532
532
  async def fini():
533
- async def _logout():
534
- await s_common.wait_for(imap.logout(), 5)
533
+ async def imapfini():
534
+ if imap.isfini:
535
+ return
536
+
537
+ try:
538
+ await s_common.wait_for(imap.logout(), 5)
539
+ except TimeoutError:
540
+ pass # pragma: no cover
541
+
535
542
  await imap.fini()
536
- s_coro.create_task(_logout())
543
+
544
+ self.runt.snap.core.schedCoro(imapfini())
537
545
 
538
546
  self.runt.snap.onfini(fini)
539
547
 
@@ -3,9 +3,9 @@ import bs4
3
3
  import synapse.lib.coro as s_coro
4
4
  import synapse.lib.stormtypes as s_stormtypes
5
5
 
6
- def htmlToText(html):
6
+ def htmlToText(html, separator='\n', strip=True):
7
7
  soup = bs4.BeautifulSoup(html, 'html5lib')
8
- return soup.get_text(separator='\n', strip=True)
8
+ return soup.get_text(separator=separator, strip=strip)
9
9
 
10
10
  @s_stormtypes.registry.registerLib
11
11
  class LibMimeHtml(s_stormtypes.Lib):
@@ -17,8 +17,12 @@ class LibMimeHtml(s_stormtypes.Lib):
17
17
  'type': {'type': 'function', '_funcname': 'totext',
18
18
  'args': (
19
19
  {'name': 'html', 'type': 'str', 'desc': 'The HTML text to be parsed.'},
20
+ {'name': 'separator', 'type': 'str', 'default': '\n',
21
+ 'desc': 'The string used to join text.'},
22
+ {'name': 'strip', 'type': 'boolean', 'default': True,
23
+ 'desc': 'Strip whitespace from the beginning and end of tag text.'},
20
24
  ),
21
- 'returns': {'type': 'str', 'desc': 'The newline-joined inner HTML text.', }
25
+ 'returns': {'type': 'str', 'desc': 'The separator-joined inner HTML text.', }
22
26
  }},
23
27
  )
24
28
 
@@ -30,6 +34,12 @@ class LibMimeHtml(s_stormtypes.Lib):
30
34
  }
31
35
 
32
36
  @s_stormtypes.stormfunc(readonly=True)
33
- async def totext(self, html):
37
+ async def totext(self, html, separator='\n', strip=True):
34
38
  html = await s_stormtypes.tostr(html)
35
- return await s_coro.semafork(htmlToText, html)
39
+ separator = await s_stormtypes.tostr(separator, noneok=True)
40
+ strip = await s_stormtypes.tobool(strip)
41
+
42
+ if separator is None:
43
+ separator = ''
44
+
45
+ return await s_coro.semafork(htmlToText, html, separator, strip)