synapse 2.197.0__py311-none-any.whl → 2.198.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 (44) hide show
  1. synapse/axon.py +3 -0
  2. synapse/common.py +3 -0
  3. synapse/cortex.py +1 -3
  4. synapse/lib/aha.py +3 -0
  5. synapse/lib/ast.py +277 -165
  6. synapse/lib/auth.py +39 -11
  7. synapse/lib/cell.py +22 -4
  8. synapse/lib/hive.py +2 -1
  9. synapse/lib/hiveauth.py +10 -1
  10. synapse/lib/jsonstor.py +6 -5
  11. synapse/lib/layer.py +6 -5
  12. synapse/lib/node.py +10 -4
  13. synapse/lib/parser.py +46 -21
  14. synapse/lib/schemas.py +13 -0
  15. synapse/lib/snap.py +68 -26
  16. synapse/lib/storm.lark +13 -11
  17. synapse/lib/storm.py +1 -1
  18. synapse/lib/storm_format.py +3 -2
  19. synapse/lib/stormtypes.py +13 -4
  20. synapse/lib/version.py +2 -2
  21. synapse/models/infotech.py +18 -0
  22. synapse/models/risk.py +9 -0
  23. synapse/models/syn.py +18 -2
  24. synapse/tests/files/stormpkg/badendpoints.yaml +7 -0
  25. synapse/tests/files/stormpkg/testpkg.yaml +8 -0
  26. synapse/tests/test_cortex.py +108 -0
  27. synapse/tests/test_lib_aha.py +12 -2
  28. synapse/tests/test_lib_ast.py +57 -0
  29. synapse/tests/test_lib_auth.py +143 -2
  30. synapse/tests/test_lib_grammar.py +54 -2
  31. synapse/tests/test_lib_lmdbslab.py +24 -0
  32. synapse/tests/test_lib_storm.py +20 -0
  33. synapse/tests/test_lib_stormlib_macro.py +3 -3
  34. synapse/tests/test_lib_stormtypes.py +14 -2
  35. synapse/tests/test_model_infotech.py +13 -0
  36. synapse/tests/test_model_risk.py +6 -0
  37. synapse/tests/test_model_syn.py +58 -0
  38. synapse/tests/test_tools_genpkg.py +10 -0
  39. synapse/tools/hive/load.py +1 -0
  40. {synapse-2.197.0.dist-info → synapse-2.198.0.dist-info}/METADATA +1 -1
  41. {synapse-2.197.0.dist-info → synapse-2.198.0.dist-info}/RECORD +44 -43
  42. {synapse-2.197.0.dist-info → synapse-2.198.0.dist-info}/LICENSE +0 -0
  43. {synapse-2.197.0.dist-info → synapse-2.198.0.dist-info}/WHEEL +0 -0
  44. {synapse-2.197.0.dist-info → synapse-2.198.0.dist-info}/top_level.txt +0 -0
@@ -735,6 +735,17 @@ Queries = [
735
735
  '[test:str=foo :$foo*$bar.baz=heval]',
736
736
  '[test:str=foo :$foo*$bar.("baz")=heval]',
737
737
  '[test:str=foo :$foo*$bar.baz()=heval]',
738
+ '[test:str=foo +(refs)> $n]',
739
+ '[test:str=foo +(refs)> $n.baz()]',
740
+ '[test:str=foo -(refs)> $n]',
741
+ '[test:str=foo <(refs)+ $n]',
742
+ '[test:str=foo <(refs)+ $n.baz()]',
743
+ '[test:str=foo <(refs)- $n]',
744
+ '[test:str=foo :bar++=([1, 2])]',
745
+ '[test:str=foo :$foo++=([1, 2])]',
746
+ '[test:str=foo :bar--=(foo, bar)]',
747
+ '[test:str=foo :bar?++=$baz]',
748
+ '[test:str=foo :bar?--={[it:dev:str=foo]}]',
738
749
  ]
739
750
 
740
751
  # Generated with print_parse_list below
@@ -778,7 +789,7 @@ _ParseResults = [
778
789
  'Query: [TryCatch: [Query: [LiftPropBy: [Const: inet:ipv4, Const: =, Const: asdf]], CatchBlock: [Const: TypeError, Const: err, Query: []]]]',
779
790
  'Query: [TryCatch: [Query: [LiftPropBy: [Const: inet:ipv4, Const: =, Const: asdf]], CatchBlock: [Const: FooBar, Const: err, Query: []], CatchBlock: [Const: *, Const: err, Query: []]]]',
780
791
  'Query: [LiftByArray: [Const: test:array, Const: =, Const: 1.2.3.4]]',
781
- 'Query: [CmdOper: [Const: macro.set, List: [Const: hehe, EmbedQuery: inet:ipv4]]]',
792
+ 'Query: [CmdOper: [Const: macro.set, List: [Const: hehe, EmbedQuery: inet:ipv4 ]]]',
782
793
  'Query: [SetVarOper: [Const: q, EmbedQuery: #foo.bar]]',
783
794
  'Query: [CmdOper: [Const: metrics.edits.byprop, List: [Const: inet:fqdn:domain, Const: --newv, VarDeref: [VarValue: [Const: lib], Const: null]]]]',
784
795
  'Query: [CmdOper: [Const: tee, Const: ()]]',
@@ -1364,7 +1375,7 @@ _ParseResults = [
1364
1375
  'Query: [SetVarOper: [Const: p, Const: names], LiftPropBy: [Const: ps:contact:name, Const: =, Const: foo], EditPropSet: [RelProp: [VarValue: [Const: p]], Const: ?-=, Const: bar]]',
1365
1376
  'Query: [SetVarOper: [Const: pvar, Const: stuff], LiftProp: [Const: test:arrayprop], FiltOper: [Const: +, ArrayCond: [RelProp: [VarValue: [Const: pvar]], Const: =, Const: neato]]]',
1366
1377
  'Query: [SetVarOper: [Const: pvar, Const: ints], LiftProp: [Const: test:arrayprop], FiltOper: [Const: +, ArrayCond: [RelProp: [VarValue: [Const: pvar]], Const: =, VarValue: [Const: othervar]]]]',
1367
- 'Query: [SetVarOper: [Const: foo, DollarExpr: [ExprDict: [Const: foo, EmbedQuery: inet:fqdn]]]]',
1378
+ 'Query: [SetVarOper: [Const: foo, DollarExpr: [ExprDict: [Const: foo, EmbedQuery: inet:fqdn ]]]]',
1368
1379
  'Query: [EditNodeAdd: [FormName: [Const: test:str], Const: =, Const: foo], EditCondPropSet: [RelProp: [Const: hehe], CondSetOper: [Const: unset], Const: heval]]',
1369
1380
  'Query: [EditNodeAdd: [FormName: [Const: test:str], Const: =, Const: foo], EditCondPropSet: [RelProp: [Const: hehe], CondSetOper: [VarValue: [Const: foo]], Const: heval]]',
1370
1381
  'Query: [EditNodeAdd: [FormName: [Const: test:str], Const: =, Const: foo], EditCondPropSet: [RelProp: [VarValue: [Const: foo]], CondSetOper: [Const: unset], Const: heval]]',
@@ -1372,6 +1383,17 @@ _ParseResults = [
1372
1383
  'Query: [EditNodeAdd: [FormName: [Const: test:str], Const: =, Const: foo], EditCondPropSet: [RelProp: [VarValue: [Const: foo]], CondSetOper: [VarDeref: [VarValue: [Const: bar], Const: baz]], Const: heval]]',
1373
1384
  'Query: [EditNodeAdd: [FormName: [Const: test:str], Const: =, Const: foo], EditCondPropSet: [RelProp: [VarValue: [Const: foo]], CondSetOper: [VarDeref: [VarValue: [Const: bar], DollarExpr: [Const: baz]]], Const: heval]]',
1374
1385
  'Query: [EditNodeAdd: [FormName: [Const: test:str], Const: =, Const: foo], EditCondPropSet: [RelProp: [VarValue: [Const: foo]], CondSetOper: [FuncCall: [VarDeref: [VarValue: [Const: bar], Const: baz], CallArgs: [], CallKwargs: []]], Const: heval]]',
1386
+ 'Query: [EditNodeAdd: [FormName: [Const: test:str], Const: =, Const: foo], EditEdgeAdd: [Const: refs, VarValue: [Const: n]]]',
1387
+ 'Query: [EditNodeAdd: [FormName: [Const: test:str], Const: =, Const: foo], EditEdgeAdd: [Const: refs, FuncCall: [VarDeref: [VarValue: [Const: n], Const: baz], CallArgs: [], CallKwargs: []]]]',
1388
+ 'Query: [EditNodeAdd: [FormName: [Const: test:str], Const: =, Const: foo], EditEdgeDel: [Const: refs, VarValue: [Const: n]]]',
1389
+ 'Query: [EditNodeAdd: [FormName: [Const: test:str], Const: =, Const: foo], EditEdgeAdd: [Const: refs, VarValue: [Const: n]]]',
1390
+ 'Query: [EditNodeAdd: [FormName: [Const: test:str], Const: =, Const: foo], EditEdgeAdd: [Const: refs, FuncCall: [VarDeref: [VarValue: [Const: n], Const: baz], CallArgs: [], CallKwargs: []]]]',
1391
+ 'Query: [EditNodeAdd: [FormName: [Const: test:str], Const: =, Const: foo], EditEdgeDel: [Const: refs, VarValue: [Const: n]]]',
1392
+ 'Query: [EditNodeAdd: [FormName: [Const: test:str], Const: =, Const: foo], EditPropSetMulti: [RelProp: [Const: bar], Const: ++=, DollarExpr: [ExprList: [Const: 1, Const: 2]]]]',
1393
+ 'Query: [EditNodeAdd: [FormName: [Const: test:str], Const: =, Const: foo], EditPropSetMulti: [RelProp: [VarValue: [Const: foo]], Const: ++=, DollarExpr: [ExprList: [Const: 1, Const: 2]]]]',
1394
+ 'Query: [EditNodeAdd: [FormName: [Const: test:str], Const: =, Const: foo], EditPropSetMulti: [RelProp: [Const: bar], Const: --=, List: [Const: foo, Const: bar]]]',
1395
+ 'Query: [EditNodeAdd: [FormName: [Const: test:str], Const: =, Const: foo], EditPropSetMulti: [RelProp: [Const: bar], Const: ?++=, VarValue: [Const: baz]]]',
1396
+ 'Query: [EditNodeAdd: [FormName: [Const: test:str], Const: =, Const: foo], EditPropSetMulti: [RelProp: [Const: bar], Const: ?--=, SubQuery: [Query: [EditNodeAdd: [FormName: [Const: it:dev:str], Const: =, Const: foo]]]]]',
1375
1397
  ]
1376
1398
 
1377
1399
  class GrammarTest(s_t_utils.SynTest):
@@ -1663,6 +1685,27 @@ class GrammarTest(s_t_utils.SynTest):
1663
1685
  errinfo = cm.exception.errinfo
1664
1686
  self.eq(1, errinfo.get('mesg').count('#'))
1665
1687
 
1688
+ query = '$q = ${ /* secret comment */ $lib.print([hello) } $lib.macro.set(hehe, $q)'
1689
+ parser = s_parser.Parser(query)
1690
+ with self.raises(s_exc.BadSyntax) as cm:
1691
+ _ = parser.query()
1692
+ info = cm.exception.errinfo.get('highlight')
1693
+ self.eq((40, 41), info['offsets'])
1694
+ self.eq((1, 1), info['lines'])
1695
+ self.eq((41, 42), info['columns'])
1696
+
1697
+ query = """function test(hello) {
1698
+ +'''asdf
1699
+ asdfasdf'''
1700
+ }"""
1701
+ parser = s_parser.Parser(query)
1702
+ with self.raises(s_exc.BadSyntax) as cm:
1703
+ _ = parser.query()
1704
+ info = cm.exception.errinfo.get('highlight')
1705
+ self.eq((44, 83), info['offsets'])
1706
+ self.eq((2, 3), info['lines'])
1707
+ self.eq((22, 31), info['columns'])
1708
+
1666
1709
  async def test_quotes(self):
1667
1710
 
1668
1711
  # Test vectors
@@ -1766,6 +1809,15 @@ class GrammarTest(s_t_utils.SynTest):
1766
1809
  self.false(s_grammar.isPropName('.hehe'))
1767
1810
  self.false(s_grammar.isPropName('testcmd'))
1768
1811
 
1812
+ async def test_embed_offsets(self):
1813
+
1814
+ embq = ' /* secret comment */ $lib.print(hello) /* haha */ $lib.print(goodbye) /*foo */ '
1815
+ query = f'$q = ${{{embq}}} $lib.print($q)'
1816
+ parser = s_parser.Parser(query)
1817
+ q = parser.query()
1818
+ embed = q.kids[0].kids[1]
1819
+ self.eq(embq, embed.getAstText())
1820
+
1769
1821
  def gen_parse_list():
1770
1822
  '''
1771
1823
  Prints out the Asts for a list of queries in order to compare ASTs between versions of parsers
@@ -371,6 +371,30 @@ class LmdbSlabTest(s_t_utils.SynTest):
371
371
  'vm.dirty_ratio',
372
372
  ], msgs[0].get('sysctls', {}).keys())
373
373
 
374
+ async def test_lmdbslab_commit_over_max_xactops(self):
375
+
376
+ # Make sure that we don't confuse the periodic commit with the max replay log commit
377
+ with (self.getTestDir() as dirn,
378
+ patch('synapse.lib.lmdbslab.Slab.WARN_COMMIT_TIME_MS', 1),
379
+ patch('synapse.lib.lmdbslab.Slab.COMMIT_PERIOD', 100)
380
+ ):
381
+ path = os.path.join(dirn, 'test.lmdb')
382
+
383
+ async with await s_lmdbslab.Slab.anit(path, max_replay_log=100, map_size=100_000_000) as slab:
384
+ foo = slab.initdb('foo', dupsort=True)
385
+
386
+ byts = b'\x00' * 256
387
+ for i in range(1000):
388
+ slab.put(b'\xff\xff\xff\xff' + s_common.guid(i).encode('utf8'), byts, db=foo)
389
+ await asyncio.sleep(0)
390
+
391
+ # Let the slab close and then grab its stats
392
+ stats = slab.statinfo()
393
+ commitstats = stats.get('commitstats', ())
394
+ self.gt(len(commitstats), 0)
395
+ commitstats = [x[1] for x in commitstats if x[1] != 0]
396
+ self.eq(commitstats, (100, 100, 100, 100, 100, 100, 100, 100, 100, 100))
397
+
374
398
  async def test_lmdbslab_max_replay(self):
375
399
  with self.getTestDir() as dirn:
376
400
  path = os.path.join(dirn, 'test.lmdb')
@@ -143,6 +143,26 @@ class StormTest(s_t_utils.SynTest):
143
143
  self.eq(props.get('name'), 'org name 77')
144
144
  self.eq(props.get('desc'), 'an org desc')
145
145
 
146
+ nodes = await core.nodes('ou:org=({"name": "the vertex project", "type": "lulz"})')
147
+ self.len(1, nodes)
148
+ orgn = nodes[0].ndef
149
+ self.eq(orgn, nodes11[0].ndef)
150
+
151
+ q = '[ ps:contact=* :org={ ou:org=({"name": "the vertex project", "type": "lulz"}) } ]'
152
+ nodes = await core.nodes(q)
153
+ self.len(1, nodes)
154
+ cont = nodes[0]
155
+ self.eq(cont.get('org'), orgn[1])
156
+
157
+ nodes = await core.nodes('ps:contact:org=({"name": "the vertex project", "type": "lulz"})')
158
+ self.len(1, nodes)
159
+ self.eq(nodes[0].ndef, cont.ndef)
160
+
161
+ self.len(0, await core.nodes('ps:contact:org=({"name": "vertex", "type": "newp"})'))
162
+
163
+ with self.raises(s_exc.BadTypeValu):
164
+ await core.nodes('inet:flow:from=({"name": "vertex", "type": "newp"})')
165
+
146
166
  async def test_lib_storm_jsonexpr(self):
147
167
  async with self.getTestCore() as core:
148
168
 
@@ -89,7 +89,7 @@ class MacroTest(s_test.SynTest):
89
89
  name = 'v' * 491
90
90
  q = '$lib.macro.set($name, ${ help }) return ( $lib.macro.get($name) )'
91
91
  mdef = await core.callStorm(q, opts={'vars': {'name': name}})
92
- self.eq(mdef.get('storm'), 'help')
92
+ self.eq(mdef.get('storm'), ' help ')
93
93
 
94
94
  badname = 'v' * 492
95
95
  with self.raises(s_exc.BadArg):
@@ -381,7 +381,7 @@ class MacroTest(s_test.SynTest):
381
381
  self.eq('storm:macro:add', addmesg['data']['event'])
382
382
  macro = addmesg['data']['info']['macro']
383
383
  self.eq(macro['name'], 'foobar')
384
- self.eq(macro['storm'], 'file:bytes | [+#neato]')
384
+ self.eq(macro['storm'], ' file:bytes | [+#neato] ')
385
385
  self.ne(visi.iden, macro['user'])
386
386
  self.ne(visi.iden, macro['creator'])
387
387
  self.nn(macro['iden'])
@@ -390,7 +390,7 @@ class MacroTest(s_test.SynTest):
390
390
  self.eq('storm:macro:mod', setmesg['data']['event'])
391
391
  event = setmesg['data']['info']
392
392
  self.nn(event['macro'])
393
- self.eq(event['info']['storm'], 'inet:ipv4 | [+#burrito]')
393
+ self.eq(event['info']['storm'], ' inet:ipv4 | [+#burrito] ')
394
394
  self.nn(event['info']['updated'])
395
395
 
396
396
  modmesg = await sock.receive_json()
@@ -749,7 +749,7 @@ class StormTypesTest(s_test.SynTest):
749
749
  self.stormIsInPrint("['1', 2, '3']", mesgs)
750
750
 
751
751
  mesgs = await core.stormlist('$lib.print(${ $foo=bar })')
752
- self.stormIsInPrint('storm:query: "$foo=bar"', mesgs)
752
+ self.stormIsInPrint('storm:query: " $foo=bar "', mesgs)
753
753
 
754
754
  mesgs = await core.stormlist('$lib.print($lib.set(1,2,3))')
755
755
  self.stormIsInPrint("'1'", mesgs)
@@ -1168,7 +1168,7 @@ class StormTypesTest(s_test.SynTest):
1168
1168
  fires = [m for m in msgs if m[0] == 'storm:fire']
1169
1169
  self.len(1, fires)
1170
1170
  self.eq(fires[0][1].get('data').get('q'),
1171
- "$lib.print('fire in the hole')")
1171
+ " $lib.print('fire in the hole') ")
1172
1172
 
1173
1173
  q = '''
1174
1174
  $q=${ [test:int=1 test:int=2] }
@@ -1409,6 +1409,18 @@ class StormTypesTest(s_test.SynTest):
1409
1409
  with self.raises(s_exc.BadJsonText):
1410
1410
  await core.callStorm('return(("foo").json())')
1411
1411
 
1412
+ with self.raises(s_exc.BadArg):
1413
+ await core.nodes("$lib.regex.search('?id=([0-9]+)', 'foo')")
1414
+
1415
+ with self.raises(s_exc.BadArg):
1416
+ await core.nodes("$lib.regex.search('(?au)\\w', 'foo')")
1417
+
1418
+ with self.raises(s_exc.BadArg):
1419
+ await core.nodes("$lib.regex.replace('(?P<a>x)', '\\g<ab>', 'xx')")
1420
+
1421
+ with self.raises(s_exc.BadArg):
1422
+ await core.nodes("$lib.regex.replace('(?P<a>x)', '(?au)\\w', 'xx')")
1423
+
1412
1424
  async def test_storm_lib_bytes_gzip(self):
1413
1425
  async with self.getTestCore() as core:
1414
1426
  hstr = 'ohhai'
@@ -767,6 +767,9 @@ class InfotechModelTest(s_t_utils.SynTest):
767
767
 
768
768
  :host={it:host | limit 1}
769
769
  :sandbox:file=*
770
+ :service:platform=*
771
+ :service:instance=*
772
+ :service:account=*
770
773
  ]''')
771
774
  self.len(1, nodes)
772
775
  self.eq(10, nodes[0].get('severity'))
@@ -775,6 +778,9 @@ class InfotechModelTest(s_t_utils.SynTest):
775
778
  # check that the host activity model was inherited
776
779
  self.nn(nodes[0].get('host'))
777
780
  self.len(1, await core.nodes('it:log:event :sandbox:file -> file:bytes'))
781
+ self.len(1, await core.nodes('it:log:event :service:account -> inet:service:account'))
782
+ self.len(1, await core.nodes('it:log:event :service:platform -> inet:service:platform'))
783
+ self.len(1, await core.nodes('it:log:event :service:instance -> inet:service:instance'))
778
784
 
779
785
  nodes = await core.nodes('it:host | limit 1 | [ :keyboard:layout=qwerty :keyboard:language=$lib.gen.langByCode(en.us) ]')
780
786
  self.len(1, nodes)
@@ -2034,6 +2040,9 @@ class InfotechModelTest(s_t_utils.SynTest):
2034
2040
  :offset=99
2035
2041
  :synuser=$root
2036
2042
  // we can assume the rest of the interface props work
2043
+ :service:platform = *
2044
+ :service:instance = *
2045
+ :service:account = *
2037
2046
  ]
2038
2047
  ''', opts=opts)
2039
2048
  self.eq(1658275200000, nodes[0].get('time'))
@@ -2044,6 +2053,10 @@ class InfotechModelTest(s_t_utils.SynTest):
2044
2053
  self.eq(core.auth.rootuser.iden, nodes[0].get('synuser'))
2045
2054
  self.len(1, await core.nodes('it:exec:query -> it:query +it:query="SELECT * FROM threats"'))
2046
2055
 
2056
+ self.len(1, await core.nodes('it:exec:query :service:account -> inet:service:account'))
2057
+ self.len(1, await core.nodes('it:exec:query :service:platform -> inet:service:platform'))
2058
+ self.len(1, await core.nodes('it:exec:query :service:instance -> inet:service:instance'))
2059
+
2047
2060
  async def test_infotech_softid(self):
2048
2061
 
2049
2062
  async with self.getTestCore() as core:
@@ -299,6 +299,9 @@ class RiskModelTest(s_t_utils.SynTest):
299
299
  :host=*
300
300
  :priority=high
301
301
  :severity=highest
302
+ :service:platform=*
303
+ :service:instance=*
304
+ :service:account=*
302
305
  ]
303
306
  ''')
304
307
  self.len(1, nodes)
@@ -318,6 +321,9 @@ class RiskModelTest(s_t_utils.SynTest):
318
321
  self.len(1, await core.nodes('risk:alert -> risk:vuln'))
319
322
  self.len(1, await core.nodes('risk:alert -> risk:attack'))
320
323
  self.len(1, await core.nodes('risk:alert :engine -> it:prod:softver'))
324
+ self.len(1, await core.nodes('risk:alert :service:account -> inet:service:account'))
325
+ self.len(1, await core.nodes('risk:alert :service:platform -> inet:service:platform'))
326
+ self.len(1, await core.nodes('risk:alert :service:instance -> inet:service:instance'))
321
327
 
322
328
  nodes = await core.nodes('''[
323
329
  risk:compromise=*
@@ -63,6 +63,18 @@ class SynModelTest(s_t_utils.SynTest):
63
63
 
64
64
  self.eq('root', await core.callStorm(f'return($lib.repr(syn:user, {iden}))'))
65
65
 
66
+ with self.raises(s_exc.BadTypeValu) as exc:
67
+ await core.callStorm('return($lib.cast(syn:user, newp))')
68
+ self.eq(exc.exception.get('mesg'), 'No user named newp and value is not a guid.')
69
+ self.eq(exc.exception.get('valu'), 'newp')
70
+ self.eq(exc.exception.get('name'), 'syn:user')
71
+
72
+ with self.raises(s_exc.BadTypeValu) as exc:
73
+ await core.callStorm('[ it:exec:query=* :synuser=* ]')
74
+ self.isin('syn:user values must be a valid username or a guid.', exc.exception.get('mesg'))
75
+ self.eq(exc.exception.get('valu'), '*')
76
+ self.eq(exc.exception.get('name'), 'syn:user')
77
+
66
78
  (ok, iden) = await core.callStorm('return($lib.trycast(syn:role, all))')
67
79
  self.true(ok)
68
80
  self.eq(iden, core.auth.allrole.iden)
@@ -74,6 +86,18 @@ class SynModelTest(s_t_utils.SynTest):
74
86
 
75
87
  self.eq('all', await core.callStorm(f'return($lib.repr(syn:role, {iden}))'))
76
88
 
89
+ with self.raises(s_exc.BadTypeValu) as exc:
90
+ await core.callStorm('return($lib.cast(syn:role, newp))')
91
+ self.eq(exc.exception.get('mesg'), 'No role named newp and value is not a guid.')
92
+ self.eq(exc.exception.get('valu'), 'newp')
93
+ self.eq(exc.exception.get('name'), 'syn:role')
94
+
95
+ with self.raises(s_exc.BadTypeValu) as exc:
96
+ await core.callStorm('$lib.cast(syn:role, *)')
97
+ self.eq(exc.exception.get('mesg'), 'syn:role values must be a valid rolename or a guid.')
98
+ self.eq(exc.exception.get('valu'), '*')
99
+ self.eq(exc.exception.get('name'), 'syn:role')
100
+
77
101
  # coverage for DataModel without a cortex reference
78
102
  iden = s_common.guid()
79
103
 
@@ -89,6 +113,40 @@ class SynModelTest(s_t_utils.SynTest):
89
113
  self.eq(iden, synuser.norm(iden)[0])
90
114
  self.eq(iden, synrole.norm(iden)[0])
91
115
 
116
+ async def test_synuser_merge_failure(self):
117
+ async with self.getTestCore() as core:
118
+
119
+ visi = await core.addUser('visi')
120
+ view = await core.callStorm('return($lib.view.get().fork().iden)')
121
+
122
+ q = '[proj:project=(p1,) :creator=visi ]'
123
+ msgs = await core.stormlist(q, opts={'view': view})
124
+ self.stormHasNoWarnErr(msgs)
125
+
126
+ q = 'proj:project=(p1,)'
127
+ msgs = await core.stormlist(q, opts={'view': view, 'repr': True})
128
+ self.stormHasNoWarnErr(msgs)
129
+
130
+ await core.delUser(visi.get('iden'))
131
+
132
+ q = 'proj:project=(p1,)'
133
+ msgs = await core.stormlist(q, opts={'view': view, 'repr': True})
134
+ self.stormHasNoWarnErr(msgs)
135
+
136
+ # this works
137
+ q = '$lib.view.get($view).merge()'
138
+ msgs = await core.stormlist(q, opts={'vars': {'view': view}})
139
+ self.stormHasNoWarnErr(msgs)
140
+
141
+ # this fails
142
+ q = 'proj:project | merge --apply'
143
+ msgs = await core.stormlist(q, opts={'view': view, 'repr': True})
144
+ self.stormHasNoWarnErr(msgs)
145
+
146
+ q = 'proj:project=(p1,)'
147
+ msgs = await core.stormlist(q, opts={'vars': {'view': view}})
148
+ self.stormHasNoWarnErr(msgs)
149
+
92
150
  async def test_syn_tag(self):
93
151
 
94
152
  async with self.getTestCore() as core:
@@ -73,6 +73,10 @@ class GenPkgTest(s_test.SynTest):
73
73
  ymlpath = s_common.genpath(dirname, 'files', 'stormpkg', 'badapidef.yaml')
74
74
  await s_genpkg.main((ymlpath,))
75
75
 
76
+ with self.raises(s_exc.SchemaViolation):
77
+ ymlpath = s_common.genpath(dirname, 'files', 'stormpkg', 'badendpoints.yaml')
78
+ await s_genpkg.main((ymlpath,))
79
+
76
80
  ymlpath = s_common.genpath(dirname, 'files', 'stormpkg', 'testpkg.yaml')
77
81
  async with self.getTestCore() as core:
78
82
 
@@ -111,6 +115,12 @@ class GenPkgTest(s_test.SynTest):
111
115
  self.eq(pdef['commands'][0]['name'], 'testpkgcmd')
112
116
  self.eq(pdef['commands'][0]['storm'], 'inet:ipv6\n')
113
117
 
118
+ self.eq(pdef['commands'][0]['endpoints'], [
119
+ {'path': '/v1/test/one'},
120
+ {'path': '/v1/test/two', 'host': 'vertex.link'},
121
+ {'path': '/v1/test/three', 'desc': 'endpoint three'},
122
+ ])
123
+
114
124
  self.eq(pdef['perms'][0]['perm'], ['power-ups', 'testpkg', 'user'])
115
125
  self.eq(pdef['perms'][0]['gate'], 'cortex')
116
126
  self.eq(pdef['perms'][0]['desc'], 'Controls user access to testpkg.')
@@ -47,6 +47,7 @@ async def main(argv, outp=s_output.stdout):
47
47
  try:
48
48
  s_version.reqVersion(hive._getSynVers(), reqver)
49
49
  if 'synapse.lib.hive.HiveApi' in classes:
50
+ s_common.deprecated('Connecting directly to a Hive via Telepath', curv='2.198.0', eolv='2.199.0')
50
51
  await hive.loadHiveTree(tree, path=path, trim=opts.trim)
51
52
  else:
52
53
  todo = s_common.todo('loadHiveTree', tree, path=path, trim=opts.trim)
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.2
2
2
  Name: synapse
3
- Version: 2.197.0
3
+ Version: 2.198.0
4
4
  Summary: Synapse Intelligence Analysis Framework
5
5
  Author-email: The Vertex Project LLC <root@vertex.link>
6
6
  License: Apache License 2.0