synapse 2.205.0__py311-none-any.whl → 2.206.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/axon.py +4 -4
- synapse/cortex.py +14 -1
- synapse/lib/aha.py +13 -8
- synapse/lib/httpapi.py +196 -97
- synapse/lib/lmdbslab.py +2 -0
- synapse/lib/modelrev.py +3 -3
- synapse/lib/schemas.py +11 -0
- synapse/lib/spooled.py +2 -1
- synapse/lib/stormlib/aha.py +5 -1
- synapse/lib/stormlib/model.py +1 -1
- synapse/lib/stormtypes.py +10 -0
- synapse/lib/version.py +2 -2
- synapse/models/base.py +9 -0
- synapse/models/inet.py +9 -1
- synapse/models/infotech.py +5 -0
- synapse/models/telco.py +10 -0
- synapse/tests/test_axon.py +42 -41
- synapse/tests/test_cortex.py +18 -6
- synapse/tests/test_lib_aha.py +17 -0
- synapse/tests/test_lib_cell.py +5 -3
- synapse/tests/test_lib_httpapi.py +225 -33
- synapse/tests/test_lib_lmdbslab.py +30 -0
- synapse/tests/test_lib_modelrev.py +7 -7
- synapse/tests/test_lib_spooled.py +2 -0
- synapse/tests/test_lib_stormlib_aha.py +7 -7
- synapse/tests/test_lib_stormlib_cortex.py +61 -60
- synapse/tests/test_model_infotech.py +2 -0
- synapse/tests/test_model_telco.py +4 -1
- synapse/tools/aha/easycert.py +4 -0
- synapse/tools/aha/mirror.py +6 -4
- {synapse-2.205.0.dist-info → synapse-2.206.0.dist-info}/METADATA +1 -1
- {synapse-2.205.0.dist-info → synapse-2.206.0.dist-info}/RECORD +35 -35
- {synapse-2.205.0.dist-info → synapse-2.206.0.dist-info}/WHEEL +0 -0
- {synapse-2.205.0.dist-info → synapse-2.206.0.dist-info}/licenses/LICENSE +0 -0
- {synapse-2.205.0.dist-info → synapse-2.206.0.dist-info}/top_level.txt +0 -0
synapse/lib/modelrev.py
CHANGED
|
@@ -1455,7 +1455,7 @@ class ModelMigration_0_2_31:
|
|
|
1455
1455
|
|
|
1456
1456
|
# Pick up and classify all bad CPE nodes
|
|
1457
1457
|
for idx, layer in enumerate(self.layers):
|
|
1458
|
-
logger.debug(
|
|
1458
|
+
logger.debug('Classifying nodes in layer %s %s', idx, layer.iden)
|
|
1459
1459
|
|
|
1460
1460
|
async for buid, sode in layer.getStorNodesByForm('it:sec:cpe'):
|
|
1461
1461
|
|
|
@@ -1499,7 +1499,7 @@ class ModelMigration_0_2_31:
|
|
|
1499
1499
|
|
|
1500
1500
|
# Pick up all related CPE node info. The majority of the work happens in this loop
|
|
1501
1501
|
for idx, layer in enumerate(self.layers):
|
|
1502
|
-
logger.debug(
|
|
1502
|
+
logger.debug('Processing nodes in layer %s %s', idx, layer.iden)
|
|
1503
1503
|
|
|
1504
1504
|
for buid, node in self.nodes.items():
|
|
1505
1505
|
await self._loadNode(layer, buid, node=node)
|
|
@@ -1541,7 +1541,7 @@ class ModelMigration_0_2_31:
|
|
|
1541
1541
|
await self.todos.clear()
|
|
1542
1542
|
|
|
1543
1543
|
for idx, layer in enumerate(self.layers):
|
|
1544
|
-
logger.debug(
|
|
1544
|
+
logger.debug('Processing references in layer %s %s', idx, layer.iden)
|
|
1545
1545
|
|
|
1546
1546
|
async for entry in todotmp:
|
|
1547
1547
|
match entry:
|
synapse/lib/schemas.py
CHANGED
|
@@ -1128,3 +1128,14 @@ _reqValidOauth2TokenResponseSchema = {
|
|
|
1128
1128
|
'required': ['access_token', 'expires_in'],
|
|
1129
1129
|
}
|
|
1130
1130
|
reqValidOauth2TokenResponse = s_config.getJsValidator(_reqValidOauth2TokenResponseSchema)
|
|
1131
|
+
|
|
1132
|
+
_httpLoginV1Schema = {
|
|
1133
|
+
'type': 'object',
|
|
1134
|
+
'properties': {
|
|
1135
|
+
'user': {'type': 'string'},
|
|
1136
|
+
'passwd': {'type': 'string'},
|
|
1137
|
+
},
|
|
1138
|
+
'additionalProperties': False,
|
|
1139
|
+
'required': ['user', 'passwd'],
|
|
1140
|
+
}
|
|
1141
|
+
reqValidHttpLoginV1 = s_config.getJsValidator(_httpLoginV1Schema)
|
synapse/lib/spooled.py
CHANGED
|
@@ -8,6 +8,7 @@ import synapse.lib.msgpack as s_msgpack
|
|
|
8
8
|
import synapse.lib.lmdbslab as s_lmdbslab
|
|
9
9
|
|
|
10
10
|
MAX_SPOOL_SIZE = 10000
|
|
11
|
+
DEFAULT_MAPSIZE = s_const.mebibyte * 32
|
|
11
12
|
|
|
12
13
|
class Spooled(s_base.Base):
|
|
13
14
|
'''
|
|
@@ -48,7 +49,7 @@ class Spooled(s_base.Base):
|
|
|
48
49
|
|
|
49
50
|
slabpath = tempfile.mkdtemp(dir=dirn, prefix='spooled_', suffix='.lmdb')
|
|
50
51
|
|
|
51
|
-
self.slab = await s_lmdbslab.Slab.anit(slabpath, map_size=
|
|
52
|
+
self.slab = await s_lmdbslab.Slab.anit(slabpath, map_size=DEFAULT_MAPSIZE)
|
|
52
53
|
if self.cell is not None:
|
|
53
54
|
self.slab.addResizeCallback(self.cell.checkFreeSpace)
|
|
54
55
|
|
synapse/lib/stormlib/aha.py
CHANGED
|
@@ -691,6 +691,7 @@ The ready column indicates that a service has entered into the realtime change w
|
|
|
691
691
|
{"name": "host", "width": 16},
|
|
692
692
|
{"name": "port", "width": 8},
|
|
693
693
|
{"name": "version", "width": 12},
|
|
694
|
+
{"name": "synapse", "width": 12},
|
|
694
695
|
{"name": "nexus idx", "width": 10},
|
|
695
696
|
],
|
|
696
697
|
"separators": {
|
|
@@ -732,6 +733,7 @@ The ready column indicates that a service has entered into the realtime change w
|
|
|
732
733
|
'host': $svcinfo.urlinfo.host,
|
|
733
734
|
'port': $svcinfo.urlinfo.port,
|
|
734
735
|
'version': '<unknown>',
|
|
736
|
+
'synapse_version': '<unknown>',
|
|
735
737
|
'nexs_indx': (0)
|
|
736
738
|
})
|
|
737
739
|
if ($cell_infos.$svcname) {
|
|
@@ -743,7 +745,8 @@ The ready column indicates that a service has entered into the realtime change w
|
|
|
743
745
|
} else {
|
|
744
746
|
$status.role = 'leader'
|
|
745
747
|
}
|
|
746
|
-
$status.version = $info.
|
|
748
|
+
$status.version = $info.cell.verstring
|
|
749
|
+
$status.synapse_version = $info.synapse.verstring
|
|
747
750
|
}
|
|
748
751
|
$group_status.append($status)
|
|
749
752
|
}
|
|
@@ -779,6 +782,7 @@ The ready column indicates that a service has entered into the realtime change w
|
|
|
779
782
|
$status.host,
|
|
780
783
|
$status.port,
|
|
781
784
|
$status.version,
|
|
785
|
+
$status.synapse_version,
|
|
782
786
|
$status.nexs_indx
|
|
783
787
|
)
|
|
784
788
|
$lib.print($printer.row($row))
|
synapse/lib/stormlib/model.py
CHANGED
|
@@ -1181,7 +1181,7 @@ class LibModelMigrations_0_2_31(s_stormtypes.Lib):
|
|
|
1181
1181
|
await self.runt.printf(f' layer: {layriden}')
|
|
1182
1182
|
for iden, refinfo in reflist:
|
|
1183
1183
|
form, prop, *_ = refinfo
|
|
1184
|
-
await self.runt.printf(f' - {form}:{prop} (iden: {iden}')
|
|
1184
|
+
await self.runt.printf(f' - {form}:{prop} (iden: {iden})')
|
|
1185
1185
|
|
|
1186
1186
|
n1edges = node['n1edges']
|
|
1187
1187
|
n2edges = node['n2edges']
|
synapse/lib/stormtypes.py
CHANGED
|
@@ -3933,6 +3933,16 @@ class LibQueue(Lib):
|
|
|
3933
3933
|
'returns': {'type': 'list',
|
|
3934
3934
|
'desc': 'A list of queue definitions the current user is allowed to interact with.', }}},
|
|
3935
3935
|
)
|
|
3936
|
+
_storm_lib_perms = (
|
|
3937
|
+
{'perm': ('queue', 'add'), 'gate': 'cortex',
|
|
3938
|
+
'desc': 'Permits a user to create a named queue.'},
|
|
3939
|
+
{'perm': ('queue', 'get'), 'gate': 'queue',
|
|
3940
|
+
'desc': 'Permits a user to access a queue. This allows the user to read from the queue and remove items from it.'},
|
|
3941
|
+
{'perm': ('queue', 'put'), 'gate': 'queue',
|
|
3942
|
+
'desc': 'Permits a user to put items into a queue.'},
|
|
3943
|
+
{'perm': ('queue', 'del'), 'gate': 'queue',
|
|
3944
|
+
'desc': 'Permits a user to delete a queue.'},
|
|
3945
|
+
)
|
|
3936
3946
|
_storm_lib_path = ('queue',)
|
|
3937
3947
|
|
|
3938
3948
|
def getObjLocals(self):
|
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,
|
|
226
|
+
version = (2, 206, 0)
|
|
227
227
|
verstring = '.'.join([str(x) for x in version])
|
|
228
|
-
commit = '
|
|
228
|
+
commit = '0be7ce9e061b2c752fb454adb50c5267cc14fdfe'
|
synapse/models/base.py
CHANGED
|
@@ -188,6 +188,15 @@ class BaseModule(s_module.CoreModule):
|
|
|
188
188
|
(('meta:ruleset', 'has', 'meta:rule'), {
|
|
189
189
|
'doc': 'The meta:ruleset includes the meta:rule.'}),
|
|
190
190
|
|
|
191
|
+
(('meta:ruleset', 'has', 'inet:service:rule'), {
|
|
192
|
+
'doc': 'The meta:ruleset includes the inet:service:rule.'}),
|
|
193
|
+
|
|
194
|
+
(('meta:ruleset', 'has', 'it:app:snort:rule'), {
|
|
195
|
+
'doc': 'The meta:ruleset includes the it:app:snort:rule.'}),
|
|
196
|
+
|
|
197
|
+
(('meta:ruleset', 'has', 'it:app:yara:rule'), {
|
|
198
|
+
'doc': 'The meta:ruleset includes the it:app:yara:rule.'}),
|
|
199
|
+
|
|
191
200
|
(('meta:rule', 'matches', None), {
|
|
192
201
|
'doc': 'The meta:rule has matched on target node.'}),
|
|
193
202
|
|
synapse/models/inet.py
CHANGED
|
@@ -108,12 +108,20 @@ class Addr(s_types.Str):
|
|
|
108
108
|
s_types.Str.postTypeInit(self)
|
|
109
109
|
self.setNormFunc(str, self._normPyStr)
|
|
110
110
|
|
|
111
|
+
self.defport = self.opts.get('defport', None)
|
|
112
|
+
self.defproto = self.opts.get('defproto', 'tcp')
|
|
113
|
+
|
|
111
114
|
def _getPort(self, valu):
|
|
115
|
+
|
|
112
116
|
parts = valu.split(':', 1)
|
|
113
117
|
if len(parts) == 2:
|
|
114
118
|
valu, port = parts
|
|
115
119
|
port = self.modl.type('inet:port').norm(port)[0]
|
|
116
120
|
return valu, port, f':{port}'
|
|
121
|
+
|
|
122
|
+
if self.defport:
|
|
123
|
+
return valu, self.defport, f':{self.defport}'
|
|
124
|
+
|
|
117
125
|
return valu, None, ''
|
|
118
126
|
|
|
119
127
|
def _normPyStr(self, valu):
|
|
@@ -123,7 +131,7 @@ class Addr(s_types.Str):
|
|
|
123
131
|
# no protos use case sensitivity yet...
|
|
124
132
|
valu = valu.lower()
|
|
125
133
|
|
|
126
|
-
proto =
|
|
134
|
+
proto = self.defproto
|
|
127
135
|
parts = valu.split('://', 1)
|
|
128
136
|
if len(parts) == 2:
|
|
129
137
|
proto, valu = parts
|
synapse/models/infotech.py
CHANGED
|
@@ -1296,6 +1296,11 @@ class ItModule(s_module.CoreModule):
|
|
|
1296
1296
|
('net6', ('inet:net6', {}), {
|
|
1297
1297
|
'doc': 'The optional contiguous IPv6 address range of this network.'}),
|
|
1298
1298
|
|
|
1299
|
+
('dns:resolvers', ('array', {'type': 'inet:server',
|
|
1300
|
+
'typeopts': {'defport': 53, 'defproto': 'udp'},
|
|
1301
|
+
'sorted': True, 'uniq': True}), {
|
|
1302
|
+
'doc': 'An array of DNS servers configured to resolve requests for hosts on the network.'})
|
|
1303
|
+
|
|
1299
1304
|
)),
|
|
1300
1305
|
('it:account', {}, (
|
|
1301
1306
|
('user', ('inet:user', {}), {
|
synapse/models/telco.py
CHANGED
|
@@ -193,6 +193,11 @@ class TelcoModule(s_module.CoreModule):
|
|
|
193
193
|
'doc': 'A mobile cell site which a phone may connect to.'
|
|
194
194
|
}),
|
|
195
195
|
|
|
196
|
+
# TODO - eventually break out ISO-3 country code into a sub
|
|
197
|
+
# https://en.wikipedia.org/wiki/TADIG_code
|
|
198
|
+
('tel:mob:tadig', ('str', {'regex': '^[A-Z0-9]{5}$', 'strip': True}), {
|
|
199
|
+
'doc': 'A Transferred Account Data Interchange Group number issued to a GSM carrier.'}),
|
|
200
|
+
|
|
196
201
|
),
|
|
197
202
|
|
|
198
203
|
'forms': (
|
|
@@ -322,6 +327,9 @@ class TelcoModule(s_module.CoreModule):
|
|
|
322
327
|
('loc', ('loc', {}), {
|
|
323
328
|
'doc': 'Location the carrier operates from.'
|
|
324
329
|
}),
|
|
330
|
+
|
|
331
|
+
('tadig', ('tel:mob:tadig', {}), {
|
|
332
|
+
'doc': 'The TADIG code issued to the carrier.'}),
|
|
325
333
|
)),
|
|
326
334
|
('tel:mob:cell', {}, (
|
|
327
335
|
('carrier', ('tel:mob:carrier', {}), {'doc': 'Mobile carrier.', 'ro': True, }),
|
|
@@ -340,6 +348,8 @@ class TelcoModule(s_module.CoreModule):
|
|
|
340
348
|
'doc': 'The place associated with the latlong property.'}),
|
|
341
349
|
)),
|
|
342
350
|
|
|
351
|
+
('tel:mob:tadig', {}, ()),
|
|
352
|
+
|
|
343
353
|
('tel:mob:telem', {}, (
|
|
344
354
|
|
|
345
355
|
('time', ('time', {}), {}),
|
synapse/tests/test_axon.py
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import io
|
|
2
2
|
import os
|
|
3
3
|
import csv
|
|
4
|
-
import
|
|
4
|
+
import http
|
|
5
5
|
import base64
|
|
6
6
|
import shutil
|
|
7
7
|
import struct
|
|
@@ -573,14 +573,14 @@ bar baz",vv
|
|
|
573
573
|
# No auth - coverage
|
|
574
574
|
async with self.getHttpSess() as sess:
|
|
575
575
|
async with sess.get(f'{url_dl}/foobar') as resp:
|
|
576
|
-
self.eq(
|
|
576
|
+
self.eq(resp.status, http.HTTPStatus.UNAUTHORIZED)
|
|
577
577
|
info = await resp.json()
|
|
578
578
|
self.eq('NotAuthenticated', info.get('code'))
|
|
579
579
|
async with sess.head(f'{url_dl}/foobar') as resp:
|
|
580
|
-
self.eq(
|
|
580
|
+
self.eq(resp.status, http.HTTPStatus.UNAUTHORIZED)
|
|
581
581
|
# aiohttp ignores HEAD bodies
|
|
582
582
|
async with sess.delete(f'{url_dl}/foobar') as resp:
|
|
583
|
-
self.eq(
|
|
583
|
+
self.eq(resp.status, http.HTTPStatus.UNAUTHORIZED)
|
|
584
584
|
info = await resp.json()
|
|
585
585
|
self.eq('NotAuthenticated', info.get('code'))
|
|
586
586
|
|
|
@@ -588,31 +588,31 @@ bar baz",vv
|
|
|
588
588
|
async with self.getHttpSess(auth=('newb', 'secret'), port=port) as sess:
|
|
589
589
|
|
|
590
590
|
async with sess.get(f'{url_dl}/{asdfhash_h}') as resp:
|
|
591
|
-
self.eq(
|
|
591
|
+
self.eq(resp.status, http.HTTPStatus.FORBIDDEN)
|
|
592
592
|
item = await resp.json()
|
|
593
593
|
self.eq('err', item.get('status'))
|
|
594
594
|
|
|
595
595
|
async with sess.delete(f'{url_dl}/{asdfhash_h}') as resp:
|
|
596
|
-
self.eq(
|
|
596
|
+
self.eq(resp.status, http.HTTPStatus.FORBIDDEN)
|
|
597
597
|
item = await resp.json()
|
|
598
598
|
self.eq('err', item.get('status'))
|
|
599
599
|
|
|
600
600
|
async with sess.get(f'{url_hs}/{asdfhash_h}') as resp:
|
|
601
|
-
self.eq(
|
|
601
|
+
self.eq(resp.status, http.HTTPStatus.FORBIDDEN)
|
|
602
602
|
item = await resp.json()
|
|
603
603
|
self.eq('err', item.get('status'))
|
|
604
604
|
|
|
605
605
|
async with sess.head(f'{url_dl}/{asdfhash_h}') as resp:
|
|
606
|
-
self.eq(
|
|
606
|
+
self.eq(resp.status, http.HTTPStatus.FORBIDDEN)
|
|
607
607
|
item = await resp.json()
|
|
608
608
|
|
|
609
609
|
async with sess.post(url_de) as resp:
|
|
610
|
-
self.eq(
|
|
610
|
+
self.eq(resp.status, http.HTTPStatus.FORBIDDEN)
|
|
611
611
|
item = await resp.json()
|
|
612
612
|
self.eq('err', item.get('status'))
|
|
613
613
|
|
|
614
614
|
async with sess.post(url_ul, data=abuf) as resp:
|
|
615
|
-
self.eq(
|
|
615
|
+
self.eq(resp.status, http.HTTPStatus.FORBIDDEN)
|
|
616
616
|
item = await resp.json()
|
|
617
617
|
self.eq('err', item.get('status'))
|
|
618
618
|
|
|
@@ -631,27 +631,27 @@ bar baz",vv
|
|
|
631
631
|
# Basic
|
|
632
632
|
async with self.getHttpSess(auth=('newb', 'secret'), port=port) as sess:
|
|
633
633
|
async with sess.get(f'{url_dl}/foobar') as resp:
|
|
634
|
-
self.eq(
|
|
634
|
+
self.eq(resp.status, http.HTTPStatus.NOT_FOUND)
|
|
635
635
|
info = await resp.json()
|
|
636
636
|
self.eq('err', info.get('status'))
|
|
637
637
|
self.eq('BadArg', info.get('code'))
|
|
638
638
|
self.eq('Hash is not a SHA-256: foobar', info.get('mesg'))
|
|
639
639
|
|
|
640
640
|
async with sess.get(f'{url_dl}/{asdfhash_h}') as resp:
|
|
641
|
-
self.eq(
|
|
641
|
+
self.eq(resp.status, http.HTTPStatus.NOT_FOUND)
|
|
642
642
|
info = await resp.json()
|
|
643
643
|
self.eq('err', info.get('status'))
|
|
644
644
|
self.eq('NoSuchFile', info.get('code'))
|
|
645
645
|
self.eq(f'SHA-256 not found: {asdfhash_h}', info.get('mesg'))
|
|
646
646
|
|
|
647
647
|
async with sess.get(f'{url_hs}/{asdfhash_h}') as resp:
|
|
648
|
-
self.eq(
|
|
648
|
+
self.eq(resp.status, http.HTTPStatus.OK)
|
|
649
649
|
item = await resp.json()
|
|
650
650
|
self.eq('ok', item.get('status'))
|
|
651
651
|
self.false(item.get('result'))
|
|
652
652
|
|
|
653
653
|
async with sess.post(url_ul, data=abuf) as resp:
|
|
654
|
-
self.eq(
|
|
654
|
+
self.eq(resp.status, http.HTTPStatus.OK)
|
|
655
655
|
item = await resp.json()
|
|
656
656
|
self.eq('ok', item.get('status'))
|
|
657
657
|
result = item.get('result')
|
|
@@ -661,13 +661,13 @@ bar baz",vv
|
|
|
661
661
|
self.true(await realaxon.has(asdfhash))
|
|
662
662
|
|
|
663
663
|
async with sess.get(f'{url_hs}/{asdfhash_h}') as resp:
|
|
664
|
-
self.eq(
|
|
664
|
+
self.eq(resp.status, http.HTTPStatus.OK)
|
|
665
665
|
item = await resp.json()
|
|
666
666
|
self.eq('ok', item.get('status'))
|
|
667
667
|
self.true(item.get('result'))
|
|
668
668
|
|
|
669
669
|
async with sess.put(url_ul, data=abuf) as resp:
|
|
670
|
-
self.eq(
|
|
670
|
+
self.eq(resp.status, http.HTTPStatus.OK)
|
|
671
671
|
item = await resp.json()
|
|
672
672
|
self.eq('ok', item.get('status'))
|
|
673
673
|
result = item.get('result')
|
|
@@ -676,14 +676,14 @@ bar baz",vv
|
|
|
676
676
|
self.true(await realaxon.has(asdfhash))
|
|
677
677
|
|
|
678
678
|
async with sess.get(f'{url_dl}/{asdfhash_h}') as resp:
|
|
679
|
-
self.eq(
|
|
679
|
+
self.eq(resp.status, http.HTTPStatus.OK)
|
|
680
680
|
self.eq(abuf, await resp.read())
|
|
681
681
|
|
|
682
682
|
# Streaming upload
|
|
683
683
|
byts = io.BytesIO(bbuf)
|
|
684
684
|
|
|
685
685
|
async with sess.post(url_ul, data=byts) as resp:
|
|
686
|
-
self.eq(
|
|
686
|
+
self.eq(resp.status, http.HTTPStatus.OK)
|
|
687
687
|
item = await resp.json()
|
|
688
688
|
self.eq('ok', item.get('status'))
|
|
689
689
|
result = item.get('result')
|
|
@@ -694,7 +694,7 @@ bar baz",vv
|
|
|
694
694
|
byts = io.BytesIO(bbuf)
|
|
695
695
|
|
|
696
696
|
async with sess.put(url_ul, data=byts) as resp:
|
|
697
|
-
self.eq(
|
|
697
|
+
self.eq(resp.status, http.HTTPStatus.OK)
|
|
698
698
|
item = await resp.json()
|
|
699
699
|
self.eq('ok', item.get('status'))
|
|
700
700
|
result = item.get('result')
|
|
@@ -705,7 +705,7 @@ bar baz",vv
|
|
|
705
705
|
byts = io.BytesIO(b'')
|
|
706
706
|
|
|
707
707
|
async with sess.post(url_ul, data=byts) as resp:
|
|
708
|
-
self.eq(
|
|
708
|
+
self.eq(resp.status, http.HTTPStatus.OK)
|
|
709
709
|
item = await resp.json()
|
|
710
710
|
self.eq('ok', item.get('status'))
|
|
711
711
|
result = item.get('result')
|
|
@@ -715,7 +715,7 @@ bar baz",vv
|
|
|
715
715
|
|
|
716
716
|
# Streaming download
|
|
717
717
|
async with sess.get(f'{url_dl}/{bbufhash_h}') as resp:
|
|
718
|
-
self.eq(
|
|
718
|
+
self.eq(resp.status, http.HTTPStatus.OK)
|
|
719
719
|
|
|
720
720
|
byts = []
|
|
721
721
|
async for bytz in resp.content.iter_chunked(1024):
|
|
@@ -726,44 +726,44 @@ bar baz",vv
|
|
|
726
726
|
|
|
727
727
|
# HEAD
|
|
728
728
|
async with sess.head(f'{url_dl}/{bbufhash_h}') as resp:
|
|
729
|
-
self.eq(
|
|
729
|
+
self.eq(resp.status, http.HTTPStatus.OK)
|
|
730
730
|
self.eq('33554437', resp.headers.get('content-length'))
|
|
731
731
|
self.none(resp.headers.get('content-range'))
|
|
732
732
|
|
|
733
733
|
async with sess.head(f'{url_dl}/foobar') as resp:
|
|
734
|
-
self.eq(
|
|
734
|
+
self.eq(resp.status, http.HTTPStatus.NOT_FOUND)
|
|
735
735
|
self.eq('0', resp.headers.get('content-length'))
|
|
736
736
|
|
|
737
737
|
# DELETE method by sha256
|
|
738
738
|
async with sess.delete(f'{url_dl}/foobar') as resp:
|
|
739
|
-
self.eq(
|
|
739
|
+
self.eq(resp.status, http.HTTPStatus.NOT_FOUND)
|
|
740
740
|
info = await resp.json()
|
|
741
741
|
self.eq('err', info.get('status'))
|
|
742
742
|
self.eq('BadArg', info.get('code'))
|
|
743
743
|
self.eq('Hash is not a SHA-256: foobar', info.get('mesg'))
|
|
744
744
|
|
|
745
745
|
async with sess.delete(f'{url_dl}/{asdfhash_h}') as resp:
|
|
746
|
-
self.eq(
|
|
746
|
+
self.eq(resp.status, http.HTTPStatus.OK)
|
|
747
747
|
item = await resp.json()
|
|
748
748
|
self.eq('ok', item.get('status'))
|
|
749
749
|
self.true(item.get('result'))
|
|
750
750
|
|
|
751
751
|
async with sess.delete(f'{url_dl}/{asdfhash_h}') as resp:
|
|
752
|
-
self.eq(
|
|
752
|
+
self.eq(resp.status, http.HTTPStatus.NOT_FOUND)
|
|
753
753
|
item = await resp.json()
|
|
754
754
|
self.eq('err', item.get('status'))
|
|
755
755
|
|
|
756
756
|
# test /api/v1/axon/file/del API
|
|
757
757
|
data = {'sha256s': (asdfhash_h, asdfhash_h)}
|
|
758
758
|
async with sess.post(url_de, json=data) as resp:
|
|
759
|
-
self.eq(
|
|
759
|
+
self.eq(resp.status, http.HTTPStatus.OK)
|
|
760
760
|
item = await resp.json()
|
|
761
761
|
self.eq('ok', item.get('status'))
|
|
762
762
|
self.eq(((asdfhash_h, False), (asdfhash_h, False)), item.get('result'))
|
|
763
763
|
|
|
764
764
|
data = {'newp': 'newp'}
|
|
765
765
|
async with sess.post(url_de, json=data) as resp:
|
|
766
|
-
self.eq(
|
|
766
|
+
self.eq(resp.status, http.HTTPStatus.BAD_REQUEST)
|
|
767
767
|
item = await resp.json()
|
|
768
768
|
self.eq('err', item.get('status'))
|
|
769
769
|
self.eq('SchemaViolation', item.get('code'))
|
|
@@ -783,7 +783,7 @@ bar baz",vv
|
|
|
783
783
|
|
|
784
784
|
headers = {'range': 'bytes=2-4'}
|
|
785
785
|
async with sess.get(f'{url_dl}/{shatext}', headers=headers) as resp:
|
|
786
|
-
self.eq(
|
|
786
|
+
self.eq(resp.status, http.HTTPStatus.PARTIAL_CONTENT)
|
|
787
787
|
self.eq('3', resp.headers.get('content-length'))
|
|
788
788
|
self.eq('bytes 2-4/12', resp.headers.get('content-range'))
|
|
789
789
|
buf = b''
|
|
@@ -793,7 +793,7 @@ bar baz",vv
|
|
|
793
793
|
|
|
794
794
|
headers = {'range': 'bytes=,2-'}
|
|
795
795
|
async with sess.get(f'{url_dl}/{shatext}', headers=headers) as resp:
|
|
796
|
-
self.eq(
|
|
796
|
+
self.eq(resp.status, http.HTTPStatus.PARTIAL_CONTENT)
|
|
797
797
|
self.eq('10', resp.headers.get('content-length'))
|
|
798
798
|
self.eq('bytes 2-11/12', resp.headers.get('content-range'))
|
|
799
799
|
buf = b''
|
|
@@ -803,7 +803,7 @@ bar baz",vv
|
|
|
803
803
|
|
|
804
804
|
headers = {'range': 'bytes=0-11'}
|
|
805
805
|
async with sess.get(f'{url_dl}/{shatext}', headers=headers) as resp:
|
|
806
|
-
self.eq(
|
|
806
|
+
self.eq(resp.status, http.HTTPStatus.PARTIAL_CONTENT)
|
|
807
807
|
self.eq('12', resp.headers.get('content-length'))
|
|
808
808
|
self.eq('bytes 0-11/12', resp.headers.get('content-range'))
|
|
809
809
|
buf = b''
|
|
@@ -813,7 +813,7 @@ bar baz",vv
|
|
|
813
813
|
|
|
814
814
|
headers = {'range': 'bytes=10-11'}
|
|
815
815
|
async with sess.get(f'{url_dl}/{shatext}', headers=headers) as resp:
|
|
816
|
-
self.eq(
|
|
816
|
+
self.eq(resp.status, http.HTTPStatus.PARTIAL_CONTENT)
|
|
817
817
|
self.eq('2', resp.headers.get('content-length'))
|
|
818
818
|
self.eq('bytes 10-11/12', resp.headers.get('content-range'))
|
|
819
819
|
buf = b''
|
|
@@ -823,7 +823,7 @@ bar baz",vv
|
|
|
823
823
|
|
|
824
824
|
headers = {'range': 'bytes=11-11'}
|
|
825
825
|
async with sess.get(f'{url_dl}/{shatext}', headers=headers) as resp:
|
|
826
|
-
self.eq(
|
|
826
|
+
self.eq(resp.status, http.HTTPStatus.PARTIAL_CONTENT)
|
|
827
827
|
self.eq('1', resp.headers.get('content-length'))
|
|
828
828
|
self.eq('bytes 11-11/12', resp.headers.get('content-range'))
|
|
829
829
|
buf = b''
|
|
@@ -833,7 +833,7 @@ bar baz",vv
|
|
|
833
833
|
|
|
834
834
|
headers = {'range': 'bytes=2-4,8-11'}
|
|
835
835
|
async with sess.get(f'{url_dl}/{shatext}', headers=headers) as resp:
|
|
836
|
-
self.eq(
|
|
836
|
+
self.eq(resp.status, http.HTTPStatus.PARTIAL_CONTENT)
|
|
837
837
|
self.eq('3', resp.headers.get('content-length'))
|
|
838
838
|
self.eq('bytes 2-4/12', resp.headers.get('content-range'))
|
|
839
839
|
buf = b''
|
|
@@ -844,39 +844,40 @@ bar baz",vv
|
|
|
844
844
|
# HEAD tests
|
|
845
845
|
headers = {'range': 'bytes=2-4'}
|
|
846
846
|
async with sess.head(f'{url_dl}/{shatext}', headers=headers) as resp:
|
|
847
|
-
self.eq(
|
|
847
|
+
self.eq(resp.status, http.HTTPStatus.PARTIAL_CONTENT)
|
|
848
848
|
self.eq('3', resp.headers.get('content-length'))
|
|
849
849
|
self.eq('bytes 2-4/12', resp.headers.get('content-range'))
|
|
850
850
|
|
|
851
851
|
headers = {'range': 'bytes=10-11'}
|
|
852
852
|
async with sess.head(f'{url_dl}/{shatext}', headers=headers) as resp:
|
|
853
|
-
self.eq(
|
|
853
|
+
self.eq(resp.status, http.HTTPStatus.PARTIAL_CONTENT)
|
|
854
854
|
self.eq('2', resp.headers.get('content-length'))
|
|
855
855
|
self.eq('bytes 10-11/12', resp.headers.get('content-range'))
|
|
856
856
|
|
|
857
857
|
headers = {'range': 'bytes=11-11'}
|
|
858
858
|
async with sess.head(f'{url_dl}/{shatext}', headers=headers) as resp:
|
|
859
|
-
self.eq(
|
|
859
|
+
self.eq(resp.status, http.HTTPStatus.PARTIAL_CONTENT)
|
|
860
860
|
self.eq('1', resp.headers.get('content-length'))
|
|
861
861
|
self.eq('bytes 11-11/12', resp.headers.get('content-range'))
|
|
862
862
|
|
|
863
|
+
# TODO - In python 3.13+ this can be HTTPStatus.RANGE_NOT_SATISFIABLE
|
|
863
864
|
# Reading past blobsize isn't valid HTTP
|
|
864
865
|
headers = {'range': 'bytes=10-20'}
|
|
865
866
|
async with sess.head(f'{url_dl}/{shatext}', headers=headers) as resp:
|
|
866
|
-
self.eq(
|
|
867
|
+
self.eq(resp.status, http.HTTPStatus.REQUESTED_RANGE_NOT_SATISFIABLE)
|
|
867
868
|
|
|
868
869
|
headers = {'range': 'bytes=11-12'}
|
|
869
870
|
async with sess.head(f'{url_dl}/{shatext}', headers=headers) as resp:
|
|
870
|
-
self.eq(
|
|
871
|
+
self.eq(resp.status, http.HTTPStatus.REQUESTED_RANGE_NOT_SATISFIABLE)
|
|
871
872
|
|
|
872
873
|
headers = {'range': 'bytes=20-40'}
|
|
873
874
|
async with sess.head(f'{url_dl}/{shatext}', headers=headers) as resp:
|
|
874
|
-
self.eq(
|
|
875
|
+
self.eq(resp.status, http.HTTPStatus.REQUESTED_RANGE_NOT_SATISFIABLE)
|
|
875
876
|
|
|
876
877
|
# Negative size
|
|
877
878
|
headers = {'range': 'bytes=20-4'}
|
|
878
879
|
async with sess.head(f'{url_dl}/{shatext}', headers=headers) as resp:
|
|
879
|
-
self.eq(
|
|
880
|
+
self.eq(resp.status, http.HTTPStatus.REQUESTED_RANGE_NOT_SATISFIABLE)
|
|
880
881
|
|
|
881
882
|
async def test_axon_perms(self):
|
|
882
883
|
async with self.getTestAxon() as axon:
|
synapse/tests/test_cortex.py
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import os
|
|
2
2
|
import copy
|
|
3
|
+
import http
|
|
3
4
|
import time
|
|
4
5
|
import asyncio
|
|
5
6
|
import hashlib
|
|
@@ -83,6 +84,12 @@ class CortexTest(s_t_utils.SynTest):
|
|
|
83
84
|
|
|
84
85
|
await core.nodes('[ inet:ipv4=1.2.3.4 :asn=99 .seen=now +#foo:score=10 ]')
|
|
85
86
|
|
|
87
|
+
conf = {'modules': [('NewpModule', {})]}
|
|
88
|
+
warn = '''"'modules' Cortex config value" is deprecated'''
|
|
89
|
+
with self.assertWarnsRegex(DeprecationWarning, warn) as cm:
|
|
90
|
+
async with self.getTestCore(dirn=dirn, conf=conf) as core:
|
|
91
|
+
pass
|
|
92
|
+
|
|
86
93
|
async def test_cortex_cellguid(self):
|
|
87
94
|
iden = s_common.guid()
|
|
88
95
|
conf = {'cell:guid': iden}
|
|
@@ -1178,11 +1185,11 @@ class CortexTest(s_t_utils.SynTest):
|
|
|
1178
1185
|
async with self.getHttpSess(port=port, auth=('visi', 'secret')) as sess:
|
|
1179
1186
|
body = {'query': 'return(asdf)', 'opts': {'user': core.auth.rootuser.iden}}
|
|
1180
1187
|
async with sess.get(f'https://localhost:{port}/api/v1/storm/call', json=body) as resp:
|
|
1181
|
-
self.eq(resp.status,
|
|
1188
|
+
self.eq(resp.status, http.HTTPStatus.FORBIDDEN)
|
|
1182
1189
|
|
|
1183
1190
|
async with self.getHttpSess(port=port) as sess:
|
|
1184
1191
|
resp = await sess.post(f'https://localhost:{port}/api/v1/storm/call')
|
|
1185
|
-
self.eq(
|
|
1192
|
+
self.eq(resp.status, http.HTTPStatus.UNAUTHORIZED)
|
|
1186
1193
|
|
|
1187
1194
|
async with self.getHttpSess() as sess:
|
|
1188
1195
|
async with sess.post(f'https://localhost:{port}/api/v1/login',
|
|
@@ -1193,12 +1200,14 @@ class CortexTest(s_t_utils.SynTest):
|
|
|
1193
1200
|
|
|
1194
1201
|
body = {'query': 'return (asdf)'}
|
|
1195
1202
|
async with sess.get(f'https://localhost:{port}/api/v1/storm/call', json=body) as resp:
|
|
1203
|
+
self.eq(resp.status, http.HTTPStatus.OK)
|
|
1196
1204
|
retn = await resp.json()
|
|
1197
1205
|
self.eq('ok', retn.get('status'))
|
|
1198
1206
|
self.eq('asdf', retn['result'])
|
|
1199
1207
|
|
|
1200
1208
|
body = {'query': '$foo=() $bar=$foo.index(10) return ( $bar )'}
|
|
1201
1209
|
async with sess.get(f'https://localhost:{port}/api/v1/storm/call', json=body) as resp:
|
|
1210
|
+
self.eq(resp.status, http.HTTPStatus.BAD_REQUEST)
|
|
1202
1211
|
retn = await resp.json()
|
|
1203
1212
|
self.eq('err', retn.get('status'))
|
|
1204
1213
|
self.eq('StormRuntimeError', retn.get('code'))
|
|
@@ -1206,6 +1215,7 @@ class CortexTest(s_t_utils.SynTest):
|
|
|
1206
1215
|
|
|
1207
1216
|
body = {'query': 'return ( $lib.exit() )'}
|
|
1208
1217
|
async with sess.post(f'https://localhost:{port}/api/v1/storm/call', json=body) as resp:
|
|
1218
|
+
self.eq(resp.status, http.HTTPStatus.BAD_REQUEST)
|
|
1209
1219
|
retn = await resp.json()
|
|
1210
1220
|
self.eq('err', retn.get('status'))
|
|
1211
1221
|
self.eq('StormExit', retn.get('code'))
|
|
@@ -1214,6 +1224,7 @@ class CortexTest(s_t_utils.SynTest):
|
|
|
1214
1224
|
# No body
|
|
1215
1225
|
async with sess.get(f'https://localhost:{port}/api/v1/storm/call') as resp:
|
|
1216
1226
|
retn = await resp.json()
|
|
1227
|
+
self.eq(resp.status, http.HTTPStatus.BAD_REQUEST)
|
|
1217
1228
|
self.eq('err', retn.get('status'))
|
|
1218
1229
|
self.eq('SchemaViolation', retn.get('code'))
|
|
1219
1230
|
|
|
@@ -7402,18 +7413,17 @@ class CortexBasicTest(s_t_utils.SynTest):
|
|
|
7402
7413
|
|
|
7403
7414
|
async with self.getHttpSess(port=port) as sess:
|
|
7404
7415
|
resp = await sess.post(f'https://localhost:{port}/api/v1/storm/export')
|
|
7405
|
-
self.eq(
|
|
7416
|
+
self.eq(resp.status, http.HTTPStatus.UNAUTHORIZED)
|
|
7406
7417
|
|
|
7407
7418
|
async with self.getHttpSess(port=port, auth=('visi', 'secret')) as sess:
|
|
7408
7419
|
body = {'query': 'inet:ipv4', 'opts': {'user': core.auth.rootuser.iden}}
|
|
7409
7420
|
async with sess.get(f'https://localhost:{port}/api/v1/storm/export', json=body) as resp:
|
|
7410
|
-
self.eq(resp.status,
|
|
7421
|
+
self.eq(resp.status, http.HTTPStatus.FORBIDDEN)
|
|
7411
7422
|
|
|
7412
7423
|
async with self.getHttpSess(port=port, auth=('root', 'secret')) as sess:
|
|
7413
7424
|
|
|
7414
7425
|
resp = await sess.post(f'https://localhost:{port}/api/v1/storm/export')
|
|
7415
|
-
self.eq(
|
|
7416
|
-
|
|
7426
|
+
self.eq(resp.status, http.HTTPStatus.BAD_REQUEST)
|
|
7417
7427
|
reply = await resp.json()
|
|
7418
7428
|
self.eq('err', reply.get('status'))
|
|
7419
7429
|
self.eq('SchemaViolation', reply.get('code'))
|
|
@@ -7423,6 +7433,7 @@ class CortexBasicTest(s_t_utils.SynTest):
|
|
|
7423
7433
|
'opts': {'scrub': {'include': {'tags': ('visi',)}}},
|
|
7424
7434
|
}
|
|
7425
7435
|
resp = await sess.post(f'https://localhost:{port}/api/v1/storm/export', json=body)
|
|
7436
|
+
self.eq(resp.status, http.HTTPStatus.OK)
|
|
7426
7437
|
byts = await resp.read()
|
|
7427
7438
|
|
|
7428
7439
|
podes = [i[1] for i in s_msgpack.Unpk().feed(byts)]
|
|
@@ -7440,6 +7451,7 @@ class CortexBasicTest(s_t_utils.SynTest):
|
|
|
7440
7451
|
body = {'query': 'inet:ipv4=asdfasdf'}
|
|
7441
7452
|
resp = await sess.post(f'https://localhost:{port}/api/v1/storm/export', json=body)
|
|
7442
7453
|
retval = await resp.json()
|
|
7454
|
+
self.eq(resp.status, http.HTTPStatus.BAD_REQUEST)
|
|
7443
7455
|
self.eq('err', retval['status'])
|
|
7444
7456
|
self.eq('BadTypeValu', retval['code'])
|
|
7445
7457
|
|