synapse 2.167.0__py311-none-any.whl → 2.168.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.

synapse/cortex.py CHANGED
@@ -881,7 +881,9 @@ class Cortex(s_oauth.OAuthMixin, s_cell.Cell): # type: ignore
881
881
 
882
882
  self.maxnodes = self.conf.get('max:nodes')
883
883
  self.nodecount = 0
884
+
884
885
  self.migration = False
886
+ self._migration_lock = asyncio.Lock()
885
887
 
886
888
  self.stormmods = {} # name: mdef
887
889
  self.stormpkgs = {} # name: pkgdef
@@ -1480,12 +1482,21 @@ class Cortex(s_oauth.OAuthMixin, s_cell.Cell): # type: ignore
1480
1482
  await self.stormdmons.start()
1481
1483
  await self.agenda.clearRunningStatus()
1482
1484
 
1483
- for view in self.views.values():
1484
- await view.initTrigTask()
1485
- await view.initMergeTask()
1485
+ async def _runMigrations():
1486
+ # Run migrations when this cortex becomes active. This is to prevent
1487
+ # migrations getting skipped in a zero-downtime upgrade path
1488
+ # (upgrade mirror, promote mirror).
1489
+ await self._checkLayerModels()
1486
1490
 
1487
- for layer in self.layers.values():
1488
- await layer.initLayerActive()
1491
+ # Once migrations are complete, start the view and layer tasks.
1492
+ for view in self.views.values():
1493
+ await view.initTrigTask()
1494
+ await view.initMergeTask()
1495
+
1496
+ for layer in self.layers.values():
1497
+ await layer.initLayerActive()
1498
+
1499
+ self.runActiveTask(_runMigrations())
1489
1500
 
1490
1501
  await self.initStormPool()
1491
1502
 
@@ -3597,6 +3608,7 @@ class Cortex(s_oauth.OAuthMixin, s_cell.Cell): # type: ignore
3597
3608
  break
3598
3609
 
3599
3610
  yield ioff, layr.iden, SYNC_NODEEDITS, item, meta
3611
+ await asyncio.sleep(0)
3600
3612
 
3601
3613
  if layr.isdeleted:
3602
3614
  yield layr.deloffs, layr.iden, SYNC_LAYR_DEL, (), {}
@@ -4363,7 +4375,7 @@ class Cortex(s_oauth.OAuthMixin, s_cell.Cell): # type: ignore
4363
4375
  return ret
4364
4376
 
4365
4377
  async def _checkLayerModels(self):
4366
- with self.enterMigrationMode():
4378
+ async with self.enterMigrationMode():
4367
4379
  mrev = s_modelrev.ModelRev(self)
4368
4380
  await mrev.revCoreLayers()
4369
4381
 
@@ -6098,11 +6110,12 @@ class Cortex(s_oauth.OAuthMixin, s_cell.Cell): # type: ignore
6098
6110
  appt = await self.agenda.get(iden)
6099
6111
  await appt.edits(edits)
6100
6112
 
6101
- @contextlib.contextmanager
6102
- def enterMigrationMode(self):
6103
- self.migration = True
6104
- yield
6105
- self.migration = False
6113
+ @contextlib.asynccontextmanager
6114
+ async def enterMigrationMode(self):
6115
+ async with self._migration_lock:
6116
+ self.migration = True
6117
+ yield
6118
+ self.migration = False
6106
6119
 
6107
6120
  async def iterFormRows(self, layriden, form, stortype=None, startvalu=None):
6108
6121
  '''
synapse/lib/aha.py CHANGED
@@ -807,7 +807,8 @@ class AhaCell(s_cell.Cell):
807
807
  async def _setAhaSvcDown(self, name, linkiden, network=None):
808
808
  svcname, svcnetw, svcfull = self._nameAndNetwork(name, network)
809
809
  path = ('aha', 'services', svcnetw, svcname)
810
- await self.jsonstor.cmpDelPathObjProp(path, 'svcinfo/online', linkiden)
810
+ if await self.jsonstor.cmpDelPathObjProp(path, 'svcinfo/online', linkiden):
811
+ await self.jsonstor.setPathObjProp(path, 'svcinfo/ready', False)
811
812
 
812
813
  # Check if we have any links which may need to be removed
813
814
  current_sessions = {s_common.guid(iden): sess for iden, sess in self.dmon.sessions.items()}
synapse/lib/layer.py CHANGED
@@ -165,11 +165,13 @@ class LayerApi(s_cell.CellApi):
165
165
  await self._reqUserAllowed(self.liftperm)
166
166
  async for item in self.layr.syncNodeEdits(offs, wait=wait):
167
167
  yield item
168
+ await asyncio.sleep(0)
168
169
 
169
170
  async def syncNodeEdits2(self, offs, wait=True):
170
171
  await self._reqUserAllowed(self.liftperm)
171
172
  async for item in self.layr.syncNodeEdits2(offs, wait=wait):
172
173
  yield item
174
+ await asyncio.sleep(0)
173
175
 
174
176
  async def getEditIndx(self):
175
177
  '''
synapse/lib/modelrev.py CHANGED
@@ -768,6 +768,12 @@ class ModelRev:
768
768
  Returns:
769
769
  None
770
770
  '''
771
+ if opts is None:
772
+ opts = {}
773
+
774
+ # Migrations only run on leaders
775
+ opts['mirror'] = False
776
+
771
777
  async def _runStorm():
772
778
  async for mesgtype, mesginfo in self.core.storm(text, opts=opts):
773
779
  if mesgtype == 'print':
synapse/lib/modules.py CHANGED
@@ -28,4 +28,5 @@ coremods = (
28
28
  'synapse.models.biz.BizModule',
29
29
  'synapse.models.belief.BeliefModule',
30
30
  'synapse.models.science.ScienceModule',
31
+ 'synapse.models.planning.PlanModule',
31
32
  )
@@ -190,7 +190,7 @@ class AhaPool(s_stormtypes.StormType):
190
190
  'desc': 'The name of the AHA service to add. It is easiest to use the relative name of a service, ending with "...".', },
191
191
  ),
192
192
  'returns': {'type': 'null', }}},
193
- {'name': 'add', 'desc': '''Remove a service from the AHA pool.
193
+ {'name': 'del', 'desc': '''Remove a service from the AHA pool.
194
194
 
195
195
  Examples:
196
196
  Remove a service from a pool with its relative name::
@@ -203,7 +203,7 @@ class AhaPool(s_stormtypes.StormType):
203
203
  {'name': 'svcname', 'type': 'str',
204
204
  'desc': 'The name of the AHA service to remove. It is easiest to use the relative name of a service, ending with "...".', },
205
205
  ),
206
- 'returns': {'type': 'null', }}},
206
+ 'returns': {'type': ['null', 'str'], 'desc': 'The service removed from the pool or null if a service was not removed.'}}},
207
207
  )
208
208
  _storm_typename = 'aha:pool'
209
209
 
@@ -243,9 +243,20 @@ class AhaPool(s_stormtypes.StormType):
243
243
  proxy = await self.runt.snap.core.reqAhaProxy()
244
244
 
245
245
  poolname = self.poolinfo.get('name')
246
- await proxy.delAhaPoolSvc(poolname, svcname)
246
+ newinfo = await proxy.delAhaPoolSvc(poolname, svcname)
247
+
248
+ tname = svcname
249
+ if tname.endswith('...'):
250
+ tname = tname[:-2]
251
+ deleted_service = None
252
+ deleted_services = [svc for svc in self.poolinfo.get('services').keys()
253
+ if svc not in newinfo.get('services') and svc.startswith(tname)]
254
+ if deleted_services:
255
+ deleted_service = deleted_services[0]
256
+
257
+ self.poolinfo = newinfo
247
258
 
248
- self.poolinfo = await proxy.getAhaPool(poolname)
259
+ return deleted_service
249
260
 
250
261
  stormcmds = (
251
262
  {
@@ -319,8 +330,12 @@ stormcmds = (
319
330
  $pool = $lib.aha.pool.get($cmdopts.poolname)
320
331
  if (not $pool) { $lib.exit(`No AHA service pool named: {$cmdopts.poolname}`) }
321
332
 
322
- $pool.del($cmdopts.svcname)
323
- $lib.print(`AHA service ({$cmdopts.svcname}) removed from service pool ({$pool.name})`)
333
+ $svc = $pool.del($cmdopts.svcname)
334
+ if $svc {
335
+ $lib.print(`AHA service ({$svc}) removed from service pool ({$pool.name})`)
336
+ } else {
337
+ $lib.print(`Did not remove ({$cmdopts.svcname}) from the service pool.`)
338
+ }
324
339
  ''',
325
340
  },
326
341
  {
@@ -51,6 +51,14 @@ class LibEasyPerm(s_stormtypes.Lib):
51
51
  'desc': 'Optional error message to present if user does not have required permission level.'},
52
52
  ),
53
53
  'returns': {'type': 'null'}}},
54
+ {'name': 'level.admin', 'desc': 'Constant for admin permission.',
55
+ 'type': 'int', },
56
+ {'name': 'level.deny', 'desc': 'Constant for deny permission.',
57
+ 'type': 'int', },
58
+ {'name': 'level.edit', 'desc': 'Constant for edit permission.',
59
+ 'type': 'int', },
60
+ {'name': 'level.read', 'desc': 'Constant for read permission.',
61
+ 'type': 'int', },
54
62
  )
55
63
  _storm_lib_path = ('auth', 'easyperm')
56
64
 
synapse/lib/stormtypes.py CHANGED
@@ -1707,6 +1707,13 @@ class LibDict(Lib):
1707
1707
  A Storm Library for interacting with dictionaries.
1708
1708
  '''
1709
1709
  _storm_locals = (
1710
+ {'name': 'has', 'desc': 'Check a dictionary has a specific key.',
1711
+ 'type': {'type': 'function', '_funcname': '_has',
1712
+ 'args': (
1713
+ {'name': 'valu', 'type': 'dict', 'desc': 'The dictionary being checked.'},
1714
+ {'name': 'name', 'type': 'str', 'desc': 'The key name to check.'},
1715
+ ),
1716
+ 'returns': {'type': 'boolean', 'desc': 'True if the key is present, false if the key is not present.'}}},
1710
1717
  {'name': 'keys', 'desc': 'Retrieve a list of keys in the specified dictionary.',
1711
1718
  'type': {'type': 'function', '_funcname': '_keys',
1712
1719
  'args': (
synapse/lib/version.py CHANGED
@@ -223,6 +223,6 @@ def reqVersion(valu, reqver,
223
223
  ##############################################################################
224
224
  # The following are touched during the release process by bumpversion.
225
225
  # Do not modify these directly.
226
- version = (2, 167, 0)
226
+ version = (2, 168, 0)
227
227
  verstring = '.'.join([str(x) for x in version])
228
- commit = '7b2983533ea27d69e547ac54d9aab953630137c2'
228
+ commit = 'd07eb2560a6e5e025ce9c20efaafe5571a55856c'
synapse/lib/view.py CHANGED
@@ -55,6 +55,7 @@ class ViewApi(s_cell.CellApi):
55
55
  layr = self.view.layers[0]
56
56
  async for item in layr.syncNodeEdits2(offs, wait=wait):
57
57
  yield item
58
+ await asyncio.sleep(0)
58
59
 
59
60
  @s_cell.adminapi()
60
61
  async def saveNodeEdits(self, edits, meta):
@@ -0,0 +1,161 @@
1
+ import synapse.lib.module as s_module
2
+
3
+ class PlanModule(s_module.CoreModule):
4
+
5
+ def getModelDefs(self):
6
+ return (('plan', {
7
+ 'types': (
8
+ ('plan:system', ('guid', {}), {
9
+ 'doc': 'A planning or behavioral analysis system that defines phases and procedures.'}),
10
+
11
+ ('plan:phase', ('guid', {}), {
12
+ 'doc': 'A phase within a planning system which may be used to group steps within a procedure.'}),
13
+
14
+ ('plan:procedure', ('guid', {}), {
15
+ 'doc': 'A procedure consisting of steps.'}),
16
+
17
+ ('plan:procedure:type:taxonomy', ('taxonomy', {}), {
18
+ 'interfaces': ('meta:taxonomy',),
19
+ 'doc': 'A taxonomy of procedure types.'}),
20
+
21
+ ('plan:procedure:variable', ('guid', {}), {
22
+ 'doc': 'A variable used by a procedure.'}),
23
+
24
+ ('plan:procedure:step', ('guid', {}), {
25
+ 'doc': 'A step within a procedure.'}),
26
+
27
+ ('plan:procedure:link', ('guid', {}), {
28
+ 'doc': 'A link between steps in a procedure.'}),
29
+ ),
30
+
31
+ 'forms': (
32
+ ('plan:system', {}, (
33
+
34
+ ('name', ('str', {'lower': True, 'onespace': True}), {
35
+ 'ex': 'mitre att&ck flow',
36
+ 'doc': 'The name of the planning system.'}),
37
+
38
+ ('summary', ('str', {}), {
39
+ 'disp': {'hint': 'text'},
40
+ 'doc': 'A summary of the purpose and use case for the planning system.'}),
41
+
42
+ ('author', ('ps:contact', {}), {
43
+ 'doc': 'The contact of the person or organization which authored the system.'}),
44
+
45
+ ('created', ('time', {}), {
46
+ 'doc': 'The time the planning system was first created.'}),
47
+
48
+ ('updated', ('time', {}), {
49
+ 'doc': 'The time the planning system was last updated.'}),
50
+
51
+ ('version', ('it:semver', {}), {
52
+ 'doc': 'The version of the planning system.'}),
53
+
54
+ ('url', ('inet:url', {}), {
55
+ 'doc': 'The primary URL which documents the planning system.'}),
56
+ )),
57
+ ('plan:phase', {}, (
58
+ ('title', ('str', {}), {
59
+ 'ex': 'Reconnaissance Phase',
60
+ 'doc': 'The title of the phase.'}),
61
+
62
+ ('summary', ('str', {}), {
63
+ 'disp': {'hint': 'text'},
64
+ 'doc': 'A summary of the definition of the phase.'}),
65
+
66
+ ('index', ('int', {}), {
67
+ 'doc': 'The index of this phase within the phases of the system.'}),
68
+
69
+ ('url', ('inet:url', {}), {
70
+ 'doc': 'A URL which links to the full documentation about the phase.'}),
71
+
72
+ ('system', ('plan:system', {}), {
73
+ 'doc': 'The planning system which defines this phase.'}),
74
+ )),
75
+ ('plan:procedure:type:taxonomy', {}, ()),
76
+ ('plan:procedure', {}, (
77
+
78
+ ('title', ('str', {}), {
79
+ 'ex': 'Network Reconnaissance Procedure',
80
+ 'doc': 'The name of the procedure.'}),
81
+
82
+ ('summary', ('str', {}), {
83
+ 'disp': {'hint': 'text'},
84
+ 'doc': 'A summary of the purpose and use cases for the procedure.'}),
85
+
86
+ ('author', ('ps:contact', {}), {
87
+ 'doc': 'The contact of the person or organization which authored the procedure.'}),
88
+
89
+ ('created', ('time', {}), {
90
+ 'doc': 'The time the procedure was created.'}),
91
+
92
+ ('updated', ('time', {}), {
93
+ 'doc': 'The time the procedure was last updated.'}),
94
+
95
+ ('version', ('it:semver', {}), {
96
+ 'doc': 'The version of the procedure.'}),
97
+
98
+ ('system', ('plan:system', {}), {
99
+ 'doc': 'The planning system which defines this procedure.'}),
100
+
101
+ ('type', ('plan:procedure:type:taxonomy', {}), {
102
+ 'doc': 'A type classification for the procedure.'}),
103
+
104
+ ('inputs', ('array', {'type': 'plan:procedure:variable', 'uniq': True, 'sorted': True}), {
105
+ 'doc': 'An array of inputs required to execute the procedure.'}),
106
+
107
+ ('firststep', ('plan:procedure:step', {}), {
108
+ 'doc': 'The first step in the procedure.'}),
109
+ )),
110
+ ('plan:procedure:variable', {}, (
111
+
112
+ ('name', ('str', {}), {
113
+ 'doc': 'The name of the variable.'}),
114
+
115
+ ('type', ('str', {}), {
116
+ 'doc': 'The type for the input. Types are specific to the planning system.'}),
117
+
118
+ ('default', ('data', {}), {
119
+ 'doc': 'The optional default value if the procedure is invoked without the input.'}),
120
+
121
+ ('procedure', ('plan:procedure', {}), {
122
+ 'doc': 'The procedure which defines the variable.'}),
123
+ )),
124
+ ('plan:procedure:step', {}, (
125
+
126
+ ('phase', ('plan:phase', {}), {
127
+ 'doc': 'The phase that the step belongs within.'}),
128
+
129
+ ('procedure', ('plan:procedure', {}), {
130
+ 'doc': 'The procedure which defines the step.'}),
131
+
132
+ ('title', ('str', {}), {
133
+ 'ex': 'Scan the IPv4 address range for open ports',
134
+ 'doc': 'The title of the step.'}),
135
+
136
+ ('summary', ('str', {}), {
137
+ 'doc': 'A summary of the tasks executed within the step.'}),
138
+
139
+ ('outputs', ('array', {'type': 'plan:procedure:variable', 'uniq': True, 'sorted': True}), {
140
+ 'doc': 'An array of variables defined in this step.'}),
141
+
142
+ ('techniques', ('array', {'type': 'ou:technique', 'uniq': True, 'sorted': True}), {
143
+ 'doc': 'An array of techniques used when executing this step.'}),
144
+
145
+ ('links', ('array', {'type': 'plan:procedure:link', 'uniq': True}), {
146
+ 'doc': 'An array of links to subsequent steps.'}),
147
+
148
+ )),
149
+ ('plan:procedure:link', {}, (
150
+
151
+ ('condition', ('bool', {}), {
152
+ 'doc': 'Set to true/false if this link is conditional based on a decision step.'}),
153
+
154
+ ('next', ('plan:procedure:step', {}), {
155
+ 'doc': 'The next step in the plan.'}),
156
+
157
+ ('procedure', ('plan:procedure', {}), {
158
+ 'doc': 'The procedure which defines the link.'}),
159
+ )),
160
+ ),
161
+ }),)
@@ -7958,7 +7958,7 @@ class CortexBasicTest(s_t_utils.SynTest):
7958
7958
  waiter = core01.stormpool.waiter(1, 'svc:del')
7959
7959
  msgs = await core01.stormlist('aha.pool.svc.del pool00... 01.core...', opts={'mirror': False})
7960
7960
  self.stormHasNoWarnErr(msgs)
7961
- self.stormIsInPrint('AHA service (01.core...) removed from service pool (pool00.loop.vertex.link)', msgs)
7961
+ self.stormIsInPrint('AHA service (01.core.loop.vertex.link) removed from service pool (pool00.loop.vertex.link)', msgs)
7962
7962
 
7963
7963
  # TODO: this wait should not return None
7964
7964
  await waiter.wait(timeout=3)
@@ -1126,7 +1126,7 @@ class AhaTest(s_test.SynTest):
1126
1126
  ready = svcinfo.get('ready')
1127
1127
  online = svcinfo.get('online')
1128
1128
  self.none(online)
1129
- self.true(ready) # Ready is not cleared upon restart
1129
+ self.false(ready) # Ready is cleared upon restart / setting service down.
1130
1130
 
1131
1131
  n = 3
1132
1132
  if len(stack._exit_callbacks) > 0:
@@ -1245,7 +1245,12 @@ class AhaTest(s_test.SynTest):
1245
1245
 
1246
1246
  msgs = await core00.stormlist('aha.pool.svc.del pool00... 00...')
1247
1247
  self.stormHasNoWarnErr(msgs)
1248
- self.stormIsInPrint('AHA service (00...) removed from service pool (pool00.loop.vertex.link)', msgs)
1248
+ self.stormIsInPrint('AHA service (00.loop.vertex.link) removed from service pool (pool00.loop.vertex.link)',
1249
+ msgs)
1250
+
1251
+ msgs = await core00.stormlist('aha.pool.svc.del pool00... 00...')
1252
+ self.stormHasNoWarnErr(msgs)
1253
+ self.stormIsInPrint('Did not remove (00...) from the service pool.', msgs)
1249
1254
 
1250
1255
  await waiter.wait(timeout=3)
1251
1256
  run00 = await (await pool.proxy(timeout=3)).getCellRunId()
@@ -139,7 +139,7 @@ Member: 00.cell.loop.vertex.link'''
139
139
  self.len(nevents, await waiter.wait(timeout=12))
140
140
 
141
141
  msgs = await core00.stormlist('aha.svc.list')
142
- self.stormIsInPrint('01.cell.loop.vertex.link false false true', msgs)
142
+ self.stormIsInPrint('01.cell.loop.vertex.link false false false', msgs)
143
143
 
144
144
  # Fake a record
145
145
  await aha.addAhaSvc('00.newp', info={'urlinfo': {'scheme': 'tcp', 'host': '0.0.0.0', 'port': '3030'}},
@@ -369,7 +369,7 @@ class TrigTest(s_t_utils.SynTest):
369
369
 
370
370
  # coverage for migration mode
371
371
  await core.nodes('[inet:fqdn=vertex.link +#foo]') # for additional migration mode trigger tests below
372
- with core.enterMigrationMode():
372
+ async with core.enterMigrationMode():
373
373
  await core.nodes('inet:fqdn=vertex.link [ +#bar -#foo ]')
374
374
 
375
375
  async def test_trigger_delete(self):
@@ -774,7 +774,7 @@ class TrigTest(s_t_utils.SynTest):
774
774
  await core.nodes('trigger.add edge:add --verb r* --n2form test:int --query { [ +#n2 ] }')
775
775
  await core.nodes('trigger.add edge:add --verb no** --form test:int --n2form test:str --query { [ +#both ] }')
776
776
 
777
- with core.enterMigrationMode():
777
+ async with core.enterMigrationMode():
778
778
  nodes = await core.nodes('[test:int=123 +(foo:beep:boop)> { [test:str=neato] }]')
779
779
  self.len(1, nodes)
780
780
  self.notin('foo', nodes[0].tags)
@@ -834,7 +834,7 @@ class TrigTest(s_t_utils.SynTest):
834
834
  await core.nodes('trigger.add edge:del --verb r* --n2form test:int --query { [ +#del.two ] }')
835
835
  await core.nodes('trigger.add edge:del --verb no** --form test:int --n2form test:str --query { [ +#del.all ] }')
836
836
 
837
- with core.enterMigrationMode():
837
+ async with core.enterMigrationMode():
838
838
  nodes = await core.nodes('test:int=123 | [ -(foo:beep:boop)> { test:str=neato } ]')
839
839
  self.len(1, nodes)
840
840
  self.notin('del.none', nodes[0].tags)
@@ -0,0 +1,126 @@
1
+ import synapse.exc as s_exc
2
+ import synapse.common as s_common
3
+ import synapse.tests.utils as s_t_utils
4
+
5
+ class PlanModelTest(s_t_utils.SynTest):
6
+
7
+ async def test_model_planning(self):
8
+
9
+ async with self.getTestCore() as core:
10
+ nodes = await core.nodes('''
11
+ [ plan:system=*
12
+ :name="Woot CNO Planner"
13
+ :author={[ ps:contact=* :name=visi ]}
14
+ :created=20240202
15
+ :updated=20240203
16
+ :version=1.0.0
17
+ :url=https://vertex.link
18
+ ]
19
+ ''')
20
+ self.len(1, nodes)
21
+ self.eq('woot cno planner', nodes[0].get('name'))
22
+ self.eq(1706832000000, nodes[0].get('created'))
23
+ self.eq(1706918400000, nodes[0].get('updated'))
24
+ self.eq(1099511627776, nodes[0].get('version'))
25
+ self.eq('https://vertex.link', nodes[0].get('url'))
26
+
27
+ self.len(1, await core.nodes('plan:system :author -> ps:contact +:name=visi'))
28
+
29
+ nodes = await core.nodes('''
30
+ [ plan:phase=*
31
+ :system={ plan:system:name="Woot CNO Planner"}
32
+ :title="Recon"
33
+ :summary="Do some recon."
34
+ :index=17
35
+ :url=https://vertex.link/recon
36
+ ]
37
+ ''')
38
+
39
+ self.len(1, nodes)
40
+ self.eq('Recon', nodes[0].get('title'))
41
+ self.eq('Do some recon.', nodes[0].get('summary'))
42
+ self.eq(17, nodes[0].get('index'))
43
+ self.eq('https://vertex.link/recon', nodes[0].get('url'))
44
+
45
+ self.len(1, await core.nodes('plan:phase :system -> plan:system +:name="Woot CNO Planner"'))
46
+
47
+ nodes = await core.nodes('''
48
+ [ plan:procedure=*
49
+ :system={ plan:system:name="Woot CNO Planner"}
50
+ :title="Pwn Some Boxes"
51
+ :summary="Yoink."
52
+ :author={ ps:contact:name=visi }
53
+ :created=20240202
54
+ :updated=20240203
55
+ :version=1.0.0
56
+ :type=cno.offense
57
+ :system={ plan:system:name="Woot CNO Planner" }
58
+ ]
59
+
60
+ $guid = $node.value()
61
+
62
+ [
63
+ :inputs={[ plan:procedure:variable=*
64
+ :name=network
65
+ :type=cidr
66
+ :default=127.0.0.0/24
67
+ :procedure=$guid
68
+ ]}
69
+
70
+ :firststep={[ plan:procedure:step=*
71
+ :title="Are there vulnerable services?"
72
+ :summary="Scan the target network and identify available services."
73
+ :procedure=$guid
74
+ :phase={ plan:phase:title=Recon }
75
+ :outputs={[ plan:procedure:variable=* :name=services ]}
76
+ :techniques={[ ou:technique=* :name=netscan ]}
77
+
78
+ :links={[ plan:procedure:link=*
79
+ :condition=(true)
80
+ :procedure=$guid
81
+ :next={[ plan:procedure:step=*
82
+ :title="Exploit Services"
83
+ :summary="Gank that stuff."
84
+ :procedure=$guid
85
+ :outputs={[ plan:procedure:variable=* :name=shellz ]}
86
+ ]}
87
+
88
+ ]}
89
+ ]}
90
+ ]
91
+ ''')
92
+
93
+ self.len(1, nodes)
94
+ self.eq('Pwn Some Boxes', nodes[0].get('title'))
95
+ self.eq('Yoink.', nodes[0].get('summary'))
96
+ self.nn(nodes[0].get('author'))
97
+ self.eq(1706832000000, nodes[0].get('created'))
98
+ self.eq(1706918400000, nodes[0].get('updated'))
99
+ self.eq(1099511627776, nodes[0].get('version'))
100
+
101
+ self.len(1, await core.nodes('plan:procedure :type -> plan:procedure:type:taxonomy'))
102
+ self.len(1, await core.nodes('plan:procedure :system -> plan:system +:name="Woot CNO Planner"'))
103
+ self.len(1, await core.nodes('plan:procedure :firststep -> plan:procedure:step -> plan:procedure:link'))
104
+
105
+ nodes = await core.nodes('plan:procedure :inputs -> plan:procedure:variable')
106
+ self.len(1, nodes)
107
+ self.eq('network', nodes[0].get('name'))
108
+ self.eq('cidr', nodes[0].get('type'))
109
+ self.eq('127.0.0.0/24', nodes[0].get('default'))
110
+ self.nn(nodes[0].get('procedure'))
111
+
112
+ nodes = await core.nodes('plan:procedure :firststep -> plan:procedure:step')
113
+ self.len(1, nodes)
114
+ self.eq('Are there vulnerable services?', nodes[0].get('title'))
115
+ self.eq('Scan the target network and identify available services.', nodes[0].get('summary'))
116
+ self.nn(nodes[0].get('procedure'))
117
+
118
+ self.len(1, await core.nodes('plan:procedure :firststep -> plan:procedure:step -> plan:phase'))
119
+ self.len(1, await core.nodes('plan:procedure :firststep -> plan:procedure:step :techniques -> ou:technique'))
120
+ self.len(1, await core.nodes('plan:procedure :firststep -> plan:procedure:step :outputs -> plan:procedure:variable'))
121
+
122
+ nodes = await core.nodes('plan:procedure :firststep -> plan:procedure:step -> plan:procedure:link')
123
+ self.len(1, nodes)
124
+ self.eq(True, nodes[0].get('condition'))
125
+ self.nn(nodes[0].get('next'))
126
+ self.nn(nodes[0].get('procedure'))
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: synapse
3
- Version: 2.167.0
3
+ Version: 2.168.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
@@ -2,7 +2,7 @@ synapse/__init__.py,sha256=R2kOXlF5j-8m6G0JkHuN7rXRPg_tHLmbMxr__94mHQk,1145
2
2
  synapse/axon.py,sha256=Hbbb1BqyB8xsb7xkaIMyTQJEE01-r5HXebnoAnw-qEY,61120
3
3
  synapse/cells.py,sha256=eNvdglfAoTURVhGOLGcgMXCGpfsIX1a02SQnyiklo3E,308
4
4
  synapse/common.py,sha256=_-cBBcL88YGAnhVq9WJ5nUKtoq-NytfwbgYzCq02W-Q,35578
5
- synapse/cortex.py,sha256=EXbtZ1zyhGZOyJuitagEpRovOdVyqnlcKTdULTsrgHo,234557
5
+ synapse/cortex.py,sha256=3IIy5N9By4MKAt6rHDzTaQnFGxd3Y1OrN85or0XTpHg,235141
6
6
  synapse/cryotank.py,sha256=kOriVF8LnwYxgyTxQXSepyFRtSu2C6n9t_yImTV7ZNI,11714
7
7
  synapse/daemon.py,sha256=tPPggIATq0O0Cw1J2nzL-JW10VIOFcrvP4XqsKQwozc,16776
8
8
  synapse/datamodel.py,sha256=o4YktPuoprTwjGly-8217dvHzM-sUxTMCPCwByqJCDI,34070
@@ -84,7 +84,7 @@ synapse/data/jsonschemas/raw.githubusercontent.com/oasis-open/cti-stix2-json-sch
84
84
  synapse/data/jsonschemas/raw.githubusercontent.com/oasis-open/cti-stix2-json-schemas/stix2.1/schemas/sros/sighting.json,sha256=f1T3r4CRcJP0743qmAlVCdNvi5ASrOU42PSoiDNlRqc,3575
85
85
  synapse/lib/__init__.py,sha256=qLS7nt8-Iot8jnD2Xss_6wZi5lJoyv2rqxF9kkektT0,129
86
86
  synapse/lib/agenda.py,sha256=WgISI-baosIrg1i5pB0zPL4IWpEb95Y9bUJXaOUDnQs,32724
87
- synapse/lib/aha.py,sha256=gsw9voZUlgDooT6JfUQaQKcUIpZ91s8FFz0FXhMd6wQ,42311
87
+ synapse/lib/aha.py,sha256=fT1Assn7j1YQFSr5IYuW1GNH2G19gSXwV7ajNS3mlLY,42392
88
88
  synapse/lib/ast.py,sha256=fkZ7P8-1yTam_9RTxyK2ze-GNLEvCSFgb7on_AcFMG4,148961
89
89
  synapse/lib/autodoc.py,sha256=CsGaX0tAKGh21YbIvUtvaUnZyqmsx6j-E9QD_vhKSP4,20747
90
90
  synapse/lib/base.py,sha256=sTti-XzyQnoAwq0JvbDrjSu0_GqRT_J2eBxfNV8_ZrI,22520
@@ -114,12 +114,12 @@ synapse/lib/ingest.py,sha256=HNW1xs215c_UXVjKaxjipKBmVL4ujrjmarHBRvLPLkE,40
114
114
  synapse/lib/interval.py,sha256=PqpEhMGG6LD9mJxEms0oQWC-NB01H6gwsmLSc5LrDFk,1175
115
115
  synapse/lib/jsonstor.py,sha256=QQVf7Kl90sI_v97UZZAoa6stizDeMyy0ykR3RsHpmi8,19359
116
116
  synapse/lib/jupyter.py,sha256=EGAE1D-zlv1YVSDrTkr4bNMFsXvZuzBfIo5FhId2xSI,16358
117
- synapse/lib/layer.py,sha256=n1RLwx1g24G9rDEbH3eZg3zk5RVZhb_JAyAjxxwuJTA,144585
117
+ synapse/lib/layer.py,sha256=NYNxt6vYkYZk3h-CeGjk_BYZ0sLKNxSbcqd3YBCJC4E,144655
118
118
  synapse/lib/link.py,sha256=YiiAiFe1HTkEBeAtxKjNzWMH6i73Md93sZ5SKxtZylg,9802
119
119
  synapse/lib/lmdbslab.py,sha256=JlGmBA5tGfRIQmdqNxdh_HwWnT2JyYBBHpRRlQvG98E,54567
120
- synapse/lib/modelrev.py,sha256=0i5h2yEVTyEkW3J-6gQxIoBVJNAPA1SQhtUMpNN8iSM,40766
120
+ synapse/lib/modelrev.py,sha256=otBcP_q_bVgjfVLupFrB66u1I2zF0n0EedEzKkUrfDY,40887
121
121
  synapse/lib/module.py,sha256=0XLFLzuZVmEqulKmdT0uah0oi1t8_f_ghakhqvoKtKI,4686
122
- synapse/lib/modules.py,sha256=cjWjYrPYagyx2Oq2tuuzHHeSc7sSvPLUyW6io5P8ErI,1124
122
+ synapse/lib/modules.py,sha256=thFIZuhHP04ukBg4Xcie96VPiJeN19suBHl02SpF6xg,1166
123
123
  synapse/lib/msgpack.py,sha256=YXI8bTVIpwJWGIjbK8RXxSd-oVgxrcOHCR1tPnh4bRQ,7018
124
124
  synapse/lib/multislabseqn.py,sha256=WxJQm6XNINyGBTUnmSkY4iifxLlR_FZe3geOcT8BxR4,15211
125
125
  synapse/lib/nexus.py,sha256=X3qR8_UlEHlY_X_70uu0a3MMJhZhT8bi3xgJClF27Lk,22325
@@ -145,7 +145,7 @@ synapse/lib/storm_format.py,sha256=IySRTGUbCAsIhULY1VS1vxvAbLYUXMezPlPSCRJX4rU,4
145
145
  synapse/lib/stormctrl.py,sha256=XvyZ6M0Ew8sXsjGvRTWbXh0MjktZrGi_zQ9kNa7AWTE,285
146
146
  synapse/lib/stormhttp.py,sha256=DkpndsFRGsWlDnT5RKknd9a53FVebZGOFVKCqkPcnrQ,26885
147
147
  synapse/lib/stormsvc.py,sha256=c8W1-2tC8Cu6IDHjqObBn8qaKH6vc-7GOR5YCOmuENA,6825
148
- synapse/lib/stormtypes.py,sha256=qjInhOsdmHSoLZGsmRALlZmQ5_GQDraaxi_i7F1zQpc,378273
148
+ synapse/lib/stormtypes.py,sha256=6rJs8cQ3LxYoG1A0zP1QBSDrC2O1KgtdW2MnoA8iCEU,378765
149
149
  synapse/lib/stormwhois.py,sha256=efG4s1_UOShY3YD8N2OLEa_ELOnzsfLaMEMfDCJYeLQ,2275
150
150
  synapse/lib/structlog.py,sha256=qiuD7TTdwCyYEDF2f-88G2iX54SuB-lJ1pqlYokL1r8,1303
151
151
  synapse/lib/task.py,sha256=krDjQvNh0EpAs1PILK8CJJa9DMeM0depI0K8Eimp010,5733
@@ -156,8 +156,8 @@ synapse/lib/time.py,sha256=FKTYwpdvpuAj8p8sSodRjOxoA7Vu67CIbbXz55gtghk,9231
156
156
  synapse/lib/trigger.py,sha256=cqKW0e2KmeiPsU3d3vwpo0PLLHUs6ZPVWZyxAxU6gMA,20849
157
157
  synapse/lib/types.py,sha256=LXpxw4aNKMA0GLs3uG-RpZE5HcZdejMg1g4XJZ9UIfk,67712
158
158
  synapse/lib/urlhelp.py,sha256=j-DvWGi-xH0TcO0NbCuwG7guUuiV8wxIxfMyJOzDygo,2523
159
- synapse/lib/version.py,sha256=DoypNr5-Lv2sEvLSCHKcG5-StOSp2L7ydQYcT0AmBgg,7162
160
- synapse/lib/view.py,sha256=5gCiR7tXYkuKgD_8g_M83XC7ndP2qdzHBiBhtriFB_I,55355
159
+ synapse/lib/version.py,sha256=yU__bTyfUKaRC850Fien8PbWr7Gi8-gYz22RHIj35WY,7162
160
+ synapse/lib/view.py,sha256=Xzx0vt_6x4Sr8IjLAU_Zhyl8nXNYnHjMVyBWNNGU_Pk,55390
161
161
  synapse/lib/crypto/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
162
162
  synapse/lib/crypto/coin.py,sha256=_dhlkzIrHT8BvHdJOWK7PDThz3sK3dDRnWAUqjRpZJc,4910
163
163
  synapse/lib/crypto/ecc.py,sha256=e5XM8fsU3YnkT9u1eNROqOK8ccjp5QirIn7FljC_z1s,6522
@@ -171,7 +171,7 @@ synapse/lib/platforms/freebsd.py,sha256=0lJNc9W5a5TWfsz734o30gtF3vS3BH8QXWvy04pz
171
171
  synapse/lib/platforms/linux.py,sha256=VBUn_tf7PYGgfBXDBBNfE16QBGWstSkuV2l4LXX0dvQ,8002
172
172
  synapse/lib/platforms/windows.py,sha256=YbB73MIoBPvePNYiTYa2xEvpGAotAiEKNl4P--njPPM,2069
173
173
  synapse/lib/stormlib/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
174
- synapse/lib/stormlib/aha.py,sha256=HQMmlcRH4PpkQJkADXpWSfpPP9JGRKy69koUlb9wS9E,19177
174
+ synapse/lib/stormlib/aha.py,sha256=hK8s80AlikSClTeZCoyUtth2qi1H6ZBdAYnNG_5pFFE,19802
175
175
  synapse/lib/stormlib/auth.py,sha256=sMyheJVQGV0Z13qMcvBsgZo6dcb34rgejaqm6z_YJ6g,83421
176
176
  synapse/lib/stormlib/backup.py,sha256=-cR7lR9IRib-e0uMRV1oKVfdJJ3PYbowtwtH0i3mOtY,2846
177
177
  synapse/lib/stormlib/basex.py,sha256=BHnThzA7xv_wBaoxO3sVjjPGgS7K5PMXyGrFFQzmX2Y,2638
@@ -179,7 +179,7 @@ synapse/lib/stormlib/cache.py,sha256=uC7whmdnqaDAcZLTE1AlFQl18RXM_tYUVjpveCDgtz8
179
179
  synapse/lib/stormlib/cell.py,sha256=QqkPnpS7WfC7wDfajFq7b7jmjDBSUz5Dzow1sG8wRMM,12623
180
180
  synapse/lib/stormlib/compression.py,sha256=JgF9JVVrBL_FlxYUD98HAXFwbVSr4XtIxto81HpBPQw,6206
181
181
  synapse/lib/stormlib/cortex.py,sha256=VHsU_krrUDKoy28xJgvYkRqvZ8QmkZMesCFFpVOqc7c,55040
182
- synapse/lib/stormlib/easyperm.py,sha256=D_i7ZB20Ow3mLS6-e5GC5qx3pUuWroFOv-dv9m68iMo,5453
182
+ synapse/lib/stormlib/easyperm.py,sha256=W59IyPFPc34pKxS43C9LvyI5la88o7sZP9UBti2yqNs,5851
183
183
  synapse/lib/stormlib/ethereum.py,sha256=hsgQD4tQpS7mS9lrbghxZF5gEwop4OeeN2Tf3CfncuY,1219
184
184
  synapse/lib/stormlib/gen.py,sha256=2fNXkBPdV1T4Ln7zbIbBeQcUjXLRVsqHF1CWAwxSO-s,27069
185
185
  synapse/lib/stormlib/gis.py,sha256=LUsFcPn0g3Y23lMDpKveegT2SwoOSAwkgmifpXpm23c,1629
@@ -238,6 +238,7 @@ synapse/models/material.py,sha256=d-nonZKyJpHc32ebghtkm5tSifwVFN_ctx2kb8N4NqI,32
238
238
  synapse/models/media.py,sha256=uIsayKqdDM36eGyrJwz2UqOa_QQ9MpMJ2uHdgGYDLa4,3605
239
239
  synapse/models/orgs.py,sha256=QfBvD7NmX51v9k7tmWci7d_PvLRejL96m4nJG9Q3-cY,62484
240
240
  synapse/models/person.py,sha256=w6lihRSU_6wW9UOj_dogR1c7BfMAmUPXb3S9_LKk-zI,26847
241
+ synapse/models/planning.py,sha256=kuBjIvU2juZvOYJ0DxE-JQRNF6ee1il5iKsIBZx3OLQ,7117
241
242
  synapse/models/proj.py,sha256=eYY2bY7H8HJGvmuVQOrn4rQQWZQ_7noKtjLiq3QzgUU,9035
242
243
  synapse/models/risk.py,sha256=kH-FnPj0fhZvC_nEr3RPjiRz6OLYTj_FyTaYXvE9luk,50450
243
244
  synapse/models/science.py,sha256=oSkKbjmVncYcVkVgx8rhM08XtcsgDgjf3mpunz5kL30,4329
@@ -263,7 +264,7 @@ synapse/tests/test_cmds_boss.py,sha256=SdBwM2qJHFzzfrjWYiZOLBKeye8uru7KeJ3NU_YSk
263
264
  synapse/tests/test_cmds_cortex.py,sha256=LWFz8HyuvsIGjtz2DqXYh-R-5QbiQWzLlQKqew7gabY,17157
264
265
  synapse/tests/test_cmds_hive.py,sha256=aRH_Gh8oF_1BsfpmffyhDDNIqnTqsuF2cavdtGke1-0,5912
265
266
  synapse/tests/test_common.py,sha256=Akj1KLWbj7XRjTL_oN2Nt9v9liuGRKu2_3oCrHaMQkE,16415
266
- synapse/tests/test_cortex.py,sha256=vEQ4QUppccwHk9wQj937hw1UG25ViOdM1ZXMv5dUdP0,338204
267
+ synapse/tests/test_cortex.py,sha256=nMota3-F9YutKvHG8af-boCkkjajP7Z94QxrdNQqG1I,338218
267
268
  synapse/tests/test_cryotank.py,sha256=JwEn_roIu4wlfPv34kjyAoJ2cWTrX3jDOr7ZMFUyslQ,12085
268
269
  synapse/tests/test_daemon.py,sha256=srOQ78HaHxCL38mvq5LWzsxgU0yb3UNLgi5KSMGQP8c,5812
269
270
  synapse/tests/test_data.py,sha256=f8L-q6kpMq8XPG3hq1jwlyaFRQEinSBf7ZlsRFeCuoM,196
@@ -272,7 +273,7 @@ synapse/tests/test_exc.py,sha256=j24ddx0PFdwtmgtwsjIvypXxfn4ji3rhAWo9I2sUbSY,172
272
273
  synapse/tests/test_glob.py,sha256=cSNrtEKWLsZXRhsjxQjRjjMqdgqfpl05yT4S53dC0NU,249
273
274
  synapse/tests/test_init.py,sha256=rHqYBVL_aFf1HO6zCF5akHVcHUP2g1kpJLRdTkV0yys,557
274
275
  synapse/tests/test_lib_agenda.py,sha256=PowCWygRdErvjvaQNx80G3zNIqsLMMlrakyJU9XF5nE,37779
275
- synapse/tests/test_lib_aha.py,sha256=uop0hlh1HOskqky3oHAa9vmmtFpPmGVfb6ynC_ZUaDA,68576
276
+ synapse/tests/test_lib_aha.py,sha256=-XbpX1M47afeBH2sI_TxW5YsIZ5WrpynuEkq78Qtj1U,68898
276
277
  synapse/tests/test_lib_ast.py,sha256=bFdcP2al2qgLuY_yTXWNMsZSClv4oJRxj9kOR8KReaE,160358
277
278
  synapse/tests/test_lib_autodoc.py,sha256=H9Yb7cvzXOMPGBIoCCqNClcyIp6zEWcawtfudKbG-2U,6282
278
279
  synapse/tests/test_lib_base.py,sha256=mgqGmjioQaT75r4tWH7QkyqiMFOi_Or02Wo79oAh9z0,14032
@@ -327,7 +328,7 @@ synapse/tests/test_lib_spooled.py,sha256=dC5hba4c0MehALt4qW-cokqJl-tZsIsmABCGMIc
327
328
  synapse/tests/test_lib_storm.py,sha256=u4ILHdQ0wj8l50wN-D4e79h_RezbzGlNCXcQWLcNKb0,202209
328
329
  synapse/tests/test_lib_storm_format.py,sha256=tEZgQMmKAeG8FQZE5HUjOT7bnKawVTpNaVQh_3Wa630,277
329
330
  synapse/tests/test_lib_stormhttp.py,sha256=wk907a1fIADBgETeaiY5HWddIXv-nM3vinCryl5oKxw,36823
330
- synapse/tests/test_lib_stormlib_aha.py,sha256=mVbEmy4o1zmt23tbo9SrSEpE4ZPtK-TRwVVM7YOA1OM,9073
331
+ synapse/tests/test_lib_stormlib_aha.py,sha256=ZlOoBs-55Wm7g3Qu2KueqMNnuamLccllpTnMORKoHoQ,9074
331
332
  synapse/tests/test_lib_stormlib_auth.py,sha256=YkT32btBsuUgMPgd_NlzXSfrHrgHHlmLfRFrZfZvX48,56990
332
333
  synapse/tests/test_lib_stormlib_backup.py,sha256=3ZYE3swQ4A8aYJyVueFXzbekCdoKMC7jsHLoq0hTKGI,1644
333
334
  synapse/tests/test_lib_stormlib_basex.py,sha256=DDOsH3XDR8MdJ1uj5avyqnFqBnlaIu8L5stX61jqKrw,2049
@@ -370,7 +371,7 @@ synapse/tests/test_lib_structlog.py,sha256=DGfzrfc2nybRq5RjwiUXd1v4sC5zl8d46RHgT
370
371
  synapse/tests/test_lib_task.py,sha256=Zby9Evlg_mBwE3_aF7p_5PIMhWp2Er7Y-ye4Y-3L5RQ,1646
371
372
  synapse/tests/test_lib_thishost.py,sha256=O6QCENStRuMjWS7qV9rqwW3bSZwzEUn9NcttKnDqXw8,366
372
373
  synapse/tests/test_lib_time.py,sha256=d1mPkN9P3GHNnZ_mhjyOv64tJGQ0yI_ifUjK3x-kmDg,8891
373
- synapse/tests/test_lib_trigger.py,sha256=dgYyLFHNcnzg2r8ydTva5HskCJAwZUqCM8ug3YQ8UJ4,41241
374
+ synapse/tests/test_lib_trigger.py,sha256=9P14VFnjgup5d_sIrC5l_cBeKuApcejJVJC1hVGsc8o,41259
374
375
  synapse/tests/test_lib_types.py,sha256=oC3uaMwkFOb75TG93gb6bOc0pda_kI2KS-UmYnf4vTU,76735
375
376
  synapse/tests/test_lib_urlhelp.py,sha256=ir59ZRJz5XlhMb-ZBYl_p3GpGfnUBnDRwGlffvPC7IY,3147
376
377
  synapse/tests/test_lib_version.py,sha256=yDczjNi60hXXNZ-pYVntDblGNcekFZU6DdDsjUTkGtM,8164
@@ -398,6 +399,7 @@ synapse/tests/test_model_material.py,sha256=M7ACDCuMtavm-xtwAIZa1M-bHVq5PCUedDfR
398
399
  synapse/tests/test_model_media.py,sha256=RQVhYjOZ4rkNPBSzz05rle1M7F6-Yxw545s7k-YBwzc,2627
399
400
  synapse/tests/test_model_orgs.py,sha256=ITdt6sxW2LVUWRqBcVECzt_6zsdZy3WhBEdYEYzE6XM,39537
400
401
  synapse/tests/test_model_person.py,sha256=pRt9ZA9F11V-5pTsw6M43Ktsh3RnejikJPwPOYogIGo,17068
402
+ synapse/tests/test_model_planning.py,sha256=U2kkE0uBO6CqtTfy7wlnhEIu_NFdSri4I_I5b-mRjBE,5615
401
403
  synapse/tests/test_model_proj.py,sha256=bBPNzvcbd1jZReeJ7X-AQdH7F7ZMugZVgaCTvS-QNFM,22849
402
404
  synapse/tests/test_model_risk.py,sha256=S4JDYlGLcnIG2MryDRMgDcwvMOsQCNGzgOuDG07U1lA,27342
403
405
  synapse/tests/test_model_science.py,sha256=2T9VxdzpltDufgjkUB95q97TQP9AxH2-T_sBbHfPDRk,2450
@@ -562,8 +564,8 @@ synapse/vendor/xrpl/tests/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJW
562
564
  synapse/vendor/xrpl/tests/test_codec.py,sha256=Zwq6A5uZUK_FWDL3BA932c5b-rL3hnC6efobWHSLC4o,6651
563
565
  synapse/vendor/xrpl/tests/test_main.py,sha256=kZQwWk7I6HrP-PMvLdsUUN4POvWD9I-iXDHOwdeF090,4299
564
566
  synapse/vendor/xrpl/tests/test_main_test_cases.py,sha256=vTlUM4hJD2Hd2wCIdd9rfsvcMZZZQmNHWdCTTFeGz2Y,4221
565
- synapse-2.167.0.dist-info/LICENSE,sha256=xllut76FgcGL5zbIRvuRc7aezPbvlMUTWJPsVr2Sugg,11358
566
- synapse-2.167.0.dist-info/METADATA,sha256=cDImy1cTN1MvV5O04LQprMale52840S3rd5vxET1K7o,4921
567
- synapse-2.167.0.dist-info/WHEEL,sha256=d-ss0RGbiSJGQggaPntAAFgCBIav_4d8GZcRrfBnZg4,94
568
- synapse-2.167.0.dist-info/top_level.txt,sha256=v_1YsqjmoSCzCKs7oIhzTNmWtSYoORiBMv1TJkOhx8A,8
569
- synapse-2.167.0.dist-info/RECORD,,
567
+ synapse-2.168.0.dist-info/LICENSE,sha256=xllut76FgcGL5zbIRvuRc7aezPbvlMUTWJPsVr2Sugg,11358
568
+ synapse-2.168.0.dist-info/METADATA,sha256=hpyJSpbWPbvPgMIefUR3jFm1IjtR1Pvg_-9O9oF7VKE,4921
569
+ synapse-2.168.0.dist-info/WHEEL,sha256=d-ss0RGbiSJGQggaPntAAFgCBIav_4d8GZcRrfBnZg4,94
570
+ synapse-2.168.0.dist-info/top_level.txt,sha256=v_1YsqjmoSCzCKs7oIhzTNmWtSYoORiBMv1TJkOhx8A,8
571
+ synapse-2.168.0.dist-info/RECORD,,