synapse 2.177.0__py311-none-any.whl → 2.179.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 +170 -31
- synapse/datamodel.py +47 -1
- synapse/exc.py +1 -0
- synapse/lib/aha.py +362 -88
- synapse/lib/ast.py +26 -22
- synapse/lib/base.py +39 -12
- synapse/lib/cell.py +315 -119
- synapse/lib/config.py +15 -11
- synapse/lib/coro.py +27 -0
- synapse/lib/drive.py +551 -0
- synapse/lib/layer.py +0 -5
- synapse/lib/link.py +1 -1
- synapse/lib/lmdbslab.py +3 -3
- synapse/lib/nexus.py +24 -12
- synapse/lib/schemas.py +39 -0
- synapse/lib/snap.py +17 -7
- synapse/lib/storm.py +3 -1
- synapse/lib/stormhttp.py +1 -0
- synapse/lib/stormlib/imap.py +6 -2
- synapse/lib/stormlib/modelext.py +29 -3
- synapse/lib/stormlib/smtp.py +12 -2
- synapse/lib/stormlib/stix.py +40 -17
- synapse/lib/stormlib/vault.py +2 -2
- synapse/lib/stormtypes.py +1 -1
- synapse/lib/types.py +9 -0
- synapse/lib/version.py +2 -2
- synapse/lookup/pe.py +303 -38
- synapse/models/dns.py +24 -1
- synapse/models/geospace.py +4 -1
- synapse/models/infotech.py +26 -1
- synapse/telepath.py +32 -17
- synapse/tests/files/aha/certs/cas/synapse.crt +28 -0
- synapse/tests/files/aha/certs/cas/synapse.key +51 -0
- synapse/tests/files/aha/certs/hosts/00.aha.loop.vertex.link.crt +30 -0
- synapse/tests/files/aha/certs/hosts/00.aha.loop.vertex.link.key +51 -0
- synapse/tests/files/aha/certs/users/root@synapse.crt +29 -0
- synapse/tests/files/aha/certs/users/root@synapse.key +51 -0
- synapse/tests/files/rstorm/testsvc.py +1 -1
- synapse/tests/test_axon.py +1 -1
- synapse/tests/test_cortex.py +67 -60
- synapse/tests/test_lib_agenda.py +3 -3
- synapse/tests/test_lib_aha.py +353 -490
- synapse/tests/test_lib_base.py +20 -0
- synapse/tests/test_lib_cell.py +273 -22
- synapse/tests/test_lib_config.py +4 -3
- synapse/tests/test_lib_coro.py +12 -0
- synapse/tests/test_lib_nexus.py +8 -0
- synapse/tests/test_lib_stormhttp.py +40 -0
- synapse/tests/test_lib_stormlib_aha.py +35 -35
- synapse/tests/test_lib_stormlib_cell.py +4 -15
- synapse/tests/test_lib_stormlib_imap.py +14 -3
- synapse/tests/test_lib_stormlib_modelext.py +55 -3
- synapse/tests/test_lib_stormlib_smtp.py +51 -0
- synapse/tests/test_lib_stormlib_stix.py +15 -0
- synapse/tests/test_lib_stormlib_vault.py +11 -1
- synapse/tests/test_lib_stormtypes.py +5 -0
- synapse/tests/test_lib_types.py +9 -0
- synapse/tests/test_model_dns.py +8 -0
- synapse/tests/test_model_geospace.py +3 -1
- synapse/tests/test_model_infotech.py +47 -0
- synapse/tests/test_model_syn.py +11 -0
- synapse/tests/test_tools_aha.py +78 -101
- synapse/tests/test_utils_stormcov.py +1 -1
- synapse/tests/utils.py +86 -120
- synapse/tools/aha/clone.py +50 -0
- synapse/tools/aha/enroll.py +2 -1
- synapse/tools/backup.py +2 -2
- synapse/tools/changelog.py +31 -1
- {synapse-2.177.0.dist-info → synapse-2.179.0.dist-info}/METADATA +48 -48
- {synapse-2.177.0.dist-info → synapse-2.179.0.dist-info}/RECORD +73 -65
- {synapse-2.177.0.dist-info → synapse-2.179.0.dist-info}/WHEEL +1 -1
- {synapse-2.177.0.dist-info → synapse-2.179.0.dist-info}/LICENSE +0 -0
- {synapse-2.177.0.dist-info → synapse-2.179.0.dist-info}/top_level.txt +0 -0
|
@@ -10,7 +10,7 @@ class AhaLibTest(s_test.SynTest):
|
|
|
10
10
|
|
|
11
11
|
async def test_stormlib_aha_basics(self):
|
|
12
12
|
|
|
13
|
-
async with self.
|
|
13
|
+
async with self.getTestAha() as aha:
|
|
14
14
|
|
|
15
15
|
with self.getTestDir() as dirn:
|
|
16
16
|
|
|
@@ -36,24 +36,24 @@ class AhaLibTest(s_test.SynTest):
|
|
|
36
36
|
self.len(5, svcs)
|
|
37
37
|
|
|
38
38
|
svc = await core00.callStorm('return( $lib.aha.get(core...) )')
|
|
39
|
-
self.eq('core.
|
|
40
|
-
svc = await core00.callStorm('return( $lib.aha.get(core.
|
|
41
|
-
self.eq('core.
|
|
39
|
+
self.eq('core.synapse', svc.get('name'))
|
|
40
|
+
svc = await core00.callStorm('return( $lib.aha.get(core.synapse))')
|
|
41
|
+
self.eq('core.synapse', svc.get('name'))
|
|
42
42
|
svc = await core00.callStorm('return( $lib.aha.get(00.cell...))')
|
|
43
|
-
self.eq('00.cell.
|
|
43
|
+
self.eq('00.cell.synapse', svc.get('name'))
|
|
44
44
|
svc = await core00.callStorm('return( $lib.aha.get(cell...))')
|
|
45
|
-
self.eq('cell.
|
|
45
|
+
self.eq('cell.synapse', svc.get('name'))
|
|
46
46
|
svc = await core00.callStorm('$f=({"mirror": (true)}) return( $lib.aha.get(cell..., filters=$f))')
|
|
47
|
-
self.eq('01.cell.
|
|
47
|
+
self.eq('01.cell.synapse', svc.get('name'))
|
|
48
48
|
|
|
49
49
|
# List the aha services available
|
|
50
50
|
msgs = await core00.stormlist('aha.svc.list --nexus')
|
|
51
51
|
self.stormIsInPrint('Nexus', msgs)
|
|
52
|
-
self.stormIsInPrint('00.cell.
|
|
53
|
-
self.stormIsInPrint('01.cell.
|
|
54
|
-
self.stormIsInPrint('cell.
|
|
55
|
-
self.stormIsInPrint('core.
|
|
56
|
-
self.stormIsInPrint('mysvc.
|
|
52
|
+
self.stormIsInPrint('00.cell.synapse true true true', msgs, whitespace=False)
|
|
53
|
+
self.stormIsInPrint('01.cell.synapse false true true', msgs, whitespace=False)
|
|
54
|
+
self.stormIsInPrint('cell.synapse true true true', msgs, whitespace=False)
|
|
55
|
+
self.stormIsInPrint('core.synapse null true true', msgs, whitespace=False)
|
|
56
|
+
self.stormIsInPrint('mysvc.synapse null true true', msgs, whitespace=False)
|
|
57
57
|
|
|
58
58
|
msgs = await core00.stormlist('aha.svc.list')
|
|
59
59
|
self.stormNotInPrint('Nexus', msgs)
|
|
@@ -63,24 +63,24 @@ class AhaLibTest(s_test.SynTest):
|
|
|
63
63
|
# Omit checking part of that.
|
|
64
64
|
emsg = '''Resolved cell... to an AHA Service.
|
|
65
65
|
|
|
66
|
-
Name: cell.
|
|
66
|
+
Name: cell.synapse
|
|
67
67
|
Online: true
|
|
68
68
|
Ready: true
|
|
69
69
|
Run iden: ********************************
|
|
70
70
|
Cell iden: ********************************
|
|
71
71
|
Leader: cell
|
|
72
72
|
Connection information:
|
|
73
|
-
ca:
|
|
73
|
+
ca: synapse
|
|
74
74
|
'''
|
|
75
75
|
self.stormIsInPrint(emsg, msgs, deguid=True)
|
|
76
|
-
self.stormIsInPrint(' hostname: 00.cell.
|
|
76
|
+
self.stormIsInPrint(' hostname: 00.cell.synapse', msgs)
|
|
77
77
|
self.stormIsInPrint(' scheme: ssl', msgs)
|
|
78
78
|
self.stormIsInPrint(' user: root', msgs)
|
|
79
79
|
|
|
80
80
|
msgs = await core00.stormlist('aha.svc.stat --nexus cell...')
|
|
81
81
|
emsg = '''Resolved cell... to an AHA Service.
|
|
82
82
|
|
|
83
|
-
Name: cell.
|
|
83
|
+
Name: cell.synapse
|
|
84
84
|
Online: true
|
|
85
85
|
Ready: true
|
|
86
86
|
Run iden: ********************************
|
|
@@ -88,14 +88,14 @@ Cell iden: ********************************
|
|
|
88
88
|
Leader: cell
|
|
89
89
|
Nexus: 1
|
|
90
90
|
Connection information:
|
|
91
|
-
ca:
|
|
91
|
+
ca: synapse
|
|
92
92
|
'''
|
|
93
93
|
self.stormIsInPrint(emsg, msgs, deguid=True)
|
|
94
94
|
|
|
95
95
|
msgs = await core00.stormlist('aha.svc.stat --nexus 01.cell...')
|
|
96
96
|
emsg = '''Resolved 01.cell... to an AHA Service.
|
|
97
97
|
|
|
98
|
-
Name: 01.cell.
|
|
98
|
+
Name: 01.cell.synapse
|
|
99
99
|
Online: true
|
|
100
100
|
Ready: true
|
|
101
101
|
Run iden: ********************************
|
|
@@ -103,15 +103,15 @@ Cell iden: ********************************
|
|
|
103
103
|
Leader: cell
|
|
104
104
|
Nexus: 1
|
|
105
105
|
Connection information:
|
|
106
|
-
ca:
|
|
106
|
+
ca: synapse
|
|
107
107
|
'''
|
|
108
108
|
self.stormIsInPrint(emsg, msgs, deguid=True)
|
|
109
109
|
|
|
110
110
|
# Full name works
|
|
111
|
-
msgs = await core00.stormlist('aha.svc.stat 01.cell.
|
|
112
|
-
emsg = '''Resolved 01.cell.
|
|
111
|
+
msgs = await core00.stormlist('aha.svc.stat 01.cell.synapse')
|
|
112
|
+
emsg = '''Resolved 01.cell.synapse to an AHA Service.
|
|
113
113
|
|
|
114
|
-
Name: 01.cell.
|
|
114
|
+
Name: 01.cell.synapse
|
|
115
115
|
'''
|
|
116
116
|
self.stormIsInPrint(emsg, msgs, deguid=True)
|
|
117
117
|
|
|
@@ -128,8 +128,8 @@ Name: 01.cell.loop.vertex.link
|
|
|
128
128
|
emsg = '''Resolved pool00... to an AHA Pool.
|
|
129
129
|
|
|
130
130
|
The pool currently has 1 members.
|
|
131
|
-
AHA Pool: pool00.
|
|
132
|
-
Member: 00.cell.
|
|
131
|
+
AHA Pool: pool00.synapse
|
|
132
|
+
Member: 00.cell.synapse'''
|
|
133
133
|
self.stormIsInPrint(emsg, msgs)
|
|
134
134
|
|
|
135
135
|
# Shut down a service
|
|
@@ -139,15 +139,15 @@ 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.
|
|
142
|
+
self.stormIsInPrint('01.cell.synapse false false false', msgs, whitespace=False)
|
|
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'}},
|
|
146
|
-
network='
|
|
146
|
+
network='synapse')
|
|
147
147
|
|
|
148
148
|
msgs = await core00.stormlist('aha.svc.list --nexus')
|
|
149
|
-
emsg = '00.newp.
|
|
150
|
-
self.stormIsInPrint(emsg, msgs)
|
|
149
|
+
emsg = '00.newp.synapse null false null 0.0.0.0 3030 <offline>'
|
|
150
|
+
self.stormIsInPrint(emsg, msgs, whitespace=False)
|
|
151
151
|
|
|
152
152
|
self.none(await core00.callStorm('return($lib.aha.del(00.newp...))'))
|
|
153
153
|
msgs = await core00.stormlist('aha.svc.list')
|
|
@@ -160,22 +160,22 @@ Member: 00.cell.loop.vertex.link'''
|
|
|
160
160
|
'port': '3030'},
|
|
161
161
|
'online': guid,
|
|
162
162
|
},
|
|
163
|
-
network='
|
|
163
|
+
network='synapse')
|
|
164
164
|
msgs = await core00.stormlist('aha.svc.list --nexus')
|
|
165
|
-
emsg = '00.newp.
|
|
166
|
-
'Failed to connect to Telepath service: "aha://00.newp.
|
|
167
|
-
self.stormIsInPrint(emsg, msgs)
|
|
165
|
+
emsg = '00.newp.synapse null true null 0.0.0.0 3030 ' \
|
|
166
|
+
'Failed to connect to Telepath service: "aha://00.newp.synapse/" error:'
|
|
167
|
+
self.stormIsInPrint(emsg, msgs, whitespace=False)
|
|
168
168
|
|
|
169
169
|
msgs = await core00.stormlist('aha.svc.stat --nexus 00.newp...')
|
|
170
170
|
emsg = '''Resolved 00.newp... to an AHA Service.
|
|
171
171
|
|
|
172
|
-
Name: 00.newp.
|
|
172
|
+
Name: 00.newp.synapse
|
|
173
173
|
Online: true
|
|
174
174
|
Ready: null
|
|
175
175
|
Run iden: $lib.null
|
|
176
176
|
Cell iden: $lib.null
|
|
177
177
|
Leader: Service did not register itself with a leader name.
|
|
178
|
-
Nexus: Failed to connect to Telepath service: "aha://00.newp.
|
|
178
|
+
Nexus: Failed to connect to Telepath service: "aha://00.newp.synapse/" error: [Errno 111] Connect call failed ('0.0.0.0', 3030)
|
|
179
179
|
Connection information:
|
|
180
180
|
host: 0.0.0.0
|
|
181
181
|
port: 3030
|
|
@@ -184,7 +184,7 @@ Connection information:
|
|
|
184
184
|
self.stormIsInPrint(emsg, msgs)
|
|
185
185
|
|
|
186
186
|
# Delete the fake service with its full service name
|
|
187
|
-
self.none(await core00.callStorm('return($lib.aha.del(00.newp.
|
|
187
|
+
self.none(await core00.callStorm('return($lib.aha.del(00.newp.synapse))'))
|
|
188
188
|
self.none(await core00.callStorm('return($lib.aha.get(00.newp...))'))
|
|
189
189
|
|
|
190
190
|
# Coverage for sad paths
|
|
@@ -76,18 +76,7 @@ class StormCellTest(s_test.SynTest):
|
|
|
76
76
|
|
|
77
77
|
async def test_stormlib_cell_getmirrors(self):
|
|
78
78
|
|
|
79
|
-
|
|
80
|
-
'aha:name': 'aha',
|
|
81
|
-
'aha:network': 'mynet',
|
|
82
|
-
'provision:listen': 'tcp://127.0.0.1:0',
|
|
83
|
-
}
|
|
84
|
-
async with self.getTestCell(s_aha.AhaCell, conf=conf) as aha:
|
|
85
|
-
|
|
86
|
-
provaddr, provport = aha.provdmon.addr
|
|
87
|
-
aha.conf['provision:listen'] = f'tcp://127.0.0.1:{provport}'
|
|
88
|
-
|
|
89
|
-
ahahost, ahaport = await aha.dmon.listen('ssl://127.0.0.1:0?hostname=aha.mynet&ca=mynet')
|
|
90
|
-
aha.conf['aha:urls'] = (f'ssl://127.0.0.1:{ahaport}?hostname=aha.mynet',)
|
|
79
|
+
async with self.getTestAha() as aha:
|
|
91
80
|
|
|
92
81
|
provurl = await aha.addAhaSvcProv('00.cortex')
|
|
93
82
|
coreconf = {'aha:provision': provurl}
|
|
@@ -116,7 +105,7 @@ class StormCellTest(s_test.SynTest):
|
|
|
116
105
|
await core01.nodes('[ inet:ipv4=1.2.3.4 ]')
|
|
117
106
|
self.len(1, await core00.nodes('inet:ipv4=1.2.3.4'))
|
|
118
107
|
|
|
119
|
-
expurls = ['aha://01.cortex.
|
|
108
|
+
expurls = ['aha://01.cortex.synapse']
|
|
120
109
|
|
|
121
110
|
self.eq(expurls, await core00.callStorm('return($lib.cell.getMirrorUrls())'))
|
|
122
111
|
self.eq(expurls, await core01.callStorm('return($lib.cell.getMirrorUrls())'))
|
|
@@ -148,11 +137,11 @@ class StormCellTest(s_test.SynTest):
|
|
|
148
137
|
|
|
149
138
|
await svc01.sync()
|
|
150
139
|
|
|
151
|
-
expurls = ('aha://01.testsvc.
|
|
140
|
+
expurls = ('aha://01.testsvc.synapse',)
|
|
152
141
|
|
|
153
142
|
self.eq(expurls, await core00.callStorm('return($lib.cell.getMirrorUrls(name=testsvc))'))
|
|
154
143
|
|
|
155
|
-
await aha.delAhaSvc('00.testsvc.
|
|
144
|
+
await aha.delAhaSvc('00.testsvc.synapse')
|
|
156
145
|
|
|
157
146
|
with self.raises(s_exc.NoSuchName):
|
|
158
147
|
await core00.callStorm('return($lib.cell.getMirrorUrls(name=testsvc))')
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import ssl
|
|
1
2
|
import asyncio
|
|
2
3
|
|
|
3
4
|
from unittest import mock
|
|
@@ -124,8 +125,13 @@ class ImapTest(s_test.SynTest):
|
|
|
124
125
|
|
|
125
126
|
async def test_storm_imap(self):
|
|
126
127
|
|
|
127
|
-
|
|
128
|
-
|
|
128
|
+
client_args = []
|
|
129
|
+
def client_mock(*args, **kwargs):
|
|
130
|
+
client_args.append((args, kwargs))
|
|
131
|
+
return mock_create_client(*args, **kwargs)
|
|
132
|
+
|
|
133
|
+
with mock.patch('aioimaplib.IMAP4.create_client', client_mock), \
|
|
134
|
+
mock.patch('aioimaplib.IMAP4_SSL.create_client', client_mock):
|
|
129
135
|
|
|
130
136
|
async with self.getTestCore() as core:
|
|
131
137
|
|
|
@@ -137,16 +143,20 @@ class ImapTest(s_test.SynTest):
|
|
|
137
143
|
'''
|
|
138
144
|
retn = await core.callStorm(scmd)
|
|
139
145
|
self.eq((True, ('INBOX',)), retn)
|
|
146
|
+
ctx = self.nn(client_args[-1][0][5]) # type: ssl.SSLContext
|
|
147
|
+
self.eq(ctx.verify_mode, ssl.CERT_REQUIRED)
|
|
140
148
|
|
|
141
149
|
# search for UIDs
|
|
142
150
|
scmd = '''
|
|
143
|
-
$server = $lib.inet.imap.connect(hello)
|
|
151
|
+
$server = $lib.inet.imap.connect(hello, ssl_verify=(false))
|
|
144
152
|
$server.login("vtx@email.com", "secret")
|
|
145
153
|
$server.select("INBOX")
|
|
146
154
|
return($server.search("FROM", "foo@mail.com"))
|
|
147
155
|
'''
|
|
148
156
|
retn = await core.callStorm(scmd)
|
|
149
157
|
self.eq((True, ('8181', '8192', '8194')), retn)
|
|
158
|
+
ctx = self.nn(client_args[-1][0][5]) # type: ssl.SSLContext
|
|
159
|
+
self.eq(ctx.verify_mode, ssl.CERT_NONE)
|
|
150
160
|
|
|
151
161
|
# search for UIDs with specific charset
|
|
152
162
|
scmd = '''
|
|
@@ -186,6 +196,7 @@ class ImapTest(s_test.SynTest):
|
|
|
186
196
|
'''
|
|
187
197
|
retn = await core.callStorm(scmd)
|
|
188
198
|
self.eq((True, None), retn)
|
|
199
|
+
self.none(client_args[-1][0][5])
|
|
189
200
|
|
|
190
201
|
# delete
|
|
191
202
|
scmd = '''
|
|
@@ -57,12 +57,24 @@ class StormtypesModelextTest(s_test.SynTest):
|
|
|
57
57
|
model_defs = await core.callStorm('return ( $lib.model.ext.getExtModel() )')
|
|
58
58
|
self.isinstance(model_defs, dict)
|
|
59
59
|
|
|
60
|
+
self.len(1, await core.nodes('_visi:int:tick'))
|
|
61
|
+
await core._delAllFormProp('_visi:int', 'tick', {})
|
|
62
|
+
self.len(0, await core.nodes('_visi:int:tick'))
|
|
63
|
+
|
|
64
|
+
self.len(1, await core.nodes('._woot'))
|
|
65
|
+
await core._delAllUnivProp('_woot', {})
|
|
66
|
+
self.len(0, await core.nodes('._woot'))
|
|
67
|
+
|
|
68
|
+
self.len(1, await core.nodes('#lol:score'))
|
|
69
|
+
await core._delAllTagProp('score', {})
|
|
70
|
+
self.len(0, await core.nodes('#lol:score'))
|
|
71
|
+
|
|
60
72
|
await core.callStorm('_visi:int=10 test:int=1234 | delnode')
|
|
61
73
|
await core.callStorm('''
|
|
62
|
-
$lib.model.ext.delTagProp(score)
|
|
63
|
-
$lib.model.ext.delUnivProp(_woot)
|
|
74
|
+
$lib.model.ext.delTagProp(score, force=(true))
|
|
75
|
+
$lib.model.ext.delUnivProp(_woot, force=(true))
|
|
64
76
|
$lib.model.ext.delFormProp(_visi:int, tick)
|
|
65
|
-
$lib.model.ext.delFormProp(test:int, _tick)
|
|
77
|
+
$lib.model.ext.delFormProp(test:int, _tick, force=(true))
|
|
66
78
|
$lib.model.ext.delForm(_visi:int)
|
|
67
79
|
$lib.model.ext.delEdge(inet:user, _copies, *)
|
|
68
80
|
''')
|
|
@@ -276,6 +288,46 @@ class StormtypesModelextTest(s_test.SynTest):
|
|
|
276
288
|
|
|
277
289
|
self.nn(core.model.edge(('inet:user', '_copies', None)))
|
|
278
290
|
|
|
291
|
+
# Property values left behind in layers are cleanly removed
|
|
292
|
+
async with self.getTestCore() as core:
|
|
293
|
+
await core.callStorm('''
|
|
294
|
+
$typeinfo = ({})
|
|
295
|
+
$docinfo = ({"doc": "NEWP"})
|
|
296
|
+
$lib.model.ext.addUnivProp(_woot, (int, ({})), $docinfo)
|
|
297
|
+
$lib.model.ext.addTagProp(score, (int, ({})), $docinfo)
|
|
298
|
+
$lib.model.ext.addFormProp(test:int, _tick, (time, ({})), $docinfo)
|
|
299
|
+
''')
|
|
300
|
+
fork = await core.callStorm('return ( $lib.view.get().fork().iden ) ')
|
|
301
|
+
nodes = await core.nodes('[test:int=1234 :_tick=2024 ._woot=1 +#hehe:score=10]')
|
|
302
|
+
self.len(1, nodes)
|
|
303
|
+
self.eq(nodes[0].get('._woot'), 1)
|
|
304
|
+
|
|
305
|
+
nodes = await core.nodes('test:int=1234 [:_tick=2023 ._woot=2 +#hehe:score=9]',
|
|
306
|
+
opts={'view': fork})
|
|
307
|
+
self.len(1, nodes)
|
|
308
|
+
self.eq(nodes[0].get('._woot'), 2)
|
|
309
|
+
|
|
310
|
+
self.len(0, await core.nodes('test:int | delnode'))
|
|
311
|
+
|
|
312
|
+
with self.raises(s_exc.CantDelUniv):
|
|
313
|
+
await core.callStorm('$lib.model.ext.delUnivProp(_woot)')
|
|
314
|
+
with self.raises(s_exc.CantDelProp):
|
|
315
|
+
await core.callStorm('$lib.model.ext.delFormProp(test:int, _tick)')
|
|
316
|
+
with self.raises(s_exc.CantDelProp):
|
|
317
|
+
await core.callStorm('$lib.model.ext.delTagProp(score)')
|
|
318
|
+
|
|
319
|
+
await core.callStorm('$lib.model.ext.delUnivProp(_woot, force=(true))')
|
|
320
|
+
await core.callStorm('$lib.model.ext.delFormProp(test:int, _tick, force=(true))')
|
|
321
|
+
await core.callStorm('$lib.model.ext.delTagProp(score, force=(true))')
|
|
322
|
+
|
|
323
|
+
nodes = await core.nodes('[test:int=1234]')
|
|
324
|
+
self.len(1, nodes)
|
|
325
|
+
self.none(nodes[0].get('._woot'))
|
|
326
|
+
self.none(nodes[0].get('_tick'))
|
|
327
|
+
nodes = await core.nodes('test:int=1234', opts={'view': fork})
|
|
328
|
+
self.none(nodes[0].get('._woot'))
|
|
329
|
+
self.none(nodes[0].get('_tick'))
|
|
330
|
+
|
|
279
331
|
async def test_lib_stormlib_behold_modelext(self):
|
|
280
332
|
self.skipIfNexusReplay()
|
|
281
333
|
async with self.getTestCore() as core:
|
|
@@ -1,3 +1,6 @@
|
|
|
1
|
+
import ssl
|
|
2
|
+
import email.mime.multipart as e_muiltipart
|
|
3
|
+
|
|
1
4
|
from unittest import mock
|
|
2
5
|
import synapse.tests.utils as s_test
|
|
3
6
|
|
|
@@ -5,7 +8,9 @@ class SmtpTest(s_test.SynTest):
|
|
|
5
8
|
|
|
6
9
|
async def test_storm_smtp(self):
|
|
7
10
|
|
|
11
|
+
called_args = []
|
|
8
12
|
async def send(*args, **kwargs):
|
|
13
|
+
called_args.append((args, kwargs))
|
|
9
14
|
return
|
|
10
15
|
|
|
11
16
|
with mock.patch('aiosmtplib.send', send):
|
|
@@ -14,6 +19,9 @@ class SmtpTest(s_test.SynTest):
|
|
|
14
19
|
|
|
15
20
|
retn = await core.callStorm('return($lib.inet.smtp.message().send(127.0.0.1))')
|
|
16
21
|
self.false(retn[0])
|
|
22
|
+
self.eq(retn[1].get('err'), 'StormRuntimeError')
|
|
23
|
+
self.isin('The inet:smtp:message has no HTML or text body.', retn[1].get('errmsg'))
|
|
24
|
+
self.len(0, called_args)
|
|
17
25
|
|
|
18
26
|
retn = await core.callStorm('''
|
|
19
27
|
$message = $lib.inet.smtp.message()
|
|
@@ -31,6 +39,49 @@ class SmtpTest(s_test.SynTest):
|
|
|
31
39
|
return($message.send('smtp.gmail.com', port=465, usetls=true))
|
|
32
40
|
''')
|
|
33
41
|
self.eq(retn, (True, {}))
|
|
42
|
+
mesg = called_args[-1][0][0] # type: e_muiltipart.MIMEMultipart
|
|
43
|
+
self.eq(mesg.get_all('subject'), ['woot'])
|
|
44
|
+
payload = mesg.get_payload()
|
|
45
|
+
self.len(2, payload)
|
|
46
|
+
self.eq([pl.get_content_type() for pl in payload],
|
|
47
|
+
['text/plain', 'text/html'])
|
|
48
|
+
ctx = self.nn(called_args[-1][1].get('tls_context')) # type: ssl.SSLContext
|
|
49
|
+
self.eq(ctx.verify_mode, ssl.CERT_REQUIRED)
|
|
50
|
+
self.eq(called_args[-1][1].get('port'), 465)
|
|
51
|
+
self.true(called_args[-1][1].get('use_tls'))
|
|
52
|
+
self.false(called_args[-1][1].get('start_tls'))
|
|
53
|
+
|
|
54
|
+
retn = await core.callStorm('''
|
|
55
|
+
$message = $lib.inet.smtp.message()
|
|
56
|
+
$message.text = "HELLO WORLD"
|
|
57
|
+
$message.sender = visi@vertex.link
|
|
58
|
+
$message.headers.Subject = woot
|
|
59
|
+
$message.recipients.append(visi@vertex.link)
|
|
60
|
+
return($message.send('smtp.gmail.com', port=465, starttls=true, ssl_verify=(false)))
|
|
61
|
+
''')
|
|
62
|
+
self.eq(retn, (True, {}))
|
|
63
|
+
mesg = called_args[-1][0][0] # type: e_muiltipart.MIMEMultipart
|
|
64
|
+
payload = mesg.get_payload()
|
|
65
|
+
self.len(1, payload)
|
|
66
|
+
self.eq([pl.get_content_type() for pl in payload], ['text/plain'])
|
|
67
|
+
ctx = self.nn(called_args[-1][1].get('tls_context')) # type: ssl.SSLContext
|
|
68
|
+
self.eq(ctx.verify_mode, ssl.CERT_NONE)
|
|
69
|
+
self.false(called_args[-1][1].get('use_tls'))
|
|
70
|
+
self.true(called_args[-1][1].get('start_tls'))
|
|
71
|
+
|
|
72
|
+
retn = await core.callStorm('''
|
|
73
|
+
$message = $lib.inet.smtp.message()
|
|
74
|
+
$message.text = "HELLO WORLD"
|
|
75
|
+
$message.sender = visi@vertex.link
|
|
76
|
+
$message.headers.Subject = woot
|
|
77
|
+
$message.recipients.append(visi@vertex.link)
|
|
78
|
+
return($message.send('smtp.gmail.com', port=25))
|
|
79
|
+
''')
|
|
80
|
+
self.eq(retn, (True, {}))
|
|
81
|
+
self.none(called_args[-1][1].get('tls_context')) # type: ssl.SSLContext
|
|
82
|
+
self.eq(called_args[-1][1].get('port'), 25)
|
|
83
|
+
self.false(called_args[-1][1].get('use_tls'))
|
|
84
|
+
self.false(called_args[-1][1].get('start_tls'))
|
|
34
85
|
|
|
35
86
|
isok, info = await core.callStorm('''
|
|
36
87
|
$message = $lib.inet.smtp.message()
|
|
@@ -410,6 +410,21 @@ class StormLibStixTest(s_test.SynTest):
|
|
|
410
410
|
self.len(1, [n for n in nodes if n[0][0] == 'it:cmd'])
|
|
411
411
|
self.stormIsInWarn("STIX bundle ingest has no relationship definition for: ('threat-actor', 'gronks', 'threat-actor')", msgs)
|
|
412
412
|
|
|
413
|
+
msgs = await core.stormlist('yield $lib.stix.import.ingest(({}), newp)')
|
|
414
|
+
self.stormIsInErr('config must be a dictionary', msgs)
|
|
415
|
+
|
|
416
|
+
msgs = await core.stormlist('yield $lib.stix.import.ingest(({}), ({"relationships": 5}))')
|
|
417
|
+
self.stormIsInErr('Error processing relationships', msgs)
|
|
418
|
+
|
|
419
|
+
msgs = await core.stormlist('yield $lib.stix.import.ingest(({}), ({"bundle": 3}))')
|
|
420
|
+
self.stormIsInErr('bundle value must be a dictionary', msgs)
|
|
421
|
+
|
|
422
|
+
msgs = await core.stormlist('yield $lib.stix.import.ingest(({}), ({"bundle": {"storm": 3}}))')
|
|
423
|
+
self.stormIsInErr('storm query must be a string', msgs)
|
|
424
|
+
|
|
425
|
+
msgs = await core.stormlist('yield $lib.stix.import.ingest(({"objects": 3}), ({}))')
|
|
426
|
+
self.stormIsInErr('Error processing objects', msgs)
|
|
427
|
+
|
|
413
428
|
async def test_stix_export_custom(self):
|
|
414
429
|
|
|
415
430
|
async with self.getTestCore() as core:
|
|
@@ -159,10 +159,13 @@ class StormlibVaultTest(s_test.SynTest):
|
|
|
159
159
|
|
|
160
160
|
# Rename vault
|
|
161
161
|
opts = {'vars': {'giden': giden}}
|
|
162
|
+
self.eq('gvault', await core.callStorm('return($lib.vault.get($giden).name)', opts=opts))
|
|
162
163
|
q = '$lib.vault.get($giden).name = foobar'
|
|
163
164
|
await core.callStorm(q, opts=opts)
|
|
164
165
|
vault = core.getVault(giden)
|
|
165
166
|
self.eq(vault.get('name'), 'foobar')
|
|
167
|
+
self.nn(await core.callStorm('return($lib.vault.byname(foobar))'))
|
|
168
|
+
await self.asyncraises(s_exc.NoSuchName, core.callStorm('return($lib.vault.byname(gvault))'))
|
|
166
169
|
|
|
167
170
|
# Get secrets without EDIT perms
|
|
168
171
|
opts = {'vars': {'giden': giden}, 'user': visi1.iden}
|
|
@@ -222,10 +225,17 @@ class StormlibVaultTest(s_test.SynTest):
|
|
|
222
225
|
q = '$vault = $lib.vault.get($giden) return($vault.setPerm($iden, $lib.auth.easyperm.level.deny))'
|
|
223
226
|
self.true(await core.callStorm(q, opts=opts))
|
|
224
227
|
|
|
225
|
-
# List vaults again
|
|
226
228
|
opts = {'user': visi1.iden}
|
|
227
229
|
self.eq(0, await core.callStorm('return($lib.len($lib.vault.list()))', opts=opts))
|
|
228
230
|
|
|
231
|
+
# Remove permission on global vault
|
|
232
|
+
opts = {'vars': {'iden': visi1.iden, 'giden': giden}}
|
|
233
|
+
q = '$vault = $lib.vault.get($giden) return($vault.setPerm($iden, $lib.null))'
|
|
234
|
+
self.true(await core.callStorm(q, opts=opts))
|
|
235
|
+
|
|
236
|
+
opts = {'user': visi1.iden}
|
|
237
|
+
self.eq(1, await core.callStorm('return($lib.len($lib.vault.list()))', opts=opts))
|
|
238
|
+
|
|
229
239
|
# Runtime asroot
|
|
230
240
|
|
|
231
241
|
await core.addStormPkg({
|
|
@@ -6388,6 +6388,11 @@ words\tword\twrd'''
|
|
|
6388
6388
|
self.eq(1, await core.callStorm('return($lib.math.number(1.23).toint())'))
|
|
6389
6389
|
self.eq(2, await core.callStorm('return($lib.math.number(1.23).toint(rounding=ROUND_UP))'))
|
|
6390
6390
|
|
|
6391
|
+
with self.raises(s_exc.BadCast):
|
|
6392
|
+
await core.callStorm('return($lib.math.number((null)))')
|
|
6393
|
+
with self.raises(s_exc.BadCast):
|
|
6394
|
+
await core.callStorm('return($lib.math.number(newp))')
|
|
6395
|
+
|
|
6391
6396
|
with self.raises(s_exc.StormRuntimeError):
|
|
6392
6397
|
await core.callStorm('return($lib.math.number(1.23).toint(rounding=NEWP))')
|
|
6393
6398
|
|
synapse/tests/test_lib_types.py
CHANGED
|
@@ -1606,3 +1606,12 @@ class TypesTest(s_t_utils.SynTest):
|
|
|
1606
1606
|
|
|
1607
1607
|
core.getLayer()._testAddPropArrayIndx(buid, 'test:int', '_hehe', ('newp' * 100,))
|
|
1608
1608
|
self.len(0, await core.nodes('test:int:_hehe*[~=newp]'))
|
|
1609
|
+
|
|
1610
|
+
async def test_types_typehash(self):
|
|
1611
|
+
async with self.getTestCore() as core:
|
|
1612
|
+
self.true(core.model.form('inet:fqdn').type.typehash is core.model.prop('inet:dns:a:fqdn').type.typehash)
|
|
1613
|
+
self.true(core.model.form('it:prod:softname').type.typehash is core.model.prop('it:network:name').type.typehash)
|
|
1614
|
+
self.true(core.model.form('inet:asn').type.typehash is not core.model.prop('inet:proto:port').type.typehash)
|
|
1615
|
+
|
|
1616
|
+
self.true(s_common.isguid(core.model.form('inet:fqdn').type.typehash))
|
|
1617
|
+
self.true(s_common.isguid(core.model.form('inet:fqdn').typehash))
|
synapse/tests/test_model_dns.py
CHANGED
|
@@ -108,6 +108,14 @@ class DnsModelTest(s_t_utils.SynTest):
|
|
|
108
108
|
self.eq(node.get('name:fqdn'), 'vertex.link')
|
|
109
109
|
self.eq(node.get('type'), 255)
|
|
110
110
|
|
|
111
|
+
nodes = await core.nodes('[inet:dns:request=* :reply:code=NXDOMAIN]')
|
|
112
|
+
self.eq(nodes[0].get('reply:code'), 3)
|
|
113
|
+
self.eq(nodes[0].repr('reply:code'), 'NXDOMAIN')
|
|
114
|
+
|
|
115
|
+
nodes = await core.nodes('[inet:dns:request=* :reply:code=1138]')
|
|
116
|
+
self.eq(nodes[0].get('reply:code'), 1138)
|
|
117
|
+
self.eq(nodes[0].repr('reply:code'), '1138')
|
|
118
|
+
|
|
111
119
|
nodes = await core.nodes('[inet:dns:query=("tcp://1.2.3.4", 4.3.2.1.in-addr.arpa, 255)]')
|
|
112
120
|
self.len(1, nodes)
|
|
113
121
|
node = nodes[0]
|
|
@@ -2,7 +2,6 @@ import synapse.exc as s_exc
|
|
|
2
2
|
import synapse.common as s_common
|
|
3
3
|
|
|
4
4
|
import synapse.tests.utils as s_t_utils
|
|
5
|
-
from synapse.tests.utils import alist
|
|
6
5
|
|
|
7
6
|
import synapse.lib.module as s_module
|
|
8
7
|
|
|
@@ -499,6 +498,7 @@ class GeoTest(s_t_utils.SynTest):
|
|
|
499
498
|
:place:name=woot
|
|
500
499
|
:place={[geo:place=* :name=woot]}
|
|
501
500
|
:accuracy=10m
|
|
501
|
+
:node=(test:int, 1234)
|
|
502
502
|
]
|
|
503
503
|
''')
|
|
504
504
|
self.eq(1655510400000, nodes[0].get('time'))
|
|
@@ -507,6 +507,8 @@ class GeoTest(s_t_utils.SynTest):
|
|
|
507
507
|
self.eq('woot', nodes[0].get('place:name'))
|
|
508
508
|
self.eq(10000, nodes[0].get('accuracy'))
|
|
509
509
|
self.len(1, await core.nodes('geo:telem -> geo:place +:name=woot'))
|
|
510
|
+
self.eq(('test:int', 1234), nodes[0].get('node'))
|
|
511
|
+
self.len(1, await core.nodes('test:int=1234'))
|
|
510
512
|
|
|
511
513
|
async def test_model_geospace_area(self):
|
|
512
514
|
|
|
@@ -407,6 +407,35 @@ class InfotechModelTest(s_t_utils.SynTest):
|
|
|
407
407
|
self.eq(nodes[0].get('net6'), ('fe80::', 'fe80::ffff:ffff:ffff:ffff'))
|
|
408
408
|
self.eq(nodes[0].get('type'), 'virtual.sdn.')
|
|
409
409
|
|
|
410
|
+
nodes = await core.nodes('''[
|
|
411
|
+
it:sec:stix:indicator=*
|
|
412
|
+
:id=zoinks
|
|
413
|
+
:name=woot
|
|
414
|
+
:confidence=90
|
|
415
|
+
:revoked=(false)
|
|
416
|
+
:description="my neato indicator"
|
|
417
|
+
:pattern="some rule text"
|
|
418
|
+
:pattern_type=yara
|
|
419
|
+
:created=20240815
|
|
420
|
+
:updated=20240815
|
|
421
|
+
:labels=(hehe, haha)
|
|
422
|
+
:valid_from=20240815
|
|
423
|
+
:valid_until=20240815
|
|
424
|
+
]''')
|
|
425
|
+
self.len(1, nodes)
|
|
426
|
+
self.eq('zoinks', nodes[0].get('id'))
|
|
427
|
+
self.eq('woot', nodes[0].get('name'))
|
|
428
|
+
self.eq(90, nodes[0].get('confidence'))
|
|
429
|
+
self.eq(False, nodes[0].get('revoked'))
|
|
430
|
+
self.eq('my neato indicator', nodes[0].get('description'))
|
|
431
|
+
self.eq('some rule text', nodes[0].get('pattern'))
|
|
432
|
+
self.eq('yara', nodes[0].get('pattern_type'))
|
|
433
|
+
self.eq(('haha', 'hehe'), nodes[0].get('labels'))
|
|
434
|
+
self.eq(1723680000000, nodes[0].get('created'))
|
|
435
|
+
self.eq(1723680000000, nodes[0].get('updated'))
|
|
436
|
+
self.eq(1723680000000, nodes[0].get('valid_from'))
|
|
437
|
+
self.eq(1723680000000, nodes[0].get('valid_until'))
|
|
438
|
+
|
|
410
439
|
async def test_infotech_ios(self):
|
|
411
440
|
|
|
412
441
|
async with self.getTestCore() as core:
|
|
@@ -1553,6 +1582,24 @@ class InfotechModelTest(s_t_utils.SynTest):
|
|
|
1553
1582
|
self.eq(rule, nodes[0].get('rule'))
|
|
1554
1583
|
self.eq(0x10000200003, nodes[0].get('version'))
|
|
1555
1584
|
|
|
1585
|
+
nodes = await core.nodes('''[
|
|
1586
|
+
(it:app:yara:netmatch=* :node=(inet:fqdn, foo.com))
|
|
1587
|
+
(it:app:yara:netmatch=* :node=(inet:ipv4, 1.2.3.4))
|
|
1588
|
+
(it:app:yara:netmatch=* :node=(inet:ipv6, "::ffff"))
|
|
1589
|
+
(it:app:yara:netmatch=* :node=(inet:url, "http://foo.com"))
|
|
1590
|
+
:rule=$rule
|
|
1591
|
+
:version=1.2.3
|
|
1592
|
+
]''', opts=opts)
|
|
1593
|
+
self.len(4, nodes)
|
|
1594
|
+
for node in nodes:
|
|
1595
|
+
self.nn(node.get('node'))
|
|
1596
|
+
self.nn(node.get('version'))
|
|
1597
|
+
|
|
1598
|
+
self.len(4, await core.nodes('it:app:yara:rule=$rule -> it:app:yara:netmatch', opts=opts))
|
|
1599
|
+
|
|
1600
|
+
with self.raises(s_exc.BadTypeValu):
|
|
1601
|
+
await core.nodes('[it:app:yara:netmatch=* :node=(it:dev:str, foo)]')
|
|
1602
|
+
|
|
1556
1603
|
async def test_it_app_snort(self):
|
|
1557
1604
|
|
|
1558
1605
|
async with self.getTestCore() as core:
|
synapse/tests/test_model_syn.py
CHANGED
|
@@ -340,11 +340,22 @@ class SynModelTest(s_t_utils.SynTest):
|
|
|
340
340
|
nodes = await core.nodes(f'syn:trigger={iden}')
|
|
341
341
|
self.len(1, nodes)
|
|
342
342
|
|
|
343
|
+
indx = await core.getNexsIndx()
|
|
344
|
+
|
|
343
345
|
# set the trigger doc
|
|
344
346
|
nodes = await core.nodes(f'syn:trigger={iden} [ :doc=hehe ]')
|
|
345
347
|
self.len(1, nodes)
|
|
346
348
|
self.eq('hehe', nodes[0].get('doc'))
|
|
347
349
|
|
|
350
|
+
self.eq(await core.getNexsIndx(), indx + 1)
|
|
351
|
+
|
|
352
|
+
# set the trigger name
|
|
353
|
+
nodes = await core.nodes(f'syn:trigger={iden} [ :name=trigname ]')
|
|
354
|
+
self.len(1, nodes)
|
|
355
|
+
self.eq('trigname', nodes[0].get('name'))
|
|
356
|
+
|
|
357
|
+
self.eq(await core.getNexsIndx(), indx + 2)
|
|
358
|
+
|
|
348
359
|
# Trigger reloads and make some more triggers to play with
|
|
349
360
|
tdef = {'cond': 'prop:set', 'prop': 'inet:ipv4:asn', 'storm': '[inet:user=1] | testcmd'}
|
|
350
361
|
await core.view.addTrigger(tdef)
|