synapse 2.165.0__py311-none-any.whl → 2.166.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 (51) hide show
  1. synapse/cmds/cortex.py +1 -6
  2. synapse/common.py +6 -0
  3. synapse/cortex.py +73 -56
  4. synapse/datamodel.py +32 -0
  5. synapse/lib/agenda.py +81 -51
  6. synapse/lib/ast.py +21 -23
  7. synapse/lib/base.py +0 -6
  8. synapse/lib/cell.py +13 -22
  9. synapse/lib/httpapi.py +1 -0
  10. synapse/lib/nexus.py +3 -2
  11. synapse/lib/schemas.py +2 -0
  12. synapse/lib/snap.py +50 -0
  13. synapse/lib/storm.py +19 -17
  14. synapse/lib/stormlib/aha.py +4 -1
  15. synapse/lib/stormlib/auth.py +11 -4
  16. synapse/lib/stormlib/cache.py +202 -0
  17. synapse/lib/stormlib/cortex.py +69 -7
  18. synapse/lib/stormlib/spooled.py +109 -0
  19. synapse/lib/stormtypes.py +43 -15
  20. synapse/lib/trigger.py +10 -12
  21. synapse/lib/types.py +1 -1
  22. synapse/lib/version.py +2 -2
  23. synapse/lib/view.py +12 -0
  24. synapse/models/inet.py +74 -2
  25. synapse/models/orgs.py +52 -8
  26. synapse/models/person.py +30 -11
  27. synapse/models/risk.py +44 -3
  28. synapse/telepath.py +114 -32
  29. synapse/tests/test_cortex.py +40 -6
  30. synapse/tests/test_datamodel.py +22 -0
  31. synapse/tests/test_lib_agenda.py +8 -1
  32. synapse/tests/test_lib_aha.py +18 -4
  33. synapse/tests/test_lib_storm.py +95 -4
  34. synapse/tests/test_lib_stormlib_cache.py +272 -0
  35. synapse/tests/test_lib_stormlib_cortex.py +71 -0
  36. synapse/tests/test_lib_stormlib_spooled.py +190 -0
  37. synapse/tests/test_lib_stormtypes.py +27 -4
  38. synapse/tests/test_model_inet.py +67 -0
  39. synapse/tests/test_model_risk.py +6 -0
  40. synapse/tests/test_telepath.py +30 -7
  41. synapse/tests/test_tools_modrole.py +81 -0
  42. synapse/tests/test_tools_moduser.py +105 -0
  43. synapse/tools/modrole.py +59 -7
  44. synapse/tools/moduser.py +78 -10
  45. {synapse-2.165.0.dist-info → synapse-2.166.0.dist-info}/METADATA +2 -2
  46. {synapse-2.165.0.dist-info → synapse-2.166.0.dist-info}/RECORD +49 -47
  47. synapse/lib/provenance.py +0 -111
  48. synapse/tests/test_lib_provenance.py +0 -37
  49. {synapse-2.165.0.dist-info → synapse-2.166.0.dist-info}/LICENSE +0 -0
  50. {synapse-2.165.0.dist-info → synapse-2.166.0.dist-info}/WHEEL +0 -0
  51. {synapse-2.165.0.dist-info → synapse-2.166.0.dist-info}/top_level.txt +0 -0
@@ -0,0 +1,190 @@
1
+ import synapse.exc as s_exc
2
+ import synapse.lib.stormtypes as s_stormtypes
3
+
4
+ import synapse.tests.utils as s_test
5
+
6
+ class StormlibSpooledTest(s_test.SynTest):
7
+ async def test_lib_spooled_set(self):
8
+ async with self.getTestCore() as core:
9
+ await core.nodes('[inet:ipv4=1.2.3.4 :asn=20]')
10
+ await core.nodes('[inet:ipv4=5.6.7.8 :asn=30]')
11
+
12
+ q = '''
13
+ $set = $lib.spooled.set()
14
+ $set.add(1, 2, 3, 4)
15
+ return($set)
16
+ '''
17
+ valu = await core.callStorm(q)
18
+ self.eq({'1', '2', '3', '4'}, valu)
19
+
20
+ q = '''
21
+ $set = $lib.spooled.set()
22
+ $set.adds($lib.list(1, 2, 3, 4))
23
+ return($set)
24
+ '''
25
+ valu = await core.callStorm(q)
26
+ self.eq({'1', '2', '3', '4'}, valu)
27
+
28
+ q = '''
29
+ $set = $lib.spooled.set()
30
+ inet:ipv4 $set.add(:asn)
31
+ $set.rems((:asn,:asn))
32
+ [ graph:node="*" ] +graph:node [ :data=$set.list() ]
33
+ '''
34
+ nodes = await core.nodes(q)
35
+ self.len(1, nodes)
36
+ self.eq(nodes[0].get('data'), ())
37
+
38
+ q = '''
39
+ $set = $lib.spooled.set()
40
+ $set.add($foo)
41
+ $set.add($bar)
42
+ $set.add($biz)
43
+ return(($set.has($foo), $set.has(lolnop)))
44
+ '''
45
+ valu = await core.callStorm(q, opts={'vars': {'foo': b'foo', 'bar': b'bar', 'biz': b'biz'}})
46
+ self.eq(True, valu[0])
47
+ self.eq(False, valu[1])
48
+
49
+ q = '''
50
+ $set = $lib.spooled.set()
51
+ $set.adds(('foo', 'bar', 'baz', 'biz', 'biz', 'biz', 'beep', 'boop'))
52
+ return($set.size())
53
+ '''
54
+ valu = await core.callStorm(q)
55
+ self.eq(6, valu)
56
+
57
+ q = '''
58
+ $set = $lib.spooled.set()
59
+ $set.adds(('foo', 'bar', 'baz', 'biz', 'biz', 'biz', 'beep', 'boop'))
60
+
61
+ $set.rems(('baz', 'beep', 'bar'))
62
+ return($set)
63
+
64
+ '''
65
+ valu = await core.callStorm(q)
66
+ self.eq({'foo', 'boop', 'biz'}, valu)
67
+
68
+ q = '''
69
+ $set = $lib.spooled.set(1, 2, 3, 4 ,5)
70
+ $set.add(1, 2, 3, 4)
71
+ return($set.list())
72
+ '''
73
+ valu = await core.callStorm(q)
74
+ self.isinstance(valu, tuple)
75
+ self.len(5, valu)
76
+ self.isin('1', valu)
77
+ self.isin('2', valu)
78
+ self.isin('3', valu)
79
+ self.isin('4', valu)
80
+ self.isin('5', valu)
81
+
82
+ q = '''
83
+ $set = $lib.spooled.set()
84
+ $set.add($lib.true)
85
+ $set.add($lib.false)
86
+ $set.add($lib.true)
87
+ $set.add($lib.false)
88
+ $set.add('more stuff')
89
+
90
+ $dict = ({
91
+ "foo": "bar",
92
+ "biz": "baz",
93
+ })
94
+ $set.adds($dict)
95
+ return($set)
96
+ '''
97
+ valu = await core.callStorm(q)
98
+ self.len(5, valu)
99
+ self.isin(False, valu)
100
+ self.isin(True, valu)
101
+ self.isin('more stuff', valu)
102
+ self.isin(('biz', 'baz'), valu)
103
+ self.isin(('foo', 'bar'), valu)
104
+
105
+ q = '''
106
+ $set = $lib.spooled.set()
107
+ $set.adds($items)
108
+ for $x in $set {
109
+ $lib.print(`{$x} exists in the set`)
110
+ }
111
+ return()
112
+ '''
113
+ msgs = await core.stormlist(q, opts={'vars': {'items': [True, 'neato', False, 9001]}})
114
+ self.len(7, msgs)
115
+ self.stormIsInPrint('false exists in the set', msgs)
116
+ self.stormIsInPrint('true exists in the set', msgs)
117
+ self.stormIsInPrint('neato exists in the set', msgs)
118
+ self.stormIsInPrint('9001 exists in the set', msgs)
119
+
120
+ q = '''
121
+ $set = $lib.spooled.set(neato, neato, neato, neato)
122
+ $lib.print(`The set is {$set}`)
123
+ '''
124
+ msgs = await core.stormlist(q, opts={'vars': {'items': [True, 'neato', False, 9001]}})
125
+ self.stormIsInPrint("The set is {'neato'}", msgs)
126
+
127
+ # force a fallback
128
+ q = '''
129
+ $set = $lib.spooled.set()
130
+ $set.adds($lib.range(1500))
131
+ return($set.size())
132
+ '''
133
+ valu = await core.callStorm(q)
134
+ self.eq(1500, valu)
135
+
136
+ # sad paths
137
+ # too complex
138
+ q = '''
139
+ $set = $lib.spooled.set()
140
+ $set.add($stormnode)
141
+ return($set)
142
+ '''
143
+ stormnode = s_stormtypes.Node(nodes[0])
144
+ await self.asyncraises(s_exc.StormRuntimeError, core.callStorm(q, {'vars': {'stormnode': stormnode}}))
145
+
146
+ # mutable failures
147
+ q = '''
148
+ $set = $lib.spooled.set()
149
+ $set.add(({'neato': 'burrito'}))
150
+ return($set)
151
+ '''
152
+ await self.asyncraises(s_exc.StormRuntimeError, core.callStorm(q))
153
+
154
+ q = '''
155
+ $set = $lib.spooled.set()
156
+ $dict = ({'neato': 'burrito'})
157
+ $set.adds(($dict, $dict))
158
+ return($set)
159
+ '''
160
+ await self.asyncraises(s_exc.StormRuntimeError, core.callStorm(q))
161
+
162
+ q = '''
163
+ $set = $lib.spooled.set()
164
+ $form = $lib.model.form('inet:ipv4')
165
+ $set.adds(($stormnode, $form, $form))
166
+ return($set)
167
+ '''
168
+ # it'll blow up on the first
169
+ await self.asyncraises(s_exc.StormRuntimeError, core.callStorm(q, {'vars': {'stormnode': stormnode}}))
170
+
171
+ q = '''
172
+ $dict = ({'foo': 'bar'})
173
+ $set = $lib.spooled.set($dict)
174
+ return($set)
175
+ '''
176
+ await self.asyncraises(s_exc.StormRuntimeError, core.callStorm(q))
177
+
178
+ # type not msgpack-able
179
+ q = '''
180
+ $set = $lib.spooled.set()
181
+ $set.add($lib.model.form("inet:ipv4"))
182
+ return($set)
183
+ '''
184
+ await self.asyncraises(s_exc.StormRuntimeError, core.callStorm(q))
185
+
186
+ q = '''
187
+ $set = $lib.spooled.set($stormnode)
188
+ return($set)
189
+ '''
190
+ await self.asyncraises(s_exc.StormRuntimeError, core.callStorm(q, {'vars': {'stormnode': stormnode}}))
@@ -20,7 +20,6 @@ import synapse.lib.storm as s_storm
20
20
  import synapse.lib.hashset as s_hashset
21
21
  import synapse.lib.httpapi as s_httpapi
22
22
  import synapse.lib.modelrev as s_modelrev
23
- import synapse.lib.provenance as s_provenance
24
23
  import synapse.lib.stormtypes as s_stormtypes
25
24
 
26
25
  import synapse.tests.utils as s_test
@@ -4512,7 +4511,6 @@ class StormTypesTest(s_test.SynTest):
4512
4511
 
4513
4512
  MONO_DELT = 1543827303.0
4514
4513
  unixtime = datetime.datetime(year=2018, month=12, day=5, hour=7, minute=0, tzinfo=tz.utc).timestamp()
4515
- s_provenance.reset()
4516
4514
 
4517
4515
  def timetime():
4518
4516
  return unixtime
@@ -4846,6 +4844,7 @@ class StormTypesTest(s_test.SynTest):
4846
4844
 
4847
4845
  self.stormIsInPrint('last result: finished successfully with 0 nodes', mesgs)
4848
4846
  self.stormIsInPrint('entries: <None>', mesgs)
4847
+ self.stormIsInPrint('pool: false', mesgs)
4849
4848
 
4850
4849
  # Test 'stat' command
4851
4850
  mesgs = await core.stormlist('cron.stat xxx')
@@ -4919,7 +4918,7 @@ class StormTypesTest(s_test.SynTest):
4919
4918
  self.stormIsInErr('data.iden must match pattern', msgs)
4920
4919
 
4921
4920
  opts = {'vars': {'iden': 'cd263bd133a5dafa1e1c5e9a01d9d486'}}
4922
- q = "cron.add --iden $iden --day +1 --minute 14 {[test:guid=$lib.guid()]}"
4921
+ q = "cron.add --pool --iden $iden --day +1 --minute 14 {[test:guid=$lib.guid()]}"
4923
4922
  msgs = await core.stormlist(q, opts=opts)
4924
4923
  self.stormIsInPrint('Created cron job: cd263bd133a5dafa1e1c5e9a01d9d486', msgs)
4925
4924
 
@@ -6465,6 +6464,10 @@ words\tword\twrd'''
6465
6464
  self.eq(merge['creator'], core.auth.rootuser.iden)
6466
6465
  self.none(merge.get('updated'))
6467
6466
 
6467
+ merging = 'return($lib.view.get().getMergingViews()) '
6468
+
6469
+ self.eq([fork00], await core.callStorm(merging))
6470
+
6468
6471
  with self.raises(s_exc.AuthDeny):
6469
6472
  core.getView(fork00).reqValidVoter(root.iden)
6470
6473
 
@@ -6540,8 +6543,13 @@ words\tword\twrd'''
6540
6543
  self.none(core.getView(fork00))
6541
6544
  nodes = await core.nodes('inet:fqdn')
6542
6545
  self.len(2, nodes)
6546
+
6547
+ # previously successful merges
6543
6548
  self.len(1, await core.callStorm('$list = ([]) for $merge in $lib.view.get().getMerges() { $list.append($merge) } fini { return($list) }'))
6544
6549
 
6550
+ # current open merge requests
6551
+ self.eq([], await core.callStorm(merging))
6552
+
6545
6553
  # test out the delMergeRequest logic / cleanup
6546
6554
  forkdef = await core.getView().fork()
6547
6555
 
@@ -6549,6 +6557,7 @@ words\tword\twrd'''
6549
6557
 
6550
6558
  opts = {'view': fork.iden}
6551
6559
  self.nn(await core.callStorm('return($lib.view.get().setMergeRequest())', opts=opts))
6560
+ self.eq([fork.iden], await core.callStorm(merging))
6552
6561
 
6553
6562
  # confirm that you may not re-parent to a view with a merge request
6554
6563
  layr = await core.addLayer()
@@ -6564,6 +6573,8 @@ words\tword\twrd'''
6564
6573
  self.nn(await core.callStorm('return($lib.view.get().delMergeRequest())', opts=opts))
6565
6574
  self.len(0, [vote async for vote in fork.getMergeVotes()])
6566
6575
 
6576
+ self.eq([], await core.callStorm(merging))
6577
+
6567
6578
  # test coverage for beholder progress events...
6568
6579
  forkdef = await core.getView().fork()
6569
6580
  fork = core.getView(forkdef.get('iden'))
@@ -6572,10 +6583,12 @@ words\tword\twrd'''
6572
6583
  await core.stormlist('[ inet:ipv4=1.2.3.0/20 ]', opts=opts)
6573
6584
  await core.callStorm('return($lib.view.get().setMergeRequest())', opts=opts)
6574
6585
 
6586
+ self.eq([fork.iden], await core.callStorm(merging))
6587
+
6575
6588
  nevents = 8
6576
6589
  if s_common.envbool('SYNDEV_NEXUS_REPLAY'):
6577
6590
  # view:merge:vote:set fires twice
6578
- nevents = nevents + 1
6591
+ nevents += 1
6579
6592
  waiter = core.waiter(nevents, 'cell:beholder')
6580
6593
 
6581
6594
  opts = {'view': fork.iden, 'user': visi.iden}
@@ -6598,6 +6611,8 @@ words\tword\twrd'''
6598
6611
  self.eq(msgs[-1][1]['info']['merge']['creator'], core.auth.rootuser.iden)
6599
6612
  self.eq(msgs[-1][1]['info']['votes'][0]['user'], visi.iden)
6600
6613
 
6614
+ self.eq([], await core.callStorm(merging))
6615
+
6601
6616
  # test coverage for bad state for merge request
6602
6617
  fork00 = await core.getView().fork()
6603
6618
  fork01 = await core.getView(fork00['iden']).fork()
@@ -6606,8 +6621,11 @@ words\tword\twrd'''
6606
6621
  with self.raises(s_exc.BadState):
6607
6622
  await core.callStorm('return($lib.view.get().setMergeRequest())', opts=opts)
6608
6623
 
6624
+ self.eq([], await core.callStorm(merging))
6625
+
6609
6626
  await core.delView(fork01['iden'])
6610
6627
  await core.callStorm('return($lib.view.get().setMergeRequest())', opts=opts)
6628
+ self.eq([fork00['iden']], await core.callStorm(merging))
6611
6629
 
6612
6630
  core.getView().layers[0].readonly = True
6613
6631
  with self.raises(s_exc.BadState):
@@ -6626,6 +6644,8 @@ words\tword\twrd'''
6626
6644
  await core.stormlist('[ inet:ipv4=5.5.5.5 ]', opts=opts)
6627
6645
  await core.callStorm('return($lib.view.get().setMergeRequest())', opts=opts)
6628
6646
 
6647
+ self.eq(set([fork.iden, fork00['iden']]), set(await core.callStorm(merging)))
6648
+
6629
6649
  # hamstring the runViewMerge method on the new view
6630
6650
  async def fake():
6631
6651
  return
@@ -6660,3 +6680,6 @@ words\tword\twrd'''
6660
6680
 
6661
6681
  msgs = await core.stormlist('$lib.view.get().set(quorum, $lib.null)')
6662
6682
  self.stormHasNoWarnErr(msgs)
6683
+
6684
+ with self.raises(s_exc.BadState):
6685
+ await core.callStorm(merging)
@@ -2767,3 +2767,70 @@ class InetModelTest(s_t_utils.SynTest):
2767
2767
  self.eq(nodes[0].get('client'), 'tcp://1.2.3.4')
2768
2768
  self.eq(nodes[0].get('client:ipv4'), 0x01020304)
2769
2769
  self.eq(nodes[0].get('client:ipv6'), '::1')
2770
+
2771
+ async def test_model_inet_tls_handshake(self):
2772
+
2773
+ async with self.getTestCore() as core:
2774
+ props = {
2775
+ 'ja3': '1' * 32,
2776
+ 'ja3s': '2' * 32,
2777
+ 'client': 'tcp://1.2.3.4:8888',
2778
+ 'server': 'tcp://5.6.7.8:9999'
2779
+ }
2780
+
2781
+ nodes = await core.nodes('''
2782
+ [
2783
+ inet:tls:handshake=*
2784
+ :time=now
2785
+ :flow=*
2786
+ :server=$server
2787
+ :server:cert=*
2788
+ :server:fingerprint:ja3=$ja3s
2789
+ :client=$client
2790
+ :client:cert=*
2791
+ :client:fingerprint:ja3=$ja3
2792
+ ]
2793
+ ''', opts={'vars': props})
2794
+ self.len(1, nodes)
2795
+ self.nn(nodes[0].get('time'))
2796
+ self.nn(nodes[0].get('flow'))
2797
+ self.nn(nodes[0].get('server:cert'))
2798
+ self.nn(nodes[0].get('client:cert'))
2799
+
2800
+ self.eq(props['ja3'], nodes[0].get('client:fingerprint:ja3'))
2801
+ self.eq(props['ja3s'], nodes[0].get('server:fingerprint:ja3'))
2802
+
2803
+ self.eq(props['client'], nodes[0].get('client'))
2804
+ self.eq(props['server'], nodes[0].get('server'))
2805
+
2806
+ async def test_model_inet_ja3(self):
2807
+
2808
+ async with self.getTestCore() as core:
2809
+
2810
+ ja3 = '76e7b0cb0994d60a4b3f360a088fac39'
2811
+ nodes = await core.nodes('[ inet:tls:ja3:sample=(tcp://1.2.3.4, $md5) ]', opts={'vars': {'md5': ja3}})
2812
+ self.len(1, nodes)
2813
+ self.eq(nodes[0].get('client'), 'tcp://1.2.3.4')
2814
+ self.eq(nodes[0].get('ja3'), ja3)
2815
+
2816
+ ja3 = '4769ad08107979c719d86270e706fed5'
2817
+ nodes = await core.nodes('[ inet:tls:ja3s:sample=(tcp://2.2.2.2, $md5) ]', opts={'vars': {'md5': ja3}})
2818
+ self.len(1, nodes)
2819
+ self.eq(nodes[0].get('server'), 'tcp://2.2.2.2')
2820
+ self.eq(nodes[0].get('ja3s'), ja3)
2821
+
2822
+ async def test_model_inet_tls_certs(self):
2823
+
2824
+ async with self.getTestCore() as core:
2825
+
2826
+ server = 'e4f6db65dbaa7a4598f7379f75dcd5f5'
2827
+ client = 'df8d1f7e04f7c4a322e04b0b252e2851'
2828
+ nodes = await core.nodes('[inet:tls:servercert=(tcp://1.2.3.4:1234, $server)]', opts={'vars': {'server': server}})
2829
+ self.len(1, nodes)
2830
+ self.eq(nodes[0].get('server'), 'tcp://1.2.3.4:1234')
2831
+ self.eq(nodes[0].get('cert'), server)
2832
+
2833
+ nodes = await core.nodes('[inet:tls:clientcert=(tcp://5.6.7.8:5678, $client)]', opts={'vars': {'client': client}})
2834
+ self.len(1, nodes)
2835
+ self.eq(nodes[0].get('client'), 'tcp://5.6.7.8:5678')
2836
+ self.eq(nodes[0].get('cert'), client)
@@ -435,6 +435,8 @@ class RiskModelTest(s_t_utils.SynTest):
435
435
  :public:url=https://wikileaks.org/acme
436
436
  :reporter={ gen.ou.org vertex }
437
437
  :reporter:name=vertex
438
+ :size:bytes=99
439
+ :extortion=*
438
440
  ]''')
439
441
  self.len(1, nodes)
440
442
  self.eq('wikileaks acme leak', nodes[0].get('name'))
@@ -442,9 +444,11 @@ class RiskModelTest(s_t_utils.SynTest):
442
444
  self.eq(1698883200000, nodes[0].get('disclosed'))
443
445
  self.eq('public.', nodes[0].get('type'))
444
446
  self.eq(1, nodes[0].get('public'))
447
+ self.eq(99, nodes[0].get('size:bytes'))
445
448
  self.eq('https://wikileaks.org/acme', nodes[0].get('public:url'))
446
449
  self.eq('vertex', nodes[0].get('reporter:name'))
447
450
 
451
+ self.len(1, await core.nodes('risk:leak -> risk:extortion'))
448
452
  self.len(1, await core.nodes('risk:leak -> risk:leak:type:taxonomy'))
449
453
  self.len(1, await core.nodes('risk:leak :owner -> ps:contact +:orgname=acme'))
450
454
  self.len(1, await core.nodes('risk:leak :leaker -> ps:contact +:orgname=wikileaks'))
@@ -454,6 +458,7 @@ class RiskModelTest(s_t_utils.SynTest):
454
458
 
455
459
  nodes = await core.nodes('''[ risk:extortion=*
456
460
  :demanded=20231102
461
+ :deadline=20240329
457
462
  :name="APT99 Extorted ACME"
458
463
  :desc="APT99 extorted ACME for a zillion vertex coins."
459
464
  :type=fingain
@@ -474,6 +479,7 @@ class RiskModelTest(s_t_utils.SynTest):
474
479
  self.eq('apt99 extorted acme', nodes[0].get('name'))
475
480
  self.eq('APT99 extorted ACME for a zillion vertex coins.', nodes[0].get('desc'))
476
481
  self.eq(1698883200000, nodes[0].get('demanded'))
482
+ self.eq(1711670400000, nodes[0].get('deadline'))
477
483
  self.eq('fingain.', nodes[0].get('type'))
478
484
  self.eq(1, nodes[0].get('public'))
479
485
  self.eq(1, nodes[0].get('success'))
@@ -831,15 +831,17 @@ class TeleTest(s_t_utils.SynTest):
831
831
 
832
832
  await targ.waitready()
833
833
 
834
- self.eq(110, await targ.dostuff(100))
834
+ prox00 = await targ.proxy(timeout=12)
835
+ self.eq(110, await prox00.dostuff(100))
836
+
835
837
  self.eq(1, fail0.count)
836
838
  self.eq(0, fail1.count)
837
839
 
838
- _prox = await targ.proxy()
839
840
  await dmon0.fini()
840
- self.true(await _prox.waitfini(10))
841
+ self.true(await prox00.waitfini(10))
841
842
 
842
- self.eq(110, await targ.dostuff(100))
843
+ prox01 = await targ.proxy(timeout=12)
844
+ self.eq(110, await prox01.dostuff(100))
843
845
  self.eq(1, fail0.count)
844
846
  self.eq(1, fail1.count)
845
847
 
@@ -855,15 +857,36 @@ class TeleTest(s_t_utils.SynTest):
855
857
  mesgs = stream.read()
856
858
  self.notin('password', mesgs)
857
859
 
858
- self.eq(110, await targ.dostuff(100))
860
+ prox00 = await targ.proxy(timeout=12)
861
+ self.eq(110, await prox00.dostuff(100))
859
862
 
860
863
  self.eq(1, fail0.count)
861
864
  self.eq(2, fail1.count)
862
865
 
863
866
  async with await s_telepath.open(url1) as targ:
864
- await targ.waitready()
865
- self.eq(110, await targ.dostuff(100))
867
+ await targ.waitready(timeout=12)
868
+ prox00 = await targ.proxy(timeout=12)
869
+ self.eq(110, await prox00.dostuff(100))
870
+
871
+ async def onlink(proxy, urlinfo):
872
+ self.eq(110, await proxy.dostuff(100))
873
+ _url = s_telepath.zipurl(urlinfo)
874
+ logger.info(f'Connected to url={_url}')
875
+
876
+ with self.getAsyncLoggerStream('synapse.tests.test_telepath',
877
+ f'Connected to url=tcp://127.0.0.1:{addr1[1]}/foo') as stream:
878
+ async with await s_telepath.open(url1, onlink=onlink) as targ:
879
+ self.true(await stream.wait(timeout=12))
880
+
881
+ # Coverage
882
+ async def badonlink(proxy, urlinfo):
883
+ raise ValueError('oopsie')
884
+
885
+ with self.getAsyncLoggerStream('synapse.telepath', 'onlink: ') as stream:
886
+ async with await s_telepath.open(url1, onlink=badonlink) as targ:
887
+ self.true(await stream.wait(timeout=12))
866
888
 
889
+ await dmon0.fini()
867
890
  await dmon1.fini()
868
891
 
869
892
  async def test_telepath_poolsize(self):
@@ -2,6 +2,26 @@ import synapse.lib.output as s_output
2
2
  import synapse.tests.utils as s_test
3
3
  import synapse.tools.modrole as s_t_modrole
4
4
 
5
+ rolelist = s_test.deguidify('''
6
+ Roles:
7
+ ce6928dfe88cace918c405bbef51e72f - all
8
+ 0f316b3f3e6ec970fcdb9a085fcd5b77 - visi
9
+ '''.strip())
10
+
11
+ roleinfo = s_test.deguidify('''
12
+ Role: visi (145c3321a0cd0cd06de19174415a7aeb)
13
+
14
+ Rules:
15
+ [0 ] - !foo.bar.baz
16
+ [1 ] - foo.bar
17
+
18
+ Gates:
19
+ 3ad191c63a201df3246c6d6ff81763ad
20
+ Admin: False
21
+ [0 ] - !bar.baz.faz
22
+ [1 ] - bar.baz
23
+ '''.strip())
24
+
5
25
  class ModRoleTest(s_test.SynTest):
6
26
 
7
27
  async def test_tools_modrole(self):
@@ -40,6 +60,60 @@ class ModRoleTest(s_test.SynTest):
40
60
  self.true(bool(visi.allowed('foo.bar.gaz'.split('.'))))
41
61
  self.false(bool(visi.allowed('foo.bar.baz'.split('.'))))
42
62
 
63
+ gateiden = core.getLayer().iden
64
+ argv = (
65
+ '--svcurl', svcurl,
66
+ 'visi',
67
+ '--allow', 'bar.baz',
68
+ '--deny', 'bar.baz.faz',
69
+ '--gate', gateiden,
70
+ )
71
+ outp = s_output.OutPutStr()
72
+ self.eq(0, await s_t_modrole.main(argv, outp=outp))
73
+ self.isin(f'...adding allow rule: bar.baz on gate {gateiden}', str(outp))
74
+ self.isin(f'...adding deny rule: bar.baz.faz on gate {gateiden}', str(outp))
75
+
76
+ gate = await core.getAuthGate(gateiden)
77
+ for role in gate['roles']:
78
+ if role['iden'] == visi.iden:
79
+ self.isin((True, ('bar', 'baz')), role['rules'])
80
+ self.isin((False, ('bar', 'baz', 'faz')), role['rules'])
81
+
82
+ argv = (
83
+ '--svcurl', svcurl,
84
+ '--list',
85
+ )
86
+ outp = s_output.OutPutStr()
87
+ self.eq(0, await s_t_modrole.main(argv, outp=outp))
88
+ self.isin(rolelist, s_test.deguidify(str(outp)))
89
+
90
+ argv = (
91
+ '--svcurl', svcurl,
92
+ '--list',
93
+ 'visi',
94
+ )
95
+ outp = s_output.OutPutStr()
96
+ self.eq(0, await s_t_modrole.main(argv, outp=outp))
97
+ self.isin(roleinfo, s_test.deguidify(str(outp)))
98
+
99
+ argv = (
100
+ '--svcurl', svcurl,
101
+ '--list',
102
+ 'newprole',
103
+ )
104
+ outp = s_output.OutPutStr()
105
+ self.eq(1, await s_t_modrole.main(argv, outp=outp))
106
+ self.isin('ERROR: Role not found: newprole', str(outp))
107
+
108
+ argv = (
109
+ '--svcurl', svcurl,
110
+ 'visi',
111
+ '--gate', 'newp',
112
+ )
113
+ outp = s_output.OutPutStr()
114
+ self.eq(1, await s_t_modrole.main(argv, outp=outp))
115
+ self.isin('ERROR: No auth gate found with iden: newp', str(outp))
116
+
43
117
  argv = (
44
118
  '--svcurl', svcurl,
45
119
  '--add',
@@ -59,3 +133,10 @@ class ModRoleTest(s_test.SynTest):
59
133
  self.eq(0, await s_t_modrole.main(argv, outp=outp))
60
134
  self.isin('...deleting role: visi', str(outp))
61
135
  self.none(await core.auth.getRoleByName('visi'))
136
+
137
+ argv = (
138
+ '--svcurl', svcurl,
139
+ )
140
+ outp = s_output.OutPutStr()
141
+ self.eq(1, await s_t_modrole.main(argv, outp=outp))
142
+ self.isin('ERROR: A rolename argument is required when --list is not specified.', str(outp))