synapse 2.219.0__py311-none-any.whl → 2.221.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/data/__init__.py +4 -0
- synapse/data/lark/__init__.py +0 -0
- synapse/data/lark/imap.lark +8 -0
- synapse/exc.py +2 -0
- synapse/lib/json.py +6 -5
- synapse/lib/layer.py +134 -0
- synapse/lib/link.py +49 -50
- synapse/lib/parser.py +3 -5
- synapse/lib/rstorm.py +65 -2
- synapse/lib/snap.py +21 -13
- synapse/lib/storm.py +1 -0
- synapse/lib/stormhttp.py +10 -10
- synapse/lib/stormlib/aha.py +3 -3
- synapse/lib/stormlib/auth.py +11 -11
- synapse/lib/stormlib/cell.py +1 -1
- synapse/lib/stormlib/cortex.py +9 -9
- synapse/lib/stormlib/env.py +4 -5
- synapse/lib/stormlib/ethereum.py +1 -1
- synapse/lib/stormlib/gen.py +3 -3
- synapse/lib/stormlib/hex.py +2 -2
- synapse/lib/stormlib/imap.py +478 -37
- synapse/lib/stormlib/infosec.py +2 -2
- synapse/lib/stormlib/iters.py +2 -2
- synapse/lib/stormlib/model.py +5 -5
- synapse/lib/stormlib/notifications.py +1 -1
- synapse/lib/stormlib/oauth.py +2 -2
- synapse/lib/stormlib/project.py +3 -3
- synapse/lib/stormlib/scrape.py +2 -1
- synapse/lib/stormlib/smtp.py +3 -3
- synapse/lib/stormlib/stats.py +2 -2
- synapse/lib/stormlib/stix.py +2 -2
- synapse/lib/stormlib/utils.py +19 -0
- synapse/lib/stormlib/vault.py +1 -1
- synapse/lib/stormlib/xml.py +2 -2
- synapse/lib/stormlib/yaml.py +1 -1
- synapse/lib/stormtypes.py +203 -60
- synapse/lib/version.py +2 -2
- synapse/tests/test_lib_grammar.py +2 -4
- synapse/tests/test_lib_json.py +29 -0
- synapse/tests/test_lib_layer.py +86 -67
- synapse/tests/test_lib_rstorm.py +132 -0
- synapse/tests/test_lib_storm.py +11 -1
- synapse/tests/test_lib_stormlib_env.py +3 -1
- synapse/tests/test_lib_stormlib_imap.py +1307 -230
- synapse/tests/test_lib_stormlib_utils.py +10 -0
- synapse/tests/test_lib_stormtypes.py +583 -2
- synapse/tools/aha/list.py +9 -9
- synapse/tools/aha/provision/service.py +2 -2
- synapse/utils/stormcov/plugin.py +2 -5
- {synapse-2.219.0.dist-info → synapse-2.221.0.dist-info}/METADATA +1 -2
- {synapse-2.219.0.dist-info → synapse-2.221.0.dist-info}/RECORD +55 -53
- /synapse/{lib → data/lark}/storm.lark +0 -0
- {synapse-2.219.0.dist-info → synapse-2.221.0.dist-info}/WHEEL +0 -0
- {synapse-2.219.0.dist-info → synapse-2.221.0.dist-info}/licenses/LICENSE +0 -0
- {synapse-2.219.0.dist-info → synapse-2.221.0.dist-info}/top_level.txt +0 -0
|
@@ -1,8 +1,18 @@
|
|
|
1
1
|
import synapse.exc as s_exc
|
|
2
|
+
import synapse.common as s_common
|
|
3
|
+
|
|
2
4
|
import synapse.tests.utils as s_test
|
|
3
5
|
|
|
4
6
|
class UtilsTest(s_test.SynTest):
|
|
5
7
|
|
|
8
|
+
async def test_lib_stormlib_utils_buid(self):
|
|
9
|
+
async with self.getTestCore() as core:
|
|
10
|
+
obj = ('meta:source', '0123456789abcdef0123456789abcdef')
|
|
11
|
+
self.eq(
|
|
12
|
+
await core.callStorm('return($lib.utils.buid($obj))', opts={'vars': {'obj': obj}}),
|
|
13
|
+
s_common.buid(obj)
|
|
14
|
+
)
|
|
15
|
+
|
|
6
16
|
async def test_lib_stormlib_utils_todo(self):
|
|
7
17
|
|
|
8
18
|
async with self.getTestCore() as core:
|
|
@@ -17,6 +17,7 @@ import synapse.axon as s_axon
|
|
|
17
17
|
import synapse.common as s_common
|
|
18
18
|
|
|
19
19
|
import synapse.lib.json as s_json
|
|
20
|
+
import synapse.lib.node as s_node
|
|
20
21
|
import synapse.lib.time as s_time
|
|
21
22
|
import synapse.lib.storm as s_storm
|
|
22
23
|
import synapse.lib.hashset as s_hashset
|
|
@@ -884,13 +885,32 @@ class StormTypesTest(s_test.SynTest):
|
|
|
884
885
|
self.eq(2, await core.callStorm('return($lib.len($lib.layer.get().getStorNodes()))', opts=opts))
|
|
885
886
|
|
|
886
887
|
await core.nodes('[ media:news=c0dc5dc1f7c3d27b725ef3015422f8e2 +(refs)> { inet:ipv4=1.2.3.4 } ]')
|
|
888
|
+
expN1 = [('refs', '20153b758f9d5eaaa38e4f4a65c36da797c3e59e549620fa7c4895e1a920991f')]
|
|
889
|
+
expN2 = [('refs', 'ddf7f87c0164d760e8e1e5cd2cae2fee96868a3cf184f6dab9154e31ad689528')]
|
|
890
|
+
|
|
887
891
|
edges = await core.callStorm('''
|
|
888
892
|
$edges = ([])
|
|
889
893
|
media:news=c0dc5dc1f7c3d27b725ef3015422f8e2
|
|
890
894
|
for $i in $lib.layer.get().getEdgesByN1($node.iden()) { $edges.append($i) }
|
|
891
895
|
fini { return($edges) }
|
|
892
896
|
''')
|
|
893
|
-
self.eq(
|
|
897
|
+
self.eq(expN1, edges)
|
|
898
|
+
|
|
899
|
+
edges = await core.callStorm('''
|
|
900
|
+
$edges = ([])
|
|
901
|
+
media:news=c0dc5dc1f7c3d27b725ef3015422f8e2
|
|
902
|
+
for $i in $lib.layer.get().getEdgesByN1($node.iden(), verb=refs) { $edges.append($i) }
|
|
903
|
+
fini { return($edges) }
|
|
904
|
+
''')
|
|
905
|
+
self.eq(expN1, edges)
|
|
906
|
+
|
|
907
|
+
edges = await core.callStorm('''
|
|
908
|
+
$edges = ([])
|
|
909
|
+
media:news=c0dc5dc1f7c3d27b725ef3015422f8e2
|
|
910
|
+
for $i in $lib.layer.get().getEdgesByN1($node.iden(), verb=newp) { $edges.append($i) }
|
|
911
|
+
fini { return($edges) }
|
|
912
|
+
''')
|
|
913
|
+
self.eq([], edges)
|
|
894
914
|
|
|
895
915
|
edges = await core.callStorm('''
|
|
896
916
|
$edges = ([])
|
|
@@ -898,7 +918,37 @@ class StormTypesTest(s_test.SynTest):
|
|
|
898
918
|
for $i in $lib.layer.get().getEdgesByN2($node.iden()) { $edges.append($i) }
|
|
899
919
|
fini { return($edges) }
|
|
900
920
|
''')
|
|
901
|
-
self.eq(
|
|
921
|
+
self.eq(expN2, edges)
|
|
922
|
+
|
|
923
|
+
edges = await core.callStorm('''
|
|
924
|
+
$edges = ([])
|
|
925
|
+
inet:ipv4=1.2.3.4
|
|
926
|
+
for $i in $lib.layer.get().getEdgesByN2($node.iden(), verb=refs) { $edges.append($i) }
|
|
927
|
+
fini { return($edges) }
|
|
928
|
+
''')
|
|
929
|
+
self.eq(expN2, edges)
|
|
930
|
+
|
|
931
|
+
edges = await core.callStorm('''
|
|
932
|
+
$edges = ([])
|
|
933
|
+
inet:ipv4=1.2.3.4
|
|
934
|
+
for $i in $lib.layer.get().getEdgesByN2($node.iden(), verb=newp) { $edges.append($i) }
|
|
935
|
+
fini { return($edges) }
|
|
936
|
+
''')
|
|
937
|
+
self.eq([], edges)
|
|
938
|
+
|
|
939
|
+
ret = await core.callStorm('''
|
|
940
|
+
$n1 = { media:news=c0dc5dc1f7c3d27b725ef3015422f8e2 return($node.iden()) }
|
|
941
|
+
$n2 = { inet:ipv4=1.2.3.4 return($node.iden()) }
|
|
942
|
+
return($lib.layer.get().hasEdge($n1, refs, $n2))
|
|
943
|
+
''')
|
|
944
|
+
self.true(ret)
|
|
945
|
+
|
|
946
|
+
ret = await core.callStorm('''
|
|
947
|
+
$n1 = { media:news=c0dc5dc1f7c3d27b725ef3015422f8e2 return($node.iden()) }
|
|
948
|
+
$n2 = { inet:ipv4=1.2.3.4 return($node.iden()) }
|
|
949
|
+
return($lib.layer.get().hasEdge($n1, newp, $n2))
|
|
950
|
+
''')
|
|
951
|
+
self.false(ret)
|
|
902
952
|
|
|
903
953
|
edges = await core.callStorm('''
|
|
904
954
|
$edges = ([])
|
|
@@ -1538,6 +1588,38 @@ class StormTypesTest(s_test.SynTest):
|
|
|
1538
1588
|
with self.raises(s_exc.BadJsonText):
|
|
1539
1589
|
await core.callStorm(q, opts={'vars': {'buf': b'lol{newp,', 'encoding': None}})
|
|
1540
1590
|
|
|
1591
|
+
async def test_storm_lib_bytes_xor(self):
|
|
1592
|
+
async with self.getTestCore() as core:
|
|
1593
|
+
encval = await core.callStorm("return(('foobar').encode().xor(asdf))")
|
|
1594
|
+
self.eq(encval, b'\x07\x1c\x0b\x04\x00\x01')
|
|
1595
|
+
|
|
1596
|
+
decval = await core.callStorm("return($foo.xor(asdf).decode())", opts={'vars': {'foo': encval}})
|
|
1597
|
+
self.eq(decval, 'foobar')
|
|
1598
|
+
|
|
1599
|
+
encval = await core.callStorm("return(('foofoo').encode().xor(v))")
|
|
1600
|
+
self.eq(encval, b'\x10\x19\x19\x10\x19\x19')
|
|
1601
|
+
|
|
1602
|
+
encval = await core.callStorm("$key=$lib.base64.decode('AA==') return(('foofoo').encode().xor($key))")
|
|
1603
|
+
self.eq(encval, b'foofoo')
|
|
1604
|
+
|
|
1605
|
+
encval = await core.callStorm("$key=$lib.base64.decode('/w==') return(('foofoo').encode().xor($key))")
|
|
1606
|
+
self.eq(encval, b'\x99\x90\x90\x99\x90\x90')
|
|
1607
|
+
|
|
1608
|
+
encval = await core.callStorm("$key=$lib.base64.decode('/w==') return(('foofoo').encode().xor($key).xor($key))")
|
|
1609
|
+
self.eq(encval, b'foofoo')
|
|
1610
|
+
|
|
1611
|
+
encval = await core.callStorm("return(('v').encode().xor(foo))")
|
|
1612
|
+
self.eq(encval, b'\x10')
|
|
1613
|
+
|
|
1614
|
+
encval = await core.callStorm("return(('').encode().xor(foo))")
|
|
1615
|
+
self.eq(encval, b'')
|
|
1616
|
+
|
|
1617
|
+
with self.raises(s_exc.BadArg):
|
|
1618
|
+
await core.callStorm("return(('foobar').encode().xor(''))")
|
|
1619
|
+
|
|
1620
|
+
with self.raises(s_exc.BadArg):
|
|
1621
|
+
await core.callStorm("return(('foobar').encode().xor((123)))")
|
|
1622
|
+
|
|
1541
1623
|
async def test_storm_lib_list(self):
|
|
1542
1624
|
async with self.getTestCore() as core:
|
|
1543
1625
|
# Base List object behavior
|
|
@@ -1735,6 +1817,435 @@ class StormTypesTest(s_test.SynTest):
|
|
|
1735
1817
|
await visi.addRule((True, ('layer', 'read')), gateiden=layriden)
|
|
1736
1818
|
await core.callStorm('return($lib.layer.get($layriden).getStorNode($iden))', opts=opts)
|
|
1737
1819
|
|
|
1820
|
+
async def test_storm_layer_getstornodesbyprop(self):
|
|
1821
|
+
async with self.getTestCore() as core:
|
|
1822
|
+
nodes = await core.nodes('[ test:str=foobar :hehe=foobaz ]')
|
|
1823
|
+
self.len(1, nodes)
|
|
1824
|
+
|
|
1825
|
+
buid00 = nodes[0].iden()
|
|
1826
|
+
sode00 = {
|
|
1827
|
+
'form': 'test:str',
|
|
1828
|
+
'props': {
|
|
1829
|
+
'.created': (nodes[0].get('.created'), 21),
|
|
1830
|
+
'hehe': ('foobaz', 1)
|
|
1831
|
+
},
|
|
1832
|
+
'valu': ('foobar', 1),
|
|
1833
|
+
}
|
|
1834
|
+
expval00 = (buid00, sode00)
|
|
1835
|
+
|
|
1836
|
+
nodes = await core.nodes('[ test:str=boobar :hehe=boobaz ]')
|
|
1837
|
+
self.len(1, nodes)
|
|
1838
|
+
|
|
1839
|
+
buid01 = nodes[0].iden()
|
|
1840
|
+
sode01 = {
|
|
1841
|
+
'form': 'test:str',
|
|
1842
|
+
'props': {
|
|
1843
|
+
'.created': (nodes[0].get('.created'), 21),
|
|
1844
|
+
'hehe': ('boobaz', 1)
|
|
1845
|
+
},
|
|
1846
|
+
'valu': ('boobar', 1),
|
|
1847
|
+
}
|
|
1848
|
+
expval01 = (buid01, sode01)
|
|
1849
|
+
|
|
1850
|
+
# just prop
|
|
1851
|
+
q = '''
|
|
1852
|
+
$sodes = ([])
|
|
1853
|
+
for ($buid, $sode) in $lib.layer.get().getStorNodesByProp(test:str:hehe) {
|
|
1854
|
+
$sodes.append(($buid, $sode))
|
|
1855
|
+
}
|
|
1856
|
+
return($sodes)
|
|
1857
|
+
'''
|
|
1858
|
+
sodes = await core.callStorm(q)
|
|
1859
|
+
self.len(2, sodes)
|
|
1860
|
+
self.sorteq(sodes, (expval00, expval01))
|
|
1861
|
+
|
|
1862
|
+
# prop with propvalu
|
|
1863
|
+
q = '''
|
|
1864
|
+
$sodes = ([])
|
|
1865
|
+
for ($buid, $sode) in $lib.layer.get().getStorNodesByProp(test:str:hehe, propvalu=foobaz) {
|
|
1866
|
+
$sodes.append(($buid, $sode))
|
|
1867
|
+
}
|
|
1868
|
+
return($sodes)
|
|
1869
|
+
'''
|
|
1870
|
+
sodes = await core.callStorm(q)
|
|
1871
|
+
self.len(1, sodes)
|
|
1872
|
+
self.eq(sodes[0], expval00)
|
|
1873
|
+
|
|
1874
|
+
# just form
|
|
1875
|
+
q = '''
|
|
1876
|
+
$sodes = ([])
|
|
1877
|
+
for ($buid, $sode) in $lib.layer.get().getStorNodesByProp(test:str) {
|
|
1878
|
+
$sodes.append(($buid, $sode))
|
|
1879
|
+
}
|
|
1880
|
+
return($sodes)
|
|
1881
|
+
'''
|
|
1882
|
+
sodes = await core.callStorm(q)
|
|
1883
|
+
self.len(2, sodes)
|
|
1884
|
+
self.sorteq(sodes, (expval00, expval01))
|
|
1885
|
+
|
|
1886
|
+
# form with valu
|
|
1887
|
+
q = '''
|
|
1888
|
+
$sodes = ([])
|
|
1889
|
+
for ($buid, $sode) in $lib.layer.get().getStorNodesByProp(test:str, propvalu=boobar) {
|
|
1890
|
+
$sodes.append(($buid, $sode))
|
|
1891
|
+
}
|
|
1892
|
+
return($sodes)
|
|
1893
|
+
'''
|
|
1894
|
+
sodes = await core.callStorm(q)
|
|
1895
|
+
self.len(1, sodes)
|
|
1896
|
+
self.eq(sodes[0], expval01)
|
|
1897
|
+
|
|
1898
|
+
# Non-existent prop
|
|
1899
|
+
msgs = await core.stormlist('for $item in $lib.layer.get().getStorNodesByProp(test:str:_custom) {}')
|
|
1900
|
+
self.stormIsInErr('The property test:str:_custom does not exist.', msgs)
|
|
1901
|
+
|
|
1902
|
+
async def test_storm_layer_setstornodeprop(self):
|
|
1903
|
+
async with self.getTestCore() as core:
|
|
1904
|
+
|
|
1905
|
+
nodes = await core.nodes('[ test:str=foo :hehe=bar ]')
|
|
1906
|
+
self.len(1, nodes)
|
|
1907
|
+
self.eq(nodes[0].repr(), 'foo')
|
|
1908
|
+
self.eq(nodes[0].get('hehe'), 'bar')
|
|
1909
|
+
|
|
1910
|
+
msgs = await core.stormlist('test:str $lib.layer.get().setStorNodeProp($node.iden(), test:str:hehe, baz)')
|
|
1911
|
+
self.stormHasNoWarnErr(msgs)
|
|
1912
|
+
|
|
1913
|
+
nodes = await core.nodes('test:str')
|
|
1914
|
+
self.len(1, nodes)
|
|
1915
|
+
self.eq(nodes[0].repr(), 'foo')
|
|
1916
|
+
self.eq(nodes[0].get('hehe'), 'baz')
|
|
1917
|
+
|
|
1918
|
+
# no test:str:newp prop
|
|
1919
|
+
q = '''
|
|
1920
|
+
[ test:str=foobar00 ]
|
|
1921
|
+
$lib.layer.get().setStorNodeProp($node.iden(), test:str:newp, bar00)
|
|
1922
|
+
'''
|
|
1923
|
+
msgs = await core.stormlist(q)
|
|
1924
|
+
self.stormIsInErr('No property named test:str:newp.', msgs)
|
|
1925
|
+
|
|
1926
|
+
# Bad type
|
|
1927
|
+
msgs = await core.stormlist('[ test:str=foobar01 ] $lib.layer.get().setStorNodeProp($node.iden(), test:str:tick, newp)')
|
|
1928
|
+
self.stormIsInErr('Unknown time format for newp', msgs)
|
|
1929
|
+
|
|
1930
|
+
# insufficient perms
|
|
1931
|
+
lowuser = await core.auth.addUser('lowuser')
|
|
1932
|
+
await lowuser.addRule((True, ('node', 'add', 'test:str')))
|
|
1933
|
+
|
|
1934
|
+
q = '''
|
|
1935
|
+
[ test:str=foobar02 ]
|
|
1936
|
+
$lib.layer.get().setStorNodeProp($node.iden(), test:str:hehe, baz02)
|
|
1937
|
+
'''
|
|
1938
|
+
msgs = await core.stormlist(q, opts={'user': lowuser.iden})
|
|
1939
|
+
self.stormIsInErr('setStorNodeProp() requires admin privileges.', msgs)
|
|
1940
|
+
|
|
1941
|
+
# readonly layer
|
|
1942
|
+
layer = core.view.layers[0]
|
|
1943
|
+
await layer.setLayerInfo('readonly', True)
|
|
1944
|
+
msgs = await core.stormlist('test:str $lib.layer.get().setStorNodeProp($node.iden(), test:str:hehe, baz)')
|
|
1945
|
+
self.stormIsInErr(f'Layer {layer.iden} is read only!', msgs)
|
|
1946
|
+
|
|
1947
|
+
async def test_storm_layer_delstornode(self):
|
|
1948
|
+
async with self.getTestCore() as core:
|
|
1949
|
+
await core.addTagProp('score00', ('int', {}), {})
|
|
1950
|
+
await core.addTagProp('score01', ('int', {}), {})
|
|
1951
|
+
q = '''
|
|
1952
|
+
[ test:str=foo
|
|
1953
|
+
:hehe=bar
|
|
1954
|
+
+#foo
|
|
1955
|
+
+#foo.bar=now
|
|
1956
|
+
+#foo.baz:score00=10
|
|
1957
|
+
+#foo.baz:score01=20
|
|
1958
|
+
|
|
1959
|
+
<(seen)+ {[ meta:source=* :name=seen]}
|
|
1960
|
+
+(refs)> {[ meta:source=* :name=refs]}
|
|
1961
|
+
]
|
|
1962
|
+
|
|
1963
|
+
$node.data.set(foo, foo)
|
|
1964
|
+
$node.data.set(bar, bar)
|
|
1965
|
+
$node.data.set(baz, baz)
|
|
1966
|
+
'''
|
|
1967
|
+
nodes = await core.nodes(q)
|
|
1968
|
+
self.len(1, nodes)
|
|
1969
|
+
opts = {'vars': {'iden': nodes[0].iden()}}
|
|
1970
|
+
created = nodes[0].get('.created')
|
|
1971
|
+
foobar = nodes[0].get('#foo.bar')
|
|
1972
|
+
|
|
1973
|
+
sode = await core.callStorm('return($lib.layer.get().getStorNode($iden))', opts=opts)
|
|
1974
|
+
self.eq(sode, {
|
|
1975
|
+
'form': 'test:str',
|
|
1976
|
+
'props': {'.created': (created, 21), 'hehe': ('bar', 1)},
|
|
1977
|
+
'tagprops': {
|
|
1978
|
+
'foo.baz': {
|
|
1979
|
+
'score00': (10, 9),
|
|
1980
|
+
'score01': (20, 9)
|
|
1981
|
+
}
|
|
1982
|
+
},
|
|
1983
|
+
'tags': {
|
|
1984
|
+
'foo': (None, None),
|
|
1985
|
+
'foo.bar': foobar,
|
|
1986
|
+
'foo.baz': (None, None)
|
|
1987
|
+
},
|
|
1988
|
+
'valu': ('foo', 1)
|
|
1989
|
+
})
|
|
1990
|
+
|
|
1991
|
+
msgs = await core.stormlist('$lib.layer.get().delStorNode($iden)', opts=opts)
|
|
1992
|
+
self.stormHasNoWarnErr(msgs)
|
|
1993
|
+
|
|
1994
|
+
sode = await core.callStorm('return($lib.layer.get().getStorNode($iden))', opts=opts)
|
|
1995
|
+
self.eq(sode, {})
|
|
1996
|
+
|
|
1997
|
+
q = '''
|
|
1998
|
+
$data = ([])
|
|
1999
|
+
for $item in $lib.layer.get().getNodeData($iden) {
|
|
2000
|
+
$data.append($item)
|
|
2001
|
+
}
|
|
2002
|
+
return($data)
|
|
2003
|
+
'''
|
|
2004
|
+
nodedata = await core.callStorm(q, opts=opts)
|
|
2005
|
+
self.len(0, nodedata)
|
|
2006
|
+
|
|
2007
|
+
q = '''
|
|
2008
|
+
$edges = ([])
|
|
2009
|
+
for $edge in $lib.layer.get().getEdgesByN1($iden) {
|
|
2010
|
+
$edges.append($edge)
|
|
2011
|
+
}
|
|
2012
|
+
for $edge in $lib.layer.get().getEdgesByN2($iden) {
|
|
2013
|
+
$edges.append($edge)
|
|
2014
|
+
}
|
|
2015
|
+
return($edges)
|
|
2016
|
+
'''
|
|
2017
|
+
edges = await core.callStorm(q, opts=opts)
|
|
2018
|
+
self.len(0, edges)
|
|
2019
|
+
|
|
2020
|
+
self.false(await core.callStorm('return($lib.layer.get().delStorNode($iden))', opts=opts))
|
|
2021
|
+
|
|
2022
|
+
# insufficient perms
|
|
2023
|
+
lowuser = await core.auth.addUser('lowuser')
|
|
2024
|
+
await lowuser.addRule((True, ('node', 'add', 'test:str')))
|
|
2025
|
+
|
|
2026
|
+
q = '''
|
|
2027
|
+
[ test:str=foobar02 ]
|
|
2028
|
+
$lib.layer.get().delStorNode($node.iden())
|
|
2029
|
+
'''
|
|
2030
|
+
msgs = await core.stormlist(q, opts={'user': lowuser.iden})
|
|
2031
|
+
self.stormIsInErr('delStorNode() requires admin privileges.', msgs)
|
|
2032
|
+
|
|
2033
|
+
# Readonly layer
|
|
2034
|
+
nodes = await core.nodes('[ test:str=foobar ]')
|
|
2035
|
+
self.len(1, nodes)
|
|
2036
|
+
self.eq(nodes[0].repr(), 'foobar')
|
|
2037
|
+
layer = core.view.layers[0]
|
|
2038
|
+
await layer.setLayerInfo('readonly', True)
|
|
2039
|
+
msgs = await core.stormlist('test:str $lib.layer.get().delStorNode($node.iden())')
|
|
2040
|
+
self.stormIsInErr(f'Layer {layer.iden} is read only!', msgs)
|
|
2041
|
+
|
|
2042
|
+
async def test_storm_layer_delstornodeprop(self):
|
|
2043
|
+
async with self.getTestCore() as core:
|
|
2044
|
+
nodes = await core.nodes('[ test:str=foo :hehe=bar ]')
|
|
2045
|
+
self.len(1, nodes)
|
|
2046
|
+
self.eq(nodes[0].repr(), 'foo')
|
|
2047
|
+
self.eq(nodes[0].get('hehe'), 'bar')
|
|
2048
|
+
|
|
2049
|
+
msgs = await core.stormlist('test:str $lib.layer.get().delStorNodeProp($node.iden(), test:str:hehe)')
|
|
2050
|
+
self.stormHasNoWarnErr(msgs)
|
|
2051
|
+
|
|
2052
|
+
nodes = await core.nodes('test:str')
|
|
2053
|
+
self.len(1, nodes)
|
|
2054
|
+
self.eq(nodes[0].repr(), 'foo')
|
|
2055
|
+
self.none(nodes[0].get('hehe'))
|
|
2056
|
+
|
|
2057
|
+
# no test:str:newp prop
|
|
2058
|
+
q = '''
|
|
2059
|
+
[ test:str=foobar00 ]
|
|
2060
|
+
$lib.layer.get().delStorNodeProp($node.iden(), test:str:newp)
|
|
2061
|
+
'''
|
|
2062
|
+
msgs = await core.stormlist(q)
|
|
2063
|
+
self.stormIsInErr('No property named test:str:newp.', msgs)
|
|
2064
|
+
|
|
2065
|
+
# insufficient perms
|
|
2066
|
+
lowuser = await core.auth.addUser('lowuser')
|
|
2067
|
+
await lowuser.addRule((True, ('node', 'add', 'test:str')))
|
|
2068
|
+
|
|
2069
|
+
q = '''
|
|
2070
|
+
[ test:str=foobar02 ]
|
|
2071
|
+
$lib.layer.get().delStorNodeProp($node.iden(), test:str:hehe)
|
|
2072
|
+
'''
|
|
2073
|
+
msgs = await core.stormlist(q, opts={'user': lowuser.iden})
|
|
2074
|
+
self.stormIsInErr('delStorNodeProp() requires admin privileges.', msgs)
|
|
2075
|
+
|
|
2076
|
+
# Readonly layer
|
|
2077
|
+
layer = core.view.layers[0]
|
|
2078
|
+
await layer.setLayerInfo('readonly', True)
|
|
2079
|
+
msgs = await core.stormlist('test:str $lib.layer.get().delStorNodeProp($node.iden(), test:str:hehe)')
|
|
2080
|
+
self.stormIsInErr(f'Layer {layer.iden} is read only!', msgs)
|
|
2081
|
+
|
|
2082
|
+
async def test_storm_layer_delnodedata(self):
|
|
2083
|
+
async with self.getTestCore() as core:
|
|
2084
|
+
q = '''
|
|
2085
|
+
$_ = { [test:str=foo] $node.data.set(foo, woot) }
|
|
2086
|
+
$_ = { [test:str=bar] $node.data.set(bar00, woot00) $node.data.set(bar01, woot01)}
|
|
2087
|
+
$_ = { [test:str=baz] $node.data.set(baz, woot) }
|
|
2088
|
+
'''
|
|
2089
|
+
msgs = await core.stormlist(q)
|
|
2090
|
+
self.stormHasNoWarnErr(msgs)
|
|
2091
|
+
|
|
2092
|
+
nodes = await core.nodes('test:str=foo')
|
|
2093
|
+
self.len(1, nodes)
|
|
2094
|
+
self.eq(nodes[0].repr(), 'foo')
|
|
2095
|
+
self.eq(await s_test.alist(nodes[0].iterData()), [('foo', 'woot')])
|
|
2096
|
+
|
|
2097
|
+
# Delete specific nodedata key
|
|
2098
|
+
msgs = await core.stormlist('test:str $lib.layer.get().delNodeData($node, foo)')
|
|
2099
|
+
self.stormHasNoWarnErr(msgs)
|
|
2100
|
+
|
|
2101
|
+
nodes = await core.nodes('test:str=foo')
|
|
2102
|
+
self.len(1, nodes)
|
|
2103
|
+
self.len(0, await s_test.alist(nodes[0].iterData()))
|
|
2104
|
+
|
|
2105
|
+
nodes = await core.nodes('test:str=bar')
|
|
2106
|
+
self.len(1, nodes)
|
|
2107
|
+
self.eq(nodes[0].repr(), 'bar')
|
|
2108
|
+
self.eq(await s_test.alist(nodes[0].iterData()), [('bar00', 'woot00'), ('bar01', 'woot01')])
|
|
2109
|
+
|
|
2110
|
+
# Delete all nodedata
|
|
2111
|
+
msgs = await core.stormlist('test:str=bar $lib.layer.get().delNodeData($node)')
|
|
2112
|
+
self.stormHasNoWarnErr(msgs)
|
|
2113
|
+
|
|
2114
|
+
nodes = await core.nodes('test:str=bar')
|
|
2115
|
+
self.len(1, nodes)
|
|
2116
|
+
self.len(0, await s_test.alist(nodes[0].iterData()))
|
|
2117
|
+
|
|
2118
|
+
# No edits to make
|
|
2119
|
+
self.false(await core.callStorm('test:str=bar return($lib.layer.get().delNodeData($node))'))
|
|
2120
|
+
|
|
2121
|
+
# insufficient perms
|
|
2122
|
+
lowuser = await core.auth.addUser('lowuser')
|
|
2123
|
+
await lowuser.addRule((True, ('node', 'add', 'test:str')))
|
|
2124
|
+
|
|
2125
|
+
q = '''
|
|
2126
|
+
test:str
|
|
2127
|
+
$lib.layer.get().delNodeData($node)
|
|
2128
|
+
'''
|
|
2129
|
+
msgs = await core.stormlist(q, opts={'user': lowuser.iden})
|
|
2130
|
+
self.stormIsInErr('delNodeData() requires admin privileges.', msgs)
|
|
2131
|
+
|
|
2132
|
+
# Readonly layer
|
|
2133
|
+
layer = core.view.layers[0]
|
|
2134
|
+
await layer.setLayerInfo('readonly', True)
|
|
2135
|
+
msgs = await core.stormlist('test:str=baz $lib.layer.get().delNodeData($node)')
|
|
2136
|
+
self.stormIsInErr(f'Layer {layer.iden} is read only!', msgs)
|
|
2137
|
+
|
|
2138
|
+
async def test_storm_layer_delnodeedge(self):
|
|
2139
|
+
async with self.getTestCore() as core:
|
|
2140
|
+
q = '''
|
|
2141
|
+
$seen00 = { [ meta:source=* :name=delnodeedge00 ] }
|
|
2142
|
+
$seen01 = { [ meta:source=* :name=delnodeedge01 ] }
|
|
2143
|
+
$refs = { [ it:dev:str=foobar ] }
|
|
2144
|
+
$_ = { [test:str=foo <(seen)+ $seen00 <(seen)+ $seen01]}
|
|
2145
|
+
$_ = { [test:str=bar <(seen)+ $seen00 +(refs)> $refs] }
|
|
2146
|
+
$_ = { [test:str=baz] }
|
|
2147
|
+
$_ = { [test:str=woot <(seen)+ $seen00 +(refs)> $refs] }
|
|
2148
|
+
'''
|
|
2149
|
+
msgs = await core.stormlist(q)
|
|
2150
|
+
self.stormHasNoWarnErr(msgs)
|
|
2151
|
+
|
|
2152
|
+
nodes = await core.nodes('meta:source:name=delnodeedge00')
|
|
2153
|
+
self.len(1, nodes)
|
|
2154
|
+
seen00 = nodes[0]
|
|
2155
|
+
|
|
2156
|
+
nodes = await core.nodes('meta:source:name=delnodeedge01')
|
|
2157
|
+
self.len(1, nodes)
|
|
2158
|
+
seen01 = nodes[0]
|
|
2159
|
+
|
|
2160
|
+
nodes = await core.nodes('it:dev:str=foobar')
|
|
2161
|
+
self.len(1, nodes)
|
|
2162
|
+
refs = nodes[0]
|
|
2163
|
+
|
|
2164
|
+
# Delete n2 edge
|
|
2165
|
+
nodes = await core.nodes('test:str=foo')
|
|
2166
|
+
self.len(1, nodes)
|
|
2167
|
+
self.len(0, await s_test.alist(nodes[0].iterEdgesN1()))
|
|
2168
|
+
self.sorteq(await s_test.alist(nodes[0].iterEdgesN2()), [('seen', seen00.iden()), ('seen', seen01.iden())])
|
|
2169
|
+
|
|
2170
|
+
q = '''
|
|
2171
|
+
$seen00 = { meta:source:name=delnodeedge00 }
|
|
2172
|
+
test:str=foo
|
|
2173
|
+
$lib.layer.get().delEdge($seen00, seen, $node)
|
|
2174
|
+
'''
|
|
2175
|
+
msgs = await core.stormlist(q)
|
|
2176
|
+
self.stormHasNoWarnErr(msgs)
|
|
2177
|
+
|
|
2178
|
+
nodes = await core.nodes('test:str=foo')
|
|
2179
|
+
self.len(1, nodes)
|
|
2180
|
+
self.len(0, await s_test.alist(nodes[0].iterEdgesN1()))
|
|
2181
|
+
self.eq(await s_test.alist(nodes[0].iterEdgesN2()), [('seen', seen01.iden())])
|
|
2182
|
+
|
|
2183
|
+
# Delete n1 edge
|
|
2184
|
+
nodes = await core.nodes('test:str=bar')
|
|
2185
|
+
self.len(1, nodes)
|
|
2186
|
+
self.sorteq(await s_test.alist(nodes[0].iterEdgesN1()), [('refs', refs.iden())])
|
|
2187
|
+
self.sorteq(await s_test.alist(nodes[0].iterEdgesN2()), [('seen', seen00.iden())])
|
|
2188
|
+
|
|
2189
|
+
q = '''
|
|
2190
|
+
$refs = { it:dev:str=foobar }
|
|
2191
|
+
test:str=bar
|
|
2192
|
+
$lib.layer.get().delEdge($node, refs, $refs)
|
|
2193
|
+
'''
|
|
2194
|
+
msgs = await core.stormlist(q)
|
|
2195
|
+
self.stormHasNoWarnErr(msgs)
|
|
2196
|
+
|
|
2197
|
+
nodes = await core.nodes('test:str=bar')
|
|
2198
|
+
self.len(1, nodes)
|
|
2199
|
+
self.len(0, await s_test.alist(nodes[0].iterEdgesN1()))
|
|
2200
|
+
self.eq(await s_test.alist(nodes[0].iterEdgesN2()), [('seen', seen00.iden())])
|
|
2201
|
+
|
|
2202
|
+
# No edits to make
|
|
2203
|
+
nodes = await core.nodes('test:str=baz')
|
|
2204
|
+
self.len(1, nodes)
|
|
2205
|
+
self.len(0, await s_test.alist(nodes[0].iterEdgesN1()))
|
|
2206
|
+
self.len(0, await s_test.alist(nodes[0].iterEdgesN2()))
|
|
2207
|
+
|
|
2208
|
+
q = '''
|
|
2209
|
+
$refs = { it:dev:str=foobar }
|
|
2210
|
+
test:str=baz
|
|
2211
|
+
$lib.layer.get().delEdge($node, refs, $refs)
|
|
2212
|
+
'''
|
|
2213
|
+
msgs = await core.stormlist(q)
|
|
2214
|
+
self.stormHasNoWarnErr(msgs)
|
|
2215
|
+
|
|
2216
|
+
# insufficient perms
|
|
2217
|
+
lowuser = await core.auth.addUser('lowuser')
|
|
2218
|
+
await lowuser.addRule((True, ('node', 'add', 'test:str')))
|
|
2219
|
+
|
|
2220
|
+
nodes = await core.nodes('test:str=woot')
|
|
2221
|
+
self.len(1, nodes)
|
|
2222
|
+
self.len(1, await s_test.alist(nodes[0].iterEdgesN1()))
|
|
2223
|
+
self.len(1, await s_test.alist(nodes[0].iterEdgesN2()))
|
|
2224
|
+
|
|
2225
|
+
q = '''
|
|
2226
|
+
$seen = { meta:source:name=delnodeedge00 }
|
|
2227
|
+
test:str=woot
|
|
2228
|
+
$lib.layer.get().delEdge($seen, seen, $node)
|
|
2229
|
+
'''
|
|
2230
|
+
msgs = await core.stormlist(q, opts={'user': lowuser.iden})
|
|
2231
|
+
self.stormIsInErr('delEdge() requires admin privileges.', msgs)
|
|
2232
|
+
|
|
2233
|
+
nodes = await core.nodes('test:str=woot')
|
|
2234
|
+
self.len(1, nodes)
|
|
2235
|
+
self.len(1, await s_test.alist(nodes[0].iterEdgesN1()))
|
|
2236
|
+
self.len(1, await s_test.alist(nodes[0].iterEdgesN2()))
|
|
2237
|
+
|
|
2238
|
+
# Readonly layer
|
|
2239
|
+
layer = core.view.layers[0]
|
|
2240
|
+
await layer.setLayerInfo('readonly', True)
|
|
2241
|
+
msgs = await core.stormlist(q)
|
|
2242
|
+
self.stormIsInErr(f'Layer {layer.iden} is read only!', msgs)
|
|
2243
|
+
|
|
2244
|
+
nodes = await core.nodes('test:str=woot')
|
|
2245
|
+
self.len(1, nodes)
|
|
2246
|
+
self.len(1, await s_test.alist(nodes[0].iterEdgesN1()))
|
|
2247
|
+
self.len(1, await s_test.alist(nodes[0].iterEdgesN2()))
|
|
2248
|
+
|
|
1738
2249
|
async def test_storm_lib_fire(self):
|
|
1739
2250
|
async with self.getTestCore() as core:
|
|
1740
2251
|
text = '$lib.fire(foo:bar, baz=faz)'
|
|
@@ -5639,6 +6150,76 @@ class StormTypesTest(s_test.SynTest):
|
|
|
5639
6150
|
q = '$tally = $lib.stats.tally() $tally.inc(foo) $tally.inc(foo) return($tally)'
|
|
5640
6151
|
self.eq({'foo': 2}, await core.callStorm(q))
|
|
5641
6152
|
|
|
6153
|
+
async def test_stormtypes_tobuid(self):
|
|
6154
|
+
async with self.getTestCore() as core:
|
|
6155
|
+
|
|
6156
|
+
buid = s_common.buid()
|
|
6157
|
+
sode = (
|
|
6158
|
+
buid,
|
|
6159
|
+
{
|
|
6160
|
+
'ndef': ('it:dev:str', 'foobar'),
|
|
6161
|
+
}
|
|
6162
|
+
)
|
|
6163
|
+
|
|
6164
|
+
async with await core.snap() as snap:
|
|
6165
|
+
node = s_node.Node(snap, sode)
|
|
6166
|
+
snode = s_stormtypes.Node(node)
|
|
6167
|
+
|
|
6168
|
+
self.eq(await s_stormtypes.tobuid(node), buid)
|
|
6169
|
+
self.eq(await s_stormtypes.tobuid(snode), buid)
|
|
6170
|
+
|
|
6171
|
+
self.eq(await s_stormtypes.tobuid(buid.hex()), buid)
|
|
6172
|
+
self.eq(await s_stormtypes.tobuid(buid), buid)
|
|
6173
|
+
|
|
6174
|
+
with self.raises(s_exc.BadCast) as exc:
|
|
6175
|
+
await s_stormtypes.tobuid('newp')
|
|
6176
|
+
self.eq(exc.exception.get('mesg'), 'Invalid buid string: newp')
|
|
6177
|
+
|
|
6178
|
+
with self.raises(s_exc.BadCast) as exc:
|
|
6179
|
+
await s_stormtypes.tobuid([])
|
|
6180
|
+
self.eq(exc.exception.get('mesg'), 'Invalid buid valu: ()')
|
|
6181
|
+
|
|
6182
|
+
with self.raises(s_exc.BadCast) as exc:
|
|
6183
|
+
await s_stormtypes.tobuid(b'newp')
|
|
6184
|
+
self.eq(exc.exception.get('mesg'), "Invalid buid valu: b'newp'")
|
|
6185
|
+
|
|
6186
|
+
async def test_stormtypes_tobuidhex(self):
|
|
6187
|
+
async with self.getTestCore() as core:
|
|
6188
|
+
|
|
6189
|
+
self.none(await s_stormtypes.tobuidhex(None, noneok=True))
|
|
6190
|
+
|
|
6191
|
+
buid = s_common.buid()
|
|
6192
|
+
buidhex = s_common.ehex(buid)
|
|
6193
|
+
sode = (
|
|
6194
|
+
buid,
|
|
6195
|
+
{
|
|
6196
|
+
'ndef': ('it:dev:str', 'foobar'),
|
|
6197
|
+
}
|
|
6198
|
+
)
|
|
6199
|
+
|
|
6200
|
+
async with await core.snap() as snap:
|
|
6201
|
+
node = s_node.Node(snap, sode)
|
|
6202
|
+
snode = s_stormtypes.Node(node)
|
|
6203
|
+
|
|
6204
|
+
self.eq(await s_stormtypes.tobuidhex(node), buidhex)
|
|
6205
|
+
self.eq(await s_stormtypes.tobuidhex(snode), buidhex)
|
|
6206
|
+
|
|
6207
|
+
self.eq(await s_stormtypes.tobuidhex(buidhex), buidhex)
|
|
6208
|
+
self.eq(await s_stormtypes.tobuidhex(buid), buidhex)
|
|
6209
|
+
|
|
6210
|
+
with self.raises(s_exc.BadCast) as exc:
|
|
6211
|
+
await s_stormtypes.tobuidhex('newp')
|
|
6212
|
+
self.eq(exc.exception.get('mesg'), 'Invalid buid string: newp')
|
|
6213
|
+
|
|
6214
|
+
with self.raises(s_exc.BadCast) as exc:
|
|
6215
|
+
await s_stormtypes.tobuidhex([])
|
|
6216
|
+
self.eq(exc.exception.get('mesg'), 'Invalid buid valu: ()')
|
|
6217
|
+
|
|
6218
|
+
newp = b'newp'
|
|
6219
|
+
with self.raises(s_exc.BadCast) as exc:
|
|
6220
|
+
await s_stormtypes.tobuidhex(newp)
|
|
6221
|
+
self.eq(exc.exception.get('mesg'), "Invalid buid valu: b'newp'")
|
|
6222
|
+
|
|
5642
6223
|
async def test_print_warn(self):
|
|
5643
6224
|
async with self.getTestCore() as core:
|
|
5644
6225
|
q = '$lib.print(hello)'
|
synapse/tools/aha/list.py
CHANGED
|
@@ -7,14 +7,17 @@ import synapse.lib.version as s_version
|
|
|
7
7
|
|
|
8
8
|
reqver = '>=2.11.0,<3.0.0'
|
|
9
9
|
|
|
10
|
+
descr = 'List AHA services.'
|
|
11
|
+
|
|
10
12
|
async def main(argv, outp=s_output.stdout):
|
|
11
13
|
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
14
|
+
pars = s_cmd.Parser(prog='synapse.tools.aha.list', outp=outp, description=descr)
|
|
15
|
+
pars.add_argument('url', help='The telepath URL to connect to the AHA service.')
|
|
16
|
+
pars.add_argument('network', nargs='?', default=None, help='The AHA network name.')
|
|
17
|
+
opts = pars.parse_args(argv)
|
|
15
18
|
|
|
16
19
|
async with s_telepath.withTeleEnv():
|
|
17
|
-
async with await s_telepath.openurl(
|
|
20
|
+
async with await s_telepath.openurl(opts.url) as prox:
|
|
18
21
|
try:
|
|
19
22
|
s_version.reqVersion(prox._getSynVers(), reqver)
|
|
20
23
|
except s_exc.BadVersion as e: # pragma: no cover
|
|
@@ -23,13 +26,10 @@ async def main(argv, outp=s_output.stdout):
|
|
|
23
26
|
return 1
|
|
24
27
|
classes = prox._getClasses()
|
|
25
28
|
if 'synapse.lib.aha.AhaApi' not in classes:
|
|
26
|
-
outp.printf(f'Service at {
|
|
29
|
+
outp.printf(f'Service at {opts.url} is not an Aha server')
|
|
27
30
|
return 1
|
|
28
31
|
|
|
29
|
-
|
|
30
|
-
network = argv[1]
|
|
31
|
-
except IndexError:
|
|
32
|
-
network = None
|
|
32
|
+
network = opts.network
|
|
33
33
|
|
|
34
34
|
mesg = f"{'Service':<20s} {'network':<30s} {'leader':<6} {'online':<6} {'scheme':<6} {'host':<20} {'port':<5} connection opts"
|
|
35
35
|
outp.printf(mesg)
|