synapse 2.164.0__py311-none-any.whl → 2.166.0__py311-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Potentially problematic release.
This version of synapse might be problematic. Click here for more details.
- synapse/axon.py +3 -3
- synapse/cmds/cortex.py +1 -6
- synapse/common.py +7 -1
- synapse/cortex.py +145 -192
- synapse/datamodel.py +36 -1
- synapse/lib/agenda.py +87 -97
- synapse/lib/aha.py +51 -0
- synapse/lib/ast.py +22 -23
- synapse/lib/base.py +0 -6
- synapse/lib/boss.py +3 -0
- synapse/lib/cell.py +70 -39
- synapse/lib/certdir.py +9 -0
- synapse/lib/hiveauth.py +65 -12
- synapse/lib/httpapi.py +1 -0
- synapse/lib/modelrev.py +121 -33
- synapse/lib/modules.py +1 -0
- synapse/lib/nexus.py +64 -26
- synapse/lib/parser.py +2 -0
- synapse/lib/schemas.py +14 -0
- synapse/lib/snap.py +50 -4
- synapse/lib/storm.lark +4 -3
- synapse/lib/storm.py +96 -22
- synapse/lib/storm_format.py +1 -0
- synapse/lib/stormlib/aha.py +7 -1
- synapse/lib/stormlib/auth.py +13 -5
- synapse/lib/stormlib/cache.py +202 -0
- synapse/lib/stormlib/cortex.py +147 -8
- synapse/lib/stormlib/gen.py +53 -6
- synapse/lib/stormlib/math.py +1 -1
- synapse/lib/stormlib/model.py +11 -1
- synapse/lib/stormlib/spooled.py +109 -0
- synapse/lib/stormlib/vault.py +1 -1
- synapse/lib/stormtypes.py +113 -17
- synapse/lib/trigger.py +36 -47
- synapse/lib/types.py +29 -2
- synapse/lib/version.py +2 -2
- synapse/lib/view.py +80 -53
- synapse/models/economic.py +174 -5
- synapse/models/files.py +2 -0
- synapse/models/inet.py +77 -2
- synapse/models/infotech.py +12 -12
- synapse/models/orgs.py +72 -21
- synapse/models/person.py +40 -11
- synapse/models/risk.py +78 -24
- synapse/models/science.py +102 -0
- synapse/telepath.py +117 -35
- synapse/tests/test_cortex.py +84 -158
- synapse/tests/test_datamodel.py +22 -0
- synapse/tests/test_lib_agenda.py +52 -96
- synapse/tests/test_lib_aha.py +126 -4
- synapse/tests/test_lib_ast.py +412 -6
- synapse/tests/test_lib_cell.py +24 -8
- synapse/tests/test_lib_certdir.py +32 -0
- synapse/tests/test_lib_grammar.py +9 -1
- synapse/tests/test_lib_httpapi.py +0 -1
- synapse/tests/test_lib_jupyter.py +0 -1
- synapse/tests/test_lib_modelrev.py +41 -0
- synapse/tests/test_lib_nexus.py +38 -0
- synapse/tests/test_lib_storm.py +95 -5
- synapse/tests/test_lib_stormlib_cache.py +272 -0
- synapse/tests/test_lib_stormlib_cortex.py +71 -0
- synapse/tests/test_lib_stormlib_gen.py +37 -2
- synapse/tests/test_lib_stormlib_model.py +2 -0
- synapse/tests/test_lib_stormlib_spooled.py +190 -0
- synapse/tests/test_lib_stormlib_vault.py +12 -3
- synapse/tests/test_lib_stormsvc.py +0 -10
- synapse/tests/test_lib_stormtypes.py +60 -8
- synapse/tests/test_lib_trigger.py +20 -2
- synapse/tests/test_lib_types.py +17 -1
- synapse/tests/test_model_economic.py +114 -0
- synapse/tests/test_model_files.py +2 -0
- synapse/tests/test_model_inet.py +73 -1
- synapse/tests/test_model_infotech.py +2 -2
- synapse/tests/test_model_orgs.py +10 -1
- synapse/tests/test_model_risk.py +30 -2
- synapse/tests/test_model_science.py +59 -0
- synapse/tests/test_model_syn.py +0 -1
- synapse/tests/test_telepath.py +30 -7
- synapse/tests/test_tools_modrole.py +81 -0
- synapse/tests/test_tools_moduser.py +105 -0
- synapse/tools/modrole.py +59 -7
- synapse/tools/moduser.py +78 -10
- {synapse-2.164.0.dist-info → synapse-2.166.0.dist-info}/METADATA +2 -2
- {synapse-2.164.0.dist-info → synapse-2.166.0.dist-info}/RECORD +87 -83
- {synapse-2.164.0.dist-info → synapse-2.166.0.dist-info}/WHEEL +1 -1
- synapse/lib/provenance.py +0 -111
- synapse/tests/test_lib_provenance.py +0 -37
- {synapse-2.164.0.dist-info → synapse-2.166.0.dist-info}/LICENSE +0 -0
- {synapse-2.164.0.dist-info → synapse-2.166.0.dist-info}/top_level.txt +0 -0
synapse/tests/test_lib_aha.py
CHANGED
|
@@ -186,8 +186,8 @@ class AhaTest(s_test.SynTest):
|
|
|
186
186
|
self.nn(await proxy.getCellIden())
|
|
187
187
|
|
|
188
188
|
with self.raises(s_exc.BadArg):
|
|
189
|
-
await cryo.ahaclient.
|
|
190
|
-
await
|
|
189
|
+
_proxy = await cryo.ahaclient.proxy(timeout=2)
|
|
190
|
+
await _proxy.modAhaSvcInfo('cryo.mynet', {'newp': 'newp'})
|
|
191
191
|
|
|
192
192
|
async with await s_telepath.openurl('aha://root:secret@0.cryo.mynet') as proxy:
|
|
193
193
|
self.nn(await proxy.getCellIden())
|
|
@@ -885,6 +885,27 @@ class AhaTest(s_test.SynTest):
|
|
|
885
885
|
self.isin('Provisioning aha:network must be equal to the Aha servers network',
|
|
886
886
|
cm.exception.get('mesg'))
|
|
887
887
|
|
|
888
|
+
# We can generate urls and then drop them en-mass. They will not usable.
|
|
889
|
+
provurls = []
|
|
890
|
+
enrlursl = []
|
|
891
|
+
async with aha.getLocalProxy() as proxy:
|
|
892
|
+
provurls.append(await proxy.addAhaSvcProv('00.cell'))
|
|
893
|
+
provurls.append(await proxy.addAhaSvcProv('01.cell', {'mirror': 'cell'}))
|
|
894
|
+
enrlursl.append(await proxy.addAhaUserEnroll('bob'))
|
|
895
|
+
enrlursl.append(await proxy.addAhaUserEnroll('alice'))
|
|
896
|
+
|
|
897
|
+
await proxy.clearAhaSvcProvs()
|
|
898
|
+
await proxy.clearAhaUserEnrolls()
|
|
899
|
+
|
|
900
|
+
for url in provurls:
|
|
901
|
+
with self.raises(s_exc.NoSuchName) as cm:
|
|
902
|
+
async with await s_telepath.openurl(url) as client:
|
|
903
|
+
self.fail(f'Connected to an expired provisioning URL {url}') # pragma: no cover
|
|
904
|
+
for url in enrlursl:
|
|
905
|
+
with self.raises(s_exc.NoSuchName) as cm:
|
|
906
|
+
async with await s_telepath.openurl(url) as prox:
|
|
907
|
+
self.fail(f'Connected to an expired enrollment URL {url}') # pragma: no cover
|
|
908
|
+
|
|
888
909
|
async def test_aha_httpapi(self):
|
|
889
910
|
|
|
890
911
|
conf = {
|
|
@@ -1148,13 +1169,24 @@ class AhaTest(s_test.SynTest):
|
|
|
1148
1169
|
self.stormHasNoWarnErr(msgs)
|
|
1149
1170
|
self.stormIsInPrint('Created AHA service pool: pool00.loop.vertex.link', msgs)
|
|
1150
1171
|
|
|
1151
|
-
|
|
1152
|
-
|
|
1172
|
+
# Pool has no members....
|
|
1173
|
+
pool = await s_telepath.open('aha://pool00...')
|
|
1174
|
+
self.eq(0, pool.size())
|
|
1175
|
+
waiter = pool.waiter(0, 'svc:add')
|
|
1153
1176
|
|
|
1154
1177
|
msgs = await core00.stormlist('aha.pool.svc.add pool00... 00...')
|
|
1155
1178
|
self.stormHasNoWarnErr(msgs)
|
|
1156
1179
|
self.stormIsInPrint('AHA service (00...) added to service pool (pool00.loop.vertex.link)', msgs)
|
|
1157
1180
|
|
|
1181
|
+
self.len(1, await waiter.wait(timeout=12))
|
|
1182
|
+
prox = await pool.proxy(timeout=12)
|
|
1183
|
+
info = await prox.getCellInfo()
|
|
1184
|
+
self.eq('00', info.get('cell').get('aha').get('name'))
|
|
1185
|
+
self.eq(1, pool.size())
|
|
1186
|
+
await pool.fini()
|
|
1187
|
+
self.eq(0, pool.size())
|
|
1188
|
+
self.true(prox.isfini)
|
|
1189
|
+
|
|
1158
1190
|
poolinfo = await aha.getAhaPool('pool00...')
|
|
1159
1191
|
self.len(1, poolinfo['services'])
|
|
1160
1192
|
|
|
@@ -1163,6 +1195,9 @@ class AhaTest(s_test.SynTest):
|
|
|
1163
1195
|
self.stormIsInPrint(' 00.loop.vertex.link', msgs)
|
|
1164
1196
|
self.stormIsInPrint('1 pools', msgs)
|
|
1165
1197
|
|
|
1198
|
+
msgs = await core00.stormlist('$lib.print($lib.aha.pool.get(pool00.loop.vertex.link))')
|
|
1199
|
+
self.stormIsInPrint('aha:pool: pool00.loop.vertex.link', msgs)
|
|
1200
|
+
|
|
1166
1201
|
async with await s_telepath.open('aha://pool00...') as pool:
|
|
1167
1202
|
|
|
1168
1203
|
replay = s_common.envbool('SYNDEV_NEXUS_REPLAY')
|
|
@@ -1320,3 +1355,90 @@ class AhaTest(s_test.SynTest):
|
|
|
1320
1355
|
svcinfo = snfo.get('svcinfo')
|
|
1321
1356
|
ready = svcinfo.get('ready')
|
|
1322
1357
|
self.true(ready)
|
|
1358
|
+
|
|
1359
|
+
async def test_aha_provision_longname(self):
|
|
1360
|
+
# Run a long network name and try provisioning with values that would exceed CSR
|
|
1361
|
+
# and certificate functionality.
|
|
1362
|
+
with self.withNexusReplay() as stack:
|
|
1363
|
+
|
|
1364
|
+
with self.getTestDir() as dirn:
|
|
1365
|
+
aha00dirn = s_common.gendir(dirn, 'aha00')
|
|
1366
|
+
svc0dirn = s_common.gendir(dirn, 'svc00')
|
|
1367
|
+
async with await s_base.Base.anit() as cm:
|
|
1368
|
+
# Add enough space to allow aha CA bootstraping.
|
|
1369
|
+
basenet = 'loop.vertex.link'
|
|
1370
|
+
networkname = f'{"x" * (64 - 7 - len(basenet))}.{basenet}'
|
|
1371
|
+
aconf = {
|
|
1372
|
+
'aha:name': 'aha',
|
|
1373
|
+
'aha:network': networkname,
|
|
1374
|
+
'provision:listen': f'ssl://aha.{networkname}:0'
|
|
1375
|
+
}
|
|
1376
|
+
name = aconf.get('aha:name')
|
|
1377
|
+
netw = aconf.get('aha:network')
|
|
1378
|
+
dnsname = f'{name}.{netw}'
|
|
1379
|
+
|
|
1380
|
+
aha = await s_aha.AhaCell.anit(aha00dirn, conf=aconf)
|
|
1381
|
+
await cm.enter_context(aha)
|
|
1382
|
+
|
|
1383
|
+
addr, port = aha.provdmon.addr
|
|
1384
|
+
# update the config to reflect the dynamically bound port
|
|
1385
|
+
aha.conf['provision:listen'] = f'ssl://{dnsname}:{port}'
|
|
1386
|
+
|
|
1387
|
+
# do this config ex-post-facto due to port binding...
|
|
1388
|
+
host, ahaport = await aha.dmon.listen(f'ssl://0.0.0.0:0?hostname={dnsname}&ca={netw}')
|
|
1389
|
+
aha.conf['aha:urls'] = (f'ssl://{dnsname}:{ahaport}',)
|
|
1390
|
+
|
|
1391
|
+
with self.raises(s_exc.BadArg) as errcm:
|
|
1392
|
+
await aha.addAhaSvcProv('00.svc', provinfo=None)
|
|
1393
|
+
self.isin('Hostname value must not exceed 64 characters in length.',
|
|
1394
|
+
errcm.exception.get('mesg'))
|
|
1395
|
+
self.isin('len=65', errcm.exception.get('mesg'))
|
|
1396
|
+
|
|
1397
|
+
# We can generate a 64 character names though.
|
|
1398
|
+
onetime = await aha.addAhaSvcProv('00.sv', provinfo=None)
|
|
1399
|
+
sconf = {'aha:provision': onetime}
|
|
1400
|
+
s_common.yamlsave(sconf, svc0dirn, 'cell.yaml')
|
|
1401
|
+
svc0 = await s_cell.Cell.anit(svc0dirn, conf=sconf)
|
|
1402
|
+
await cm.enter_context(svc0)
|
|
1403
|
+
|
|
1404
|
+
# Cannot generate a user cert that would be a problem for signing
|
|
1405
|
+
with self.raises(s_exc.BadArg) as errcm:
|
|
1406
|
+
await aha.addAhaUserEnroll('ruhroh')
|
|
1407
|
+
self.isin('Username value must not exceed 64 characters in length.',
|
|
1408
|
+
errcm.exception.get('mesg'))
|
|
1409
|
+
self.isin('len=65', errcm.exception.get('mesg'))
|
|
1410
|
+
|
|
1411
|
+
# We can generate a name that is 64 characters in length and have its csr signed
|
|
1412
|
+
onetime = await aha.addAhaUserEnroll('vvvvv')
|
|
1413
|
+
async with await s_telepath.openurl(onetime) as prox:
|
|
1414
|
+
userinfo = await prox.getUserInfo()
|
|
1415
|
+
ahauser = userinfo.get('aha:user')
|
|
1416
|
+
ahanetw = userinfo.get('aha:network')
|
|
1417
|
+
username = f'{ahauser}@{ahanetw}'
|
|
1418
|
+
byts = aha.certdir.genUserCsr(username)
|
|
1419
|
+
byts = await prox.signUserCsr(byts)
|
|
1420
|
+
self.nn(byts)
|
|
1421
|
+
|
|
1422
|
+
# 0 length inputs
|
|
1423
|
+
with self.raises(s_exc.BadArg) as errcm:
|
|
1424
|
+
await aha.addAhaSvcProv('')
|
|
1425
|
+
self.isin('Empty name values are not allowed for provisioning.', errcm.exception.get('mesg'))
|
|
1426
|
+
with self.raises(s_exc.BadArg) as errcm:
|
|
1427
|
+
await aha.addAhaUserEnroll('')
|
|
1428
|
+
self.isin('Empty name values are not allowed for provisioning.', errcm.exception.get('mesg'))
|
|
1429
|
+
|
|
1430
|
+
# add an aha bootstrapping test failure
|
|
1431
|
+
with self.getTestDir() as dirn:
|
|
1432
|
+
aha00dirn = s_common.gendir(dirn, 'aha00')
|
|
1433
|
+
async with await s_base.Base.anit() as cm:
|
|
1434
|
+
# Make the network too long that we cannot bootstrap the CA
|
|
1435
|
+
basenet = 'loop.vertex.link'
|
|
1436
|
+
networkname = f'{"x" * (64 - len(basenet))}.{basenet}'
|
|
1437
|
+
aconf = {
|
|
1438
|
+
'aha:name': 'aha',
|
|
1439
|
+
'aha:network': networkname,
|
|
1440
|
+
'provision:listen': f'ssl://aha.{networkname}:0'
|
|
1441
|
+
}
|
|
1442
|
+
with self.raises(s_exc.CryptoErr) as errcm:
|
|
1443
|
+
await s_aha.AhaCell.anit(aha00dirn, conf=aconf)
|
|
1444
|
+
self.isin('Certificate name values must be between 1-64 characters', errcm.exception.get('mesg'))
|
synapse/tests/test_lib_ast.py
CHANGED
|
@@ -6,6 +6,7 @@ from unittest import mock
|
|
|
6
6
|
|
|
7
7
|
import synapse.exc as s_exc
|
|
8
8
|
import synapse.common as s_common
|
|
9
|
+
import synapse.datamodel as s_datamodel
|
|
9
10
|
|
|
10
11
|
import synapse.lib.ast as s_ast
|
|
11
12
|
import synapse.lib.snap as s_snap
|
|
@@ -16,7 +17,6 @@ foo_stormpkg = {
|
|
|
16
17
|
'name': 'foo',
|
|
17
18
|
'desc': 'The Foo Module',
|
|
18
19
|
'version': (0, 0, 1),
|
|
19
|
-
'synapse_minversion': [2, 144, 0],
|
|
20
20
|
'synapse_version': '>=2.8.0,<3.0.0',
|
|
21
21
|
'modules': [
|
|
22
22
|
{
|
|
@@ -713,6 +713,8 @@ class AstTest(s_test.SynTest):
|
|
|
713
713
|
self.len(3, await core.nodes('$form=(inet:dns:a, inet:dns:mx) inet:fqdn=vertex.link -+> $form'))
|
|
714
714
|
|
|
715
715
|
self.len(2, await core.nodes('inet:fqdn=vertex.link :zone -> (inet:dns:a:fqdn, inet:dns:mx:fqdn)'))
|
|
716
|
+
self.len(2, await core.nodes('$prop=fqdn $targ=inet:fqdn inet:dns:a* :$prop -> $targ'))
|
|
717
|
+
|
|
716
718
|
self.len(1, await core.nodes('$form=inet:dns:a:fqdn inet:fqdn=vertex.link :zone -> $form'))
|
|
717
719
|
|
|
718
720
|
self.len(3, await core.nodes('inet:fqdn=vertex.link :zone -+> (inet:dns:a:fqdn, inet:dns:mx:fqdn)'))
|
|
@@ -1216,14 +1218,12 @@ class AstTest(s_test.SynTest):
|
|
|
1216
1218
|
otherpkg = {
|
|
1217
1219
|
'name': 'foosball',
|
|
1218
1220
|
'version': '0.0.1',
|
|
1219
|
-
'synapse_minversion': [2, 144, 0],
|
|
1220
1221
|
'synapse_version': '>=2.8.0,<3.0.0',
|
|
1221
1222
|
}
|
|
1222
1223
|
|
|
1223
1224
|
stormpkg = {
|
|
1224
1225
|
'name': 'stormpkg',
|
|
1225
1226
|
'version': '1.2.3',
|
|
1226
|
-
'synapse_minversion': [2, 144, 0],
|
|
1227
1227
|
'synapse_version': '>=2.8.0,<3.0.0',
|
|
1228
1228
|
'commands': (
|
|
1229
1229
|
{
|
|
@@ -1236,7 +1236,6 @@ class AstTest(s_test.SynTest):
|
|
|
1236
1236
|
stormpkgnew = {
|
|
1237
1237
|
'name': 'stormpkg',
|
|
1238
1238
|
'version': '1.2.4',
|
|
1239
|
-
'synapse_minversion': [2, 144, 0],
|
|
1240
1239
|
'synapse_version': '>=2.8.0,<3.0.0',
|
|
1241
1240
|
'commands': (
|
|
1242
1241
|
{
|
|
@@ -1249,7 +1248,6 @@ class AstTest(s_test.SynTest):
|
|
|
1249
1248
|
jsonpkg = {
|
|
1250
1249
|
'name': 'jsonpkg',
|
|
1251
1250
|
'version': '1.2.3',
|
|
1252
|
-
'synapse_minversion': [2, 144, 0],
|
|
1253
1251
|
'synapse_version': '>=2.8.0,<3.0.0',
|
|
1254
1252
|
'docs': (
|
|
1255
1253
|
{
|
|
@@ -2365,6 +2363,12 @@ class AstTest(s_test.SynTest):
|
|
|
2365
2363
|
nodes = await core.nodes('if (false) { [inet:ipv4=1.2.3.4] }')
|
|
2366
2364
|
self.len(0, nodes)
|
|
2367
2365
|
|
|
2366
|
+
nodes = await core.nodes('if (null) { [inet:ipv4=1.2.3.4] }')
|
|
2367
|
+
self.len(0, nodes)
|
|
2368
|
+
|
|
2369
|
+
self.none(await core.callStorm('return((null))'))
|
|
2370
|
+
self.eq({'foo': None}, await core.callStorm('return(({"foo": null}))'))
|
|
2371
|
+
|
|
2368
2372
|
nodes = await core.nodes('[ test:int=(18 + 2) ]')
|
|
2369
2373
|
self.len(1, nodes)
|
|
2370
2374
|
self.eq(nodes[0].ndef, ('test:int', 20))
|
|
@@ -3549,7 +3553,17 @@ class AstTest(s_test.SynTest):
|
|
|
3549
3553
|
|
|
3550
3554
|
async def test_ast_prop_perms(self):
|
|
3551
3555
|
|
|
3552
|
-
async with self.getTestCore() as core:
|
|
3556
|
+
async with self.getTestCore() as core: # type: s_cortex.Cortex
|
|
3557
|
+
|
|
3558
|
+
# TODO: This goes away in 3.0.0 when we remove old style permissions.
|
|
3559
|
+
for key, prop in core.model.props.items():
|
|
3560
|
+
if not isinstance(prop, s_datamodel.Prop):
|
|
3561
|
+
continue
|
|
3562
|
+
if prop.isuniv:
|
|
3563
|
+
continue
|
|
3564
|
+
self.len(2, prop.delperms)
|
|
3565
|
+
self.len(2, prop.setperms)
|
|
3566
|
+
|
|
3553
3567
|
visi = (await core.addUser('visi'))['iden']
|
|
3554
3568
|
|
|
3555
3569
|
self.len(1, await core.nodes('[ inet:ipv4=1.2.3.4 :asn=10 ]'))
|
|
@@ -3571,3 +3585,395 @@ class AstTest(s_test.SynTest):
|
|
|
3571
3585
|
self.stormHasNoWarnErr(msgs)
|
|
3572
3586
|
|
|
3573
3587
|
self.len(1, await core.nodes('inet:ipv4=1.2.3.4 [ -:asn ]', opts={'user': visi}))
|
|
3588
|
+
|
|
3589
|
+
# When evaluating the property set permissions:
|
|
3590
|
+
#
|
|
3591
|
+
# node.prop.del.<form>.<prop>
|
|
3592
|
+
# node.prop.del.<fullprop>
|
|
3593
|
+
# node.prop.set.<form>.<prop>
|
|
3594
|
+
# node.prop.set.<fullprop>
|
|
3595
|
+
#
|
|
3596
|
+
# We have to consider cases of no-match ( None ) results when interpreting
|
|
3597
|
+
# the rules matches, in order to grant the permission. Since we decide
|
|
3598
|
+
# the precedence order is the newer-style, we do not allow a mixed match
|
|
3599
|
+
# where is an deny on the new style and an allow on the old style.
|
|
3600
|
+
#
|
|
3601
|
+
# Implementing this can be done by short-circuiting the a0 ( representing
|
|
3602
|
+
# the new style permission matching ) where possible, and allowing the
|
|
3603
|
+
# one undefined a0 + a1 case. All other results can then be left to raise
|
|
3604
|
+
# a s_exc.AuthDeny error.
|
|
3605
|
+
#
|
|
3606
|
+
# a0 a1 action
|
|
3607
|
+
# None None Deny
|
|
3608
|
+
# None True Allow
|
|
3609
|
+
# None False Deny
|
|
3610
|
+
# True None Allow
|
|
3611
|
+
# True True Allow
|
|
3612
|
+
# True False Allow with precedence
|
|
3613
|
+
# False None Deny
|
|
3614
|
+
# False True Deny with precedence
|
|
3615
|
+
# False False Deny
|
|
3616
|
+
|
|
3617
|
+
# These tests assume that only positive permissions are present to grant node.add / node.prop.set
|
|
3618
|
+
# and then denies on node.prop.set.
|
|
3619
|
+
|
|
3620
|
+
async with self.getTestCore() as core: # type: s_cortex.Cortex
|
|
3621
|
+
q = '[media:news=* :published=2020]'
|
|
3622
|
+
|
|
3623
|
+
# test 0
|
|
3624
|
+
# None None Deny
|
|
3625
|
+
name = s_common.guid()
|
|
3626
|
+
unfo = await core.addUser(name)
|
|
3627
|
+
opts = {'vars': {'name': name}}
|
|
3628
|
+
await core.callStorm('auth.user.addrule $name node.add', opts=opts)
|
|
3629
|
+
aslow = {'user': unfo.get('iden')}
|
|
3630
|
+
|
|
3631
|
+
msgs = await core.stormlist(q, opts=aslow)
|
|
3632
|
+
self.stormIsInErr('must have permission node.prop.set.media:news.published', msgs)
|
|
3633
|
+
|
|
3634
|
+
# test 1
|
|
3635
|
+
# None True Allow
|
|
3636
|
+
name = s_common.guid()
|
|
3637
|
+
unfo = await core.addUser(name)
|
|
3638
|
+
opts = {'vars': {'name': name}}
|
|
3639
|
+
await core.callStorm('auth.user.addrule $name node.prop.set.media:news:published', opts=opts)
|
|
3640
|
+
await core.callStorm('auth.user.addrule $name node.add', opts=opts)
|
|
3641
|
+
aslow = {'user': unfo.get('iden')}
|
|
3642
|
+
msgs = await core.stormlist(q, opts=aslow)
|
|
3643
|
+
self.stormHasNoErr(msgs)
|
|
3644
|
+
|
|
3645
|
+
# test 2
|
|
3646
|
+
# None False Deny
|
|
3647
|
+
name = s_common.guid()
|
|
3648
|
+
unfo = await core.addUser(name)
|
|
3649
|
+
opts = {'vars': {'name': name}}
|
|
3650
|
+
await core.callStorm('auth.user.addrule $name "!node.prop.set.media:news:published"', opts=opts)
|
|
3651
|
+
await core.callStorm('auth.user.addrule $name node.add', opts=opts)
|
|
3652
|
+
aslow = {'user': unfo.get('iden')}
|
|
3653
|
+
msgs = await core.stormlist(q, opts=aslow)
|
|
3654
|
+
self.stormIsInErr('must have permission node.prop.set.media:news.published', msgs)
|
|
3655
|
+
|
|
3656
|
+
# test 3
|
|
3657
|
+
# True None Allow
|
|
3658
|
+
name = s_common.guid()
|
|
3659
|
+
unfo = await core.addUser(name)
|
|
3660
|
+
opts = {'vars': {'name': name}}
|
|
3661
|
+
await core.callStorm('auth.user.addrule $name "node.prop.set.media:news.published"', opts=opts)
|
|
3662
|
+
await core.callStorm('auth.user.addrule $name node.add', opts=opts)
|
|
3663
|
+
aslow = {'user': unfo.get('iden')}
|
|
3664
|
+
msgs = await core.stormlist(q, opts=aslow)
|
|
3665
|
+
self.stormHasNoWarnErr(msgs)
|
|
3666
|
+
|
|
3667
|
+
# test 4
|
|
3668
|
+
# True True Allow
|
|
3669
|
+
name = s_common.guid()
|
|
3670
|
+
unfo = await core.addUser(name)
|
|
3671
|
+
opts = {'vars': {'name': name}}
|
|
3672
|
+
await core.callStorm('auth.user.addrule $name "node.prop.set.media:news.published"', opts=opts)
|
|
3673
|
+
await core.callStorm('auth.user.addrule $name "node.prop.set.media:news:published"', opts=opts)
|
|
3674
|
+
await core.callStorm('auth.user.addrule $name node.add', opts=opts)
|
|
3675
|
+
aslow = {'user': unfo.get('iden')}
|
|
3676
|
+
msgs = await core.stormlist(q, opts=aslow)
|
|
3677
|
+
self.stormHasNoWarnErr(msgs)
|
|
3678
|
+
|
|
3679
|
+
# test 5
|
|
3680
|
+
# True False Allow with precedence
|
|
3681
|
+
name = s_common.guid()
|
|
3682
|
+
unfo = await core.addUser(name)
|
|
3683
|
+
opts = {'vars': {'name': name}}
|
|
3684
|
+
await core.callStorm('auth.user.addrule $name "node.prop.set.media:news.published"', opts=opts)
|
|
3685
|
+
await core.callStorm('auth.user.addrule $name "!node.prop.set.media:news:published"', opts=opts)
|
|
3686
|
+
await core.callStorm('auth.user.addrule $name node.add', opts=opts)
|
|
3687
|
+
aslow = {'user': unfo.get('iden')}
|
|
3688
|
+
msgs = await core.stormlist(q, opts=aslow)
|
|
3689
|
+
self.stormHasNoWarnErr(msgs)
|
|
3690
|
+
|
|
3691
|
+
# test 6
|
|
3692
|
+
# False None Deny
|
|
3693
|
+
name = s_common.guid()
|
|
3694
|
+
unfo = await core.addUser(name)
|
|
3695
|
+
opts = {'vars': {'name': name}}
|
|
3696
|
+
await core.callStorm('auth.user.addrule $name "!node.prop.set.media:news.published"', opts=opts)
|
|
3697
|
+
await core.callStorm('auth.user.addrule $name node.add', opts=opts)
|
|
3698
|
+
aslow = {'user': unfo.get('iden')}
|
|
3699
|
+
msgs = await core.stormlist(q, opts=aslow)
|
|
3700
|
+
self.stormIsInErr('must have permission node.prop.set.media:news.published', msgs)
|
|
3701
|
+
|
|
3702
|
+
# test 7
|
|
3703
|
+
# False True Deny with precedence
|
|
3704
|
+
name = s_common.guid()
|
|
3705
|
+
unfo = await core.addUser(name)
|
|
3706
|
+
opts = {'vars': {'name': name}}
|
|
3707
|
+
await core.callStorm('auth.user.addrule $name "!node.prop.set.media:news.published"', opts=opts)
|
|
3708
|
+
await core.callStorm('auth.user.addrule $name "node.prop.set.media:news:published"', opts=opts)
|
|
3709
|
+
await core.callStorm('auth.user.addrule $name node.add', opts=opts)
|
|
3710
|
+
aslow = {'user': unfo.get('iden')}
|
|
3711
|
+
msgs = await core.stormlist(q, opts=aslow)
|
|
3712
|
+
self.stormIsInErr('must have permission node.prop.set.media:news.published', msgs)
|
|
3713
|
+
|
|
3714
|
+
# test 8
|
|
3715
|
+
# False False Deny
|
|
3716
|
+
name = s_common.guid()
|
|
3717
|
+
unfo = await core.addUser(name)
|
|
3718
|
+
opts = {'vars': {'name': name}}
|
|
3719
|
+
await core.callStorm('auth.user.addrule $name "!node.prop.set.media:news.published"', opts=opts)
|
|
3720
|
+
await core.callStorm('auth.user.addrule $name "!node.prop.set.media:news:published"', opts=opts)
|
|
3721
|
+
await core.callStorm('auth.user.addrule $name node.add', opts=opts)
|
|
3722
|
+
aslow = {'user': unfo.get('iden')}
|
|
3723
|
+
msgs = await core.stormlist(q, opts=aslow)
|
|
3724
|
+
self.stormIsInErr('must have permission node.prop.set.media:news.published', msgs)
|
|
3725
|
+
|
|
3726
|
+
# Exhaustive test for node.prop.del behaviors
|
|
3727
|
+
async with self.getTestCore() as core: # type: s_cortex.Cortex
|
|
3728
|
+
q = 'inet:asn=$valu [ -:name ]'
|
|
3729
|
+
|
|
3730
|
+
# test 0
|
|
3731
|
+
# None None Deny
|
|
3732
|
+
name = s_common.guid()
|
|
3733
|
+
unfo = await core.addUser(name)
|
|
3734
|
+
varz = {'valu': 0}
|
|
3735
|
+
aslow = {'user': unfo.get('iden'), 'vars': varz}
|
|
3736
|
+
self.len(1, await core.nodes('[inet:asn=$valu :name=name]', opts={'vars': varz}))
|
|
3737
|
+
msgs = await core.stormlist(q, opts=aslow)
|
|
3738
|
+
self.stormIsInErr('must have permission node.prop.del.inet:asn.name', msgs)
|
|
3739
|
+
|
|
3740
|
+
# test 1
|
|
3741
|
+
# None True Allow
|
|
3742
|
+
name = s_common.guid()
|
|
3743
|
+
unfo = await core.addUser(name)
|
|
3744
|
+
opts = {'vars': {'name': name}}
|
|
3745
|
+
await core.callStorm('auth.user.addrule $name node.prop.del.inet:asn:name', opts=opts)
|
|
3746
|
+
|
|
3747
|
+
varz = {'valu': 1}
|
|
3748
|
+
aslow = {'user': unfo.get('iden'), 'vars': varz}
|
|
3749
|
+
self.len(1, await core.nodes('[inet:asn=$valu :name=name]', opts={'vars': varz}))
|
|
3750
|
+
msgs = await core.stormlist(q, opts=aslow)
|
|
3751
|
+
self.stormHasNoErr(msgs)
|
|
3752
|
+
|
|
3753
|
+
# test 2
|
|
3754
|
+
# None False Deny
|
|
3755
|
+
name = s_common.guid()
|
|
3756
|
+
unfo = await core.addUser(name)
|
|
3757
|
+
opts = {'vars': {'name': name}}
|
|
3758
|
+
await core.callStorm('auth.user.addrule $name "!node.prop.del:inet:asn:name"', opts=opts)
|
|
3759
|
+
varz = {'valu': 2}
|
|
3760
|
+
aslow = {'user': unfo.get('iden'), 'vars': varz}
|
|
3761
|
+
self.len(1, await core.nodes('[inet:asn=$valu :name=name]', opts={'vars': varz}))
|
|
3762
|
+
msgs = await core.stormlist(q, opts=aslow)
|
|
3763
|
+
self.stormIsInErr('must have permission node.prop.del.inet:asn.name', msgs)
|
|
3764
|
+
|
|
3765
|
+
# test 3
|
|
3766
|
+
# True None Allow
|
|
3767
|
+
name = s_common.guid()
|
|
3768
|
+
unfo = await core.addUser(name)
|
|
3769
|
+
opts = {'vars': {'name': name}}
|
|
3770
|
+
await core.callStorm('auth.user.addrule $name "node.prop.del.inet:asn.name"', opts=opts)
|
|
3771
|
+
|
|
3772
|
+
varz = {'valu': 3}
|
|
3773
|
+
aslow = {'user': unfo.get('iden'), 'vars': varz}
|
|
3774
|
+
self.len(1, await core.nodes('[inet:asn=$valu :name=name]', opts={'vars': varz}))
|
|
3775
|
+
msgs = await core.stormlist(q, opts=aslow)
|
|
3776
|
+
self.stormHasNoWarnErr(msgs)
|
|
3777
|
+
|
|
3778
|
+
# test 4
|
|
3779
|
+
# True True Allow
|
|
3780
|
+
name = s_common.guid()
|
|
3781
|
+
unfo = await core.addUser(name)
|
|
3782
|
+
opts = {'vars': {'name': name}}
|
|
3783
|
+
await core.callStorm('auth.user.addrule $name "node.prop.del.inet:asn.name"', opts=opts)
|
|
3784
|
+
await core.callStorm('auth.user.addrule $name "node.prop.del.inet:asn:name"', opts=opts)
|
|
3785
|
+
varz = {'valu': 4}
|
|
3786
|
+
aslow = {'user': unfo.get('iden'), 'vars': varz}
|
|
3787
|
+
self.len(1, await core.nodes('[inet:asn=$valu :name=name]', opts={'vars': varz}))
|
|
3788
|
+
msgs = await core.stormlist(q, opts=aslow)
|
|
3789
|
+
self.stormHasNoWarnErr(msgs)
|
|
3790
|
+
|
|
3791
|
+
# test 5
|
|
3792
|
+
# True False Allow with precedence
|
|
3793
|
+
name = s_common.guid()
|
|
3794
|
+
unfo = await core.addUser(name)
|
|
3795
|
+
opts = {'vars': {'name': name}}
|
|
3796
|
+
await core.callStorm('auth.user.addrule $name "node.prop.del.inet:asn.name"', opts=opts)
|
|
3797
|
+
await core.callStorm('auth.user.addrule $name "!node.prop.del.inet:asn:name"', opts=opts)
|
|
3798
|
+
varz = {'valu': 5}
|
|
3799
|
+
aslow = {'user': unfo.get('iden'), 'vars': varz}
|
|
3800
|
+
self.len(1, await core.nodes('[inet:asn=$valu :name=name]', opts={'vars': varz}))
|
|
3801
|
+
msgs = await core.stormlist(q, opts=aslow)
|
|
3802
|
+
self.stormHasNoWarnErr(msgs)
|
|
3803
|
+
|
|
3804
|
+
# test 6
|
|
3805
|
+
# False None Deny
|
|
3806
|
+
name = s_common.guid()
|
|
3807
|
+
unfo = await core.addUser(name)
|
|
3808
|
+
opts = {'vars': {'name': name}}
|
|
3809
|
+
await core.callStorm('auth.user.addrule $name "!node.prop.del.inet:asn.name"', opts=opts)
|
|
3810
|
+
varz = {'valu': 6}
|
|
3811
|
+
aslow = {'user': unfo.get('iden'), 'vars': varz}
|
|
3812
|
+
self.len(1, await core.nodes('[inet:asn=$valu :name=name]', opts={'vars': varz}))
|
|
3813
|
+
msgs = await core.stormlist(q, opts=aslow)
|
|
3814
|
+
self.stormIsInErr('must have permission node.prop.del.inet:asn.name', msgs)
|
|
3815
|
+
|
|
3816
|
+
# test 7
|
|
3817
|
+
# False True Deny with precedence
|
|
3818
|
+
name = s_common.guid()
|
|
3819
|
+
unfo = await core.addUser(name)
|
|
3820
|
+
opts = {'vars': {'name': name}}
|
|
3821
|
+
await core.callStorm('auth.user.addrule $name "!node.prop.del.inet:asn.name"', opts=opts)
|
|
3822
|
+
await core.callStorm('auth.user.addrule $name "node.prop.del.inet:asn:name"', opts=opts)
|
|
3823
|
+
varz = {'valu': 7}
|
|
3824
|
+
aslow = {'user': unfo.get('iden'), 'vars': varz}
|
|
3825
|
+
self.len(1, await core.nodes('[inet:asn=$valu :name=name]', opts={'vars': varz}))
|
|
3826
|
+
msgs = await core.stormlist(q, opts=aslow)
|
|
3827
|
+
self.stormIsInErr('must have permission node.prop.del.inet:asn.name', msgs)
|
|
3828
|
+
|
|
3829
|
+
# test 8
|
|
3830
|
+
# False False Deny
|
|
3831
|
+
name = s_common.guid()
|
|
3832
|
+
unfo = await core.addUser(name)
|
|
3833
|
+
opts = {'vars': {'name': name}}
|
|
3834
|
+
await core.callStorm('auth.user.addrule $name "!node.prop.del.inet:asn.name"', opts=opts)
|
|
3835
|
+
await core.callStorm('auth.user.addrule $name "!node.prop.del.inet:asn:name"', opts=opts)
|
|
3836
|
+
varz = {'valu': 8}
|
|
3837
|
+
aslow = {'user': unfo.get('iden'), 'vars': varz}
|
|
3838
|
+
self.len(1, await core.nodes('[inet:asn=$valu :name=name]', opts={'vars': varz}))
|
|
3839
|
+
msgs = await core.stormlist(q, opts=aslow)
|
|
3840
|
+
self.stormIsInErr('must have permission node.prop.del.inet:asn.name', msgs)
|
|
3841
|
+
|
|
3842
|
+
# Negative permission tests
|
|
3843
|
+
# These tests confirm the behavior when a deny rule is used to deny the permission
|
|
3844
|
+
# but may still have an underlying allow rule present.
|
|
3845
|
+
|
|
3846
|
+
async with self.getTestCore() as core: # type: s_cortex.Cortex
|
|
3847
|
+
unfo = await core.addUser('lowuser')
|
|
3848
|
+
|
|
3849
|
+
await core.callStorm('auth.user.addrule lowuser "!node.prop.set.media:news.published"')
|
|
3850
|
+
await core.callStorm('auth.user.addrule lowuser "!node.prop.set.media:news:published"')
|
|
3851
|
+
await core.callStorm('auth.user.addrule lowuser node')
|
|
3852
|
+
aslow = {'user': unfo.get('iden')}
|
|
3853
|
+
q = '[media:news=(m0,) .seen=2020 :published=2020]'
|
|
3854
|
+
msgs = await core.stormlist(q, opts=aslow)
|
|
3855
|
+
self.stormIsInErr('must have permission node.prop.set.media:news.published', msgs)
|
|
3856
|
+
|
|
3857
|
+
# New style permission being deny, blanket node allowed
|
|
3858
|
+
async with self.getTestCore() as core: # type: s_cortex.Cortex
|
|
3859
|
+
unfo = await core.addUser('lowuser')
|
|
3860
|
+
|
|
3861
|
+
await core.callStorm('auth.user.addrule lowuser "!node.prop.set.media:news.published"')
|
|
3862
|
+
await core.callStorm('auth.user.addrule lowuser node')
|
|
3863
|
+
aslow = {'user': unfo.get('iden')}
|
|
3864
|
+
q = '[media:news=(m0,) .seen=2021 :published=2021]'
|
|
3865
|
+
msgs = await core.stormlist(q, opts=aslow)
|
|
3866
|
+
self.stormIsInErr('must have permission node.prop.set.media:news.published', msgs)
|
|
3867
|
+
|
|
3868
|
+
# Old style permission being deny, blanket node allowed
|
|
3869
|
+
async with self.getTestCore() as core: # type: s_cortex.Cortex
|
|
3870
|
+
unfo = await core.addUser('lowuser')
|
|
3871
|
+
|
|
3872
|
+
await core.callStorm('auth.user.addrule lowuser "!node.prop.set.media:news:published"')
|
|
3873
|
+
await core.callStorm('auth.user.addrule lowuser node')
|
|
3874
|
+
aslow = {'user': unfo.get('iden')}
|
|
3875
|
+
q = '[media:news=(m0,) .seen=2022 :published=2022]'
|
|
3876
|
+
msgs = await core.stormlist(q, opts=aslow)
|
|
3877
|
+
self.stormIsInErr('must have permission node.prop.set.media:news.published', msgs)
|
|
3878
|
+
|
|
3879
|
+
# Now with del - new style perm
|
|
3880
|
+
async with self.getTestCore() as core: # type: s_cortex.Cortex
|
|
3881
|
+
unfo = await core.addUser('lowuser')
|
|
3882
|
+
await core.callStorm('auth.user.addrule lowuser "!node.prop.del.media:news.published"')
|
|
3883
|
+
await core.callStorm('auth.user.addrule lowuser "node"')
|
|
3884
|
+
self.len(1, await core.nodes('[media:news=(m0,) :published=2022]'))
|
|
3885
|
+
aslow = {'user': unfo.get('iden')}
|
|
3886
|
+
q = 'media:news=(m0,) [-:published]'
|
|
3887
|
+
msgs = await core.stormlist(q, opts=aslow)
|
|
3888
|
+
self.stormIsInErr('must have permission node.prop.del.media:news.published', msgs)
|
|
3889
|
+
|
|
3890
|
+
# Now with del - old style perm
|
|
3891
|
+
async with self.getTestCore() as core: # type: s_cortex.Cortex
|
|
3892
|
+
unfo = await core.addUser('lowuser')
|
|
3893
|
+
await core.callStorm('auth.user.addrule lowuser "!node.prop.del.media:news:published"')
|
|
3894
|
+
await core.callStorm('auth.user.addrule lowuser "node"')
|
|
3895
|
+
self.len(1, await core.nodes('[media:news=(m0,) :published=2022]'))
|
|
3896
|
+
aslow = {'user': unfo.get('iden')}
|
|
3897
|
+
q = 'media:news=(m0,) [-:published]'
|
|
3898
|
+
msgs = await core.stormlist(q, opts=aslow)
|
|
3899
|
+
self.stormIsInErr('must have permission node.prop.del.media:news.published', msgs)
|
|
3900
|
+
|
|
3901
|
+
# This is a legal mix which has a logical equivalence to test case #7
|
|
3902
|
+
async with self.getTestCore() as core: # type: s_cortex.Cortex
|
|
3903
|
+
unfo = await core.addUser('lowuser')
|
|
3904
|
+
await core.callStorm('auth.user.addrule lowuser "!node.prop.set.media:news:published"')
|
|
3905
|
+
await core.callStorm('auth.user.addrule lowuser node.prop.set')
|
|
3906
|
+
await core.callStorm('auth.user.addrule lowuser node.add')
|
|
3907
|
+
aslow = {'user': unfo.get('iden')}
|
|
3908
|
+
q = '[media:news=(m0,) .seen=2022 :published=2022]'
|
|
3909
|
+
msgs = await core.stormlist(q, opts=aslow)
|
|
3910
|
+
self.stormIsInErr('must have permission node.prop.set.media:news.published', msgs)
|
|
3911
|
+
|
|
3912
|
+
# "Don't do this in production" example. Since the r1 DENY permission is not more precise
|
|
3913
|
+
# than the R0 allow permission, we allow the action.
|
|
3914
|
+
async with self.getTestCore() as core: # type: s_cortex.Cortex
|
|
3915
|
+
unfo = await core.addUser('lowuser')
|
|
3916
|
+
await core.callStorm('auth.user.addrule lowuser "node.prop.set.media:news"')
|
|
3917
|
+
await core.callStorm('auth.user.addrule lowuser "!node.prop.set.media:news:published"')
|
|
3918
|
+
await core.callStorm('auth.user.addrule lowuser node')
|
|
3919
|
+
aslow = {'user': unfo.get('iden')}
|
|
3920
|
+
q = '[media:news=(m0,) .seen=2022 :published=2022]'
|
|
3921
|
+
msgs = await core.stormlist(q, opts=aslow)
|
|
3922
|
+
self.stormHasNoWarnErr(msgs)
|
|
3923
|
+
|
|
3924
|
+
# A valid construction - the user is granted one a new style prop set perm but denied others.
|
|
3925
|
+
async with self.getTestCore() as core: # type: s_cortex.Cortex
|
|
3926
|
+
unfo = await core.addUser('lowuser')
|
|
3927
|
+
await core.callStorm('auth.user.addrule lowuser "node.prop.set.media:news.published"')
|
|
3928
|
+
await core.callStorm('auth.user.addrule lowuser "!node.prop.set"')
|
|
3929
|
+
await core.callStorm('auth.user.addrule lowuser node.add')
|
|
3930
|
+
aslow = {'user': unfo.get('iden')}
|
|
3931
|
+
q = '[media:news=(m0,) :published=2022]'
|
|
3932
|
+
msgs = await core.stormlist(q, opts=aslow)
|
|
3933
|
+
self.stormHasNoWarnErr(msgs)
|
|
3934
|
+
|
|
3935
|
+
# A valid construction - the user is granted one a old style prop set perm but denied others.
|
|
3936
|
+
# This is a deny with precedence.
|
|
3937
|
+
async with self.getTestCore() as core: # type: s_cortex.Cortex
|
|
3938
|
+
unfo = await core.addUser('lowuser')
|
|
3939
|
+
await core.callStorm('auth.user.addrule lowuser "node.prop.set.media:news:published"')
|
|
3940
|
+
await core.callStorm('auth.user.addrule lowuser "!node.prop.set"')
|
|
3941
|
+
await core.callStorm('auth.user.addrule lowuser node.add')
|
|
3942
|
+
aslow = {'user': unfo.get('iden')}
|
|
3943
|
+
q = '[media:news=(m0,) :published=2022]'
|
|
3944
|
+
msgs = await core.stormlist(q, opts=aslow)
|
|
3945
|
+
self.stormHasNoWarnErr(msgs)
|
|
3946
|
+
|
|
3947
|
+
# Same but with deletion
|
|
3948
|
+
async with self.getTestCore() as core: # type: s_cortex.Cortex
|
|
3949
|
+
unfo = await core.addUser('lowuser')
|
|
3950
|
+
await core.callStorm('auth.user.addrule lowuser "node.prop.del.media:news:published"')
|
|
3951
|
+
await core.callStorm('auth.user.addrule lowuser "!node.prop.del"')
|
|
3952
|
+
self.len(1, await core.nodes('[media:news=(m0,) :published=2022]'))
|
|
3953
|
+
aslow = {'user': unfo.get('iden')}
|
|
3954
|
+
q = 'media:news=(m0,) [-:published]'
|
|
3955
|
+
msgs = await core.stormlist(q, opts=aslow)
|
|
3956
|
+
self.stormHasNoWarnErr(msgs)
|
|
3957
|
+
|
|
3958
|
+
# "Don't do this in production" example. Since the r1 ALLOW permission is not more precise
|
|
3959
|
+
# than the R0 allow permission, we deny the action.
|
|
3960
|
+
async with self.getTestCore() as core: # type: s_cortex.Cortex
|
|
3961
|
+
unfo = await core.addUser('lowuser')
|
|
3962
|
+
await core.callStorm('auth.user.addrule lowuser "node.prop.set.media:news:published"')
|
|
3963
|
+
await core.callStorm('auth.user.addrule lowuser "!node.prop.set.media:news"')
|
|
3964
|
+
await core.callStorm('auth.user.addrule lowuser node.add')
|
|
3965
|
+
aslow = {'user': unfo.get('iden')}
|
|
3966
|
+
q = '[media:news=(m0,) :published=2022]'
|
|
3967
|
+
msgs = await core.stormlist(q, opts=aslow)
|
|
3968
|
+
self.stormIsInErr('must have permission node.prop.set.media:news.published', msgs)
|
|
3969
|
+
|
|
3970
|
+
# Same but with deletion
|
|
3971
|
+
async with self.getTestCore() as core: # type: s_cortex.Cortex
|
|
3972
|
+
unfo = await core.addUser('lowuser')
|
|
3973
|
+
await core.callStorm('auth.user.addrule lowuser "node.prop.del.media:news:published"')
|
|
3974
|
+
await core.callStorm('auth.user.addrule lowuser "!node.prop.del.media:news"')
|
|
3975
|
+
self.len(1, await core.nodes('[media:news=(m0,) :published=2022]'))
|
|
3976
|
+
aslow = {'user': unfo.get('iden')}
|
|
3977
|
+
q = 'media:news=(m0,) [-:published]'
|
|
3978
|
+
msgs = await core.stormlist(q, opts=aslow)
|
|
3979
|
+
self.stormIsInErr('must have permission node.prop.del.media:news.published', msgs)
|