synapse 2.176.0__py311-none-any.whl → 2.177.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.

Files changed (70) hide show
  1. synapse/axon.py +24 -9
  2. synapse/cortex.py +329 -168
  3. synapse/cryotank.py +46 -37
  4. synapse/datamodel.py +17 -4
  5. synapse/exc.py +19 -0
  6. synapse/lib/agenda.py +7 -13
  7. synapse/lib/auth.py +1520 -0
  8. synapse/lib/cell.py +255 -53
  9. synapse/lib/grammar.py +5 -0
  10. synapse/lib/hive.py +24 -3
  11. synapse/lib/hiveauth.py +6 -32
  12. synapse/lib/layer.py +7 -4
  13. synapse/lib/link.py +21 -17
  14. synapse/lib/lmdbslab.py +149 -0
  15. synapse/lib/modelrev.py +1 -1
  16. synapse/lib/schemas.py +136 -0
  17. synapse/lib/storm.py +61 -29
  18. synapse/lib/stormlib/aha.py +1 -1
  19. synapse/lib/stormlib/auth.py +185 -10
  20. synapse/lib/stormlib/cortex.py +16 -5
  21. synapse/lib/stormlib/gen.py +80 -0
  22. synapse/lib/stormlib/model.py +55 -0
  23. synapse/lib/stormlib/modelext.py +60 -0
  24. synapse/lib/stormlib/tabular.py +212 -0
  25. synapse/lib/stormtypes.py +14 -1
  26. synapse/lib/trigger.py +1 -1
  27. synapse/lib/version.py +2 -2
  28. synapse/lib/view.py +55 -28
  29. synapse/models/base.py +7 -0
  30. synapse/models/biz.py +4 -0
  31. synapse/models/files.py +8 -1
  32. synapse/models/inet.py +8 -0
  33. synapse/tests/files/changelog/model_2.176.0_16ee721a6b7221344eaf946c3ab4602dda546b1a.yaml.gz +0 -0
  34. synapse/tests/files/changelog/model_2.176.0_2a25c58bbd344716cd7cbc3f4304d8925b0f4ef2.yaml.gz +0 -0
  35. synapse/tests/test_axon.py +7 -4
  36. synapse/tests/test_cortex.py +127 -82
  37. synapse/tests/test_cryotank.py +4 -4
  38. synapse/tests/test_datamodel.py +7 -0
  39. synapse/tests/test_lib_agenda.py +7 -0
  40. synapse/tests/{test_lib_hiveauth.py → test_lib_auth.py} +314 -11
  41. synapse/tests/test_lib_cell.py +161 -8
  42. synapse/tests/test_lib_httpapi.py +18 -14
  43. synapse/tests/test_lib_layer.py +33 -33
  44. synapse/tests/test_lib_link.py +42 -1
  45. synapse/tests/test_lib_lmdbslab.py +68 -0
  46. synapse/tests/test_lib_nexus.py +4 -4
  47. synapse/tests/test_lib_node.py +0 -7
  48. synapse/tests/test_lib_storm.py +45 -0
  49. synapse/tests/test_lib_stormlib_aha.py +1 -2
  50. synapse/tests/test_lib_stormlib_auth.py +21 -0
  51. synapse/tests/test_lib_stormlib_cortex.py +12 -12
  52. synapse/tests/test_lib_stormlib_gen.py +99 -0
  53. synapse/tests/test_lib_stormlib_model.py +108 -0
  54. synapse/tests/test_lib_stormlib_modelext.py +64 -0
  55. synapse/tests/test_lib_stormlib_tabular.py +226 -0
  56. synapse/tests/test_lib_stormsvc.py +4 -1
  57. synapse/tests/test_lib_stormtypes.py +10 -0
  58. synapse/tests/test_model_base.py +3 -0
  59. synapse/tests/test_model_biz.py +3 -0
  60. synapse/tests/test_model_files.py +12 -2
  61. synapse/tests/test_model_inet.py +24 -0
  62. synapse/tests/test_tools_changelog.py +196 -0
  63. synapse/tests/test_tools_healthcheck.py +4 -3
  64. synapse/tests/utils.py +1 -1
  65. synapse/tools/changelog.py +774 -15
  66. {synapse-2.176.0.dist-info → synapse-2.177.0.dist-info}/METADATA +3 -3
  67. {synapse-2.176.0.dist-info → synapse-2.177.0.dist-info}/RECORD +70 -64
  68. {synapse-2.176.0.dist-info → synapse-2.177.0.dist-info}/WHEEL +1 -1
  69. {synapse-2.176.0.dist-info → synapse-2.177.0.dist-info}/LICENSE +0 -0
  70. {synapse-2.176.0.dist-info → synapse-2.177.0.dist-info}/top_level.txt +0 -0
synapse/lib/cell.py CHANGED
@@ -29,6 +29,7 @@ import synapse.common as s_common
29
29
  import synapse.daemon as s_daemon
30
30
  import synapse.telepath as s_telepath
31
31
 
32
+ import synapse.lib.auth as s_auth
32
33
  import synapse.lib.base as s_base
33
34
  import synapse.lib.boss as s_boss
34
35
  import synapse.lib.coro as s_coro
@@ -50,7 +51,6 @@ import synapse.lib.schemas as s_schemas
50
51
  import synapse.lib.spooled as s_spooled
51
52
  import synapse.lib.urlhelp as s_urlhelp
52
53
  import synapse.lib.version as s_version
53
- import synapse.lib.hiveauth as s_hiveauth
54
54
  import synapse.lib.lmdbslab as s_lmdbslab
55
55
  import synapse.lib.thisplat as s_thisplat
56
56
 
@@ -60,6 +60,8 @@ import synapse.tools.backup as s_t_backup
60
60
 
61
61
  logger = logging.getLogger(__name__)
62
62
 
63
+ NEXUS_VERSION = (2, 177)
64
+
63
65
  SLAB_MAP_SIZE = 128 * s_const.mebibyte
64
66
  SSLCTX_CACHE_SIZE = 64
65
67
 
@@ -891,6 +893,10 @@ class Cell(s_nexus.Pusher, s_telepath.Aware):
891
893
  'type': 'object',
892
894
  'hideconf': True,
893
895
  },
896
+ 'auth:passwd:policy': {
897
+ 'description': 'Specify password policy/complexity requirements.',
898
+ 'type': 'object',
899
+ },
894
900
  'max:users': {
895
901
  'default': 0,
896
902
  'description': 'Maximum number of users allowed on system, not including root or locked/archived users (0 is no limit).',
@@ -1203,10 +1209,15 @@ class Cell(s_nexus.Pusher, s_telepath.Aware):
1203
1209
 
1204
1210
  self.hive = await self._initCellHive()
1205
1211
 
1206
- # self.cellinfo, a HiveDict for general purpose persistent storage
1207
- node = await self.hive.open(('cellinfo',))
1208
- self.cellinfo = await node.dict()
1209
- self.onfini(node)
1212
+ self.cellinfo = self.slab.getSafeKeyVal('cell:info')
1213
+ self.cellvers = self.slab.getSafeKeyVal('cell:vers')
1214
+
1215
+ await self._bumpCellVers('cell:storage', (
1216
+ (1, self._storCellHiveMigration),
1217
+ ), nexs=False)
1218
+
1219
+ if self.inaugural:
1220
+ self.cellinfo.set('nexus:version', NEXUS_VERSION)
1210
1221
 
1211
1222
  # Check the cell version didn't regress
1212
1223
  if (lastver := self.cellinfo.get('cell:version')) is not None and self.VERSION < lastver:
@@ -1214,7 +1225,7 @@ class Cell(s_nexus.Pusher, s_telepath.Aware):
1214
1225
  logger.error(mesg)
1215
1226
  raise s_exc.BadVersion(mesg=mesg, currver=self.VERSION, lastver=lastver)
1216
1227
 
1217
- await self.cellinfo.set('cell:version', self.VERSION)
1228
+ self.cellinfo.set('cell:version', self.VERSION)
1218
1229
 
1219
1230
  # Check the synapse version didn't regress
1220
1231
  if (lastver := self.cellinfo.get('synapse:version')) is not None and s_version.version < lastver:
@@ -1222,10 +1233,14 @@ class Cell(s_nexus.Pusher, s_telepath.Aware):
1222
1233
  logger.error(mesg)
1223
1234
  raise s_exc.BadVersion(mesg=mesg, currver=s_version.version, lastver=lastver)
1224
1235
 
1225
- await self.cellinfo.set('synapse:version', s_version.version)
1236
+ self.cellinfo.set('synapse:version', s_version.version)
1226
1237
 
1227
- node = await self.hive.open(('cellvers',))
1228
- self.cellvers = await node.dict(nexs=True)
1238
+ self.nexsvers = self.cellinfo.get('nexus:version', (0, 0))
1239
+ self.nexspatches = ()
1240
+
1241
+ await self._bumpCellVers('cell:storage', (
1242
+ (2, self._storCellAuthMigration),
1243
+ ), nexs=False)
1229
1244
 
1230
1245
  self.auth = await self._initCellAuth()
1231
1246
 
@@ -1233,8 +1248,8 @@ class Cell(s_nexus.Pusher, s_telepath.Aware):
1233
1248
  if auth_passwd is not None:
1234
1249
  user = await self.auth.getUserByName('root')
1235
1250
 
1236
- if not await user.tryPasswd(auth_passwd, nexs=False):
1237
- await user.setPasswd(auth_passwd, nexs=False)
1251
+ if not await user.tryPasswd(auth_passwd, nexs=False, enforce_policy=False):
1252
+ await user.setPasswd(auth_passwd, nexs=False, enforce_policy=False)
1238
1253
 
1239
1254
  self.boss = await s_boss.Boss.anit()
1240
1255
  self.onfini(self.boss)
@@ -1244,11 +1259,6 @@ class Cell(s_nexus.Pusher, s_telepath.Aware):
1244
1259
  'cell': self
1245
1260
  }
1246
1261
 
1247
- # a tuple of (vers, func) tuples
1248
- # it is expected that this is set by
1249
- # initServiceStorage
1250
- self.cellupdaters = ()
1251
-
1252
1262
  self.permdefs = None
1253
1263
  self.permlook = None
1254
1264
 
@@ -1273,6 +1283,8 @@ class Cell(s_nexus.Pusher, s_telepath.Aware):
1273
1283
  # phase 3 - nexus subsystem
1274
1284
  await self.initNexusSubsystem()
1275
1285
 
1286
+ await self.configNexsVers()
1287
+
1276
1288
  # We can now do nexus-safe operations
1277
1289
  await self._initInauguralConfig()
1278
1290
 
@@ -1281,6 +1293,128 @@ class Cell(s_nexus.Pusher, s_telepath.Aware):
1281
1293
  # phase 5 - service networking
1282
1294
  await self.initServiceNetwork()
1283
1295
 
1296
+ async def _storCellHiveMigration(self):
1297
+ logger.warning(f'migrating Cell ({self.getCellType()}) info out of hive')
1298
+
1299
+ async with await self.hive.open(('cellvers',)) as versnode:
1300
+ versdict = await versnode.dict()
1301
+ for key, valu in versdict.items():
1302
+ self.cellvers.set(key, valu)
1303
+
1304
+ async with await self.hive.open(('cellinfo',)) as infonode:
1305
+ infodict = await infonode.dict()
1306
+ for key, valu in infodict.items():
1307
+ self.cellinfo.set(key, valu)
1308
+
1309
+ logger.warning(f'...Cell ({self.getCellType()}) info migration complete!')
1310
+
1311
+ async def _storCellAuthMigration(self):
1312
+ if self.conf.get('auth:ctor') is not None:
1313
+ return
1314
+
1315
+ logger.warning(f'migrating Cell ({self.getCellType()}) auth out of hive')
1316
+
1317
+ authkv = self.slab.getSafeKeyVal('auth')
1318
+
1319
+ async with await self.hive.open(('auth',)) as rootnode:
1320
+
1321
+ rolekv = authkv.getSubKeyVal('role:info:')
1322
+ rolenamekv = authkv.getSubKeyVal('role:name:')
1323
+
1324
+ async with await rootnode.open(('roles',)) as roles:
1325
+ for iden, node in roles:
1326
+ roledict = await node.dict()
1327
+ roleinfo = roledict.pack()
1328
+
1329
+ roleinfo['iden'] = iden
1330
+ roleinfo['name'] = node.valu
1331
+ roleinfo['authgates'] = {}
1332
+ roleinfo.setdefault('admin', False)
1333
+ roleinfo.setdefault('rules', ())
1334
+
1335
+ rolekv.set(iden, roleinfo)
1336
+ rolenamekv.set(node.valu, iden)
1337
+
1338
+ userkv = authkv.getSubKeyVal('user:info:')
1339
+ usernamekv = authkv.getSubKeyVal('user:name:')
1340
+
1341
+ async with await rootnode.open(('users',)) as users:
1342
+ for iden, node in users:
1343
+ userdict = await node.dict()
1344
+ userinfo = userdict.pack()
1345
+
1346
+ userinfo['iden'] = iden
1347
+ userinfo['name'] = node.valu
1348
+ userinfo['authgates'] = {}
1349
+ userinfo.setdefault('admin', False)
1350
+ userinfo.setdefault('rules', ())
1351
+ userinfo.setdefault('locked', False)
1352
+ userinfo.setdefault('passwd', None)
1353
+ userinfo.setdefault('archived', False)
1354
+
1355
+ realroles = []
1356
+ for userrole in userinfo.get('roles', ()):
1357
+ if rolekv.get(userrole) is None:
1358
+ mesg = f'Unknown role {userrole} on user {iden} during migration, ignoring.'
1359
+ logger.warning(mesg)
1360
+ continue
1361
+
1362
+ realroles.append(userrole)
1363
+
1364
+ userinfo['roles'] = tuple(realroles)
1365
+
1366
+ userkv.set(iden, userinfo)
1367
+ usernamekv.set(node.valu, iden)
1368
+
1369
+ varskv = authkv.getSubKeyVal(f'user:{iden}:vars:')
1370
+ async with await node.open(('vars',)) as varnodes:
1371
+ for name, varnode in varnodes:
1372
+ varskv.set(name, varnode.valu)
1373
+
1374
+ profkv = authkv.getSubKeyVal(f'user:{iden}:profile:')
1375
+ async with await node.open(('profile',)) as profnodes:
1376
+ for name, profnode in profnodes:
1377
+ profkv.set(name, profnode.valu)
1378
+
1379
+ gatekv = authkv.getSubKeyVal('gate:info:')
1380
+ async with await rootnode.open(('authgates',)) as authgates:
1381
+ for gateiden, node in authgates:
1382
+ gateinfo = {
1383
+ 'iden': gateiden,
1384
+ 'type': node.valu
1385
+ }
1386
+ gatekv.set(gateiden, gateinfo)
1387
+
1388
+ async with await node.open(('users',)) as usernodes:
1389
+ for useriden, usernode in usernodes:
1390
+ if (user := userkv.get(useriden)) is None:
1391
+ mesg = f'Unknown user {useriden} on gate {gateiden} during migration, ignoring.'
1392
+ logger.warning(mesg)
1393
+ continue
1394
+
1395
+ userinfo = await usernode.dict()
1396
+ userdict = userinfo.pack()
1397
+ authkv.set(f'gate:{gateiden}:user:{useriden}', userdict)
1398
+
1399
+ user['authgates'][gateiden] = userdict
1400
+ userkv.set(useriden, user)
1401
+
1402
+ async with await node.open(('roles',)) as rolenodes:
1403
+ for roleiden, rolenode in rolenodes:
1404
+ if (role := rolekv.get(roleiden)) is None:
1405
+ mesg = f'Unknown role {roleiden} on gate {gateiden} during migration, ignoring.'
1406
+ logger.warning(mesg)
1407
+ continue
1408
+
1409
+ roleinfo = await rolenode.dict()
1410
+ roledict = roleinfo.pack()
1411
+ authkv.set(f'gate:{gateiden}:role:{roleiden}', roledict)
1412
+
1413
+ role['authgates'][gateiden] = roledict
1414
+ rolekv.set(roleiden, role)
1415
+
1416
+ logger.warning(f'...Cell ({self.getCellType()}) auth migration complete!')
1417
+
1284
1418
  def getPermDef(self, perm):
1285
1419
  perm = tuple(perm)
1286
1420
  if self.permlook is None:
@@ -1412,10 +1546,52 @@ class Cell(s_nexus.Pusher, s_telepath.Aware):
1412
1546
  # ( and do so using _bumpCellVers )
1413
1547
  pass
1414
1548
 
1549
+ async def setNexsVers(self, vers):
1550
+ if self.nexsvers < NEXUS_VERSION:
1551
+ await self._push('nexs:vers:set', NEXUS_VERSION)
1552
+
1553
+ @s_nexus.Pusher.onPush('nexs:vers:set')
1554
+ async def _setNexsVers(self, vers):
1555
+ if vers > self.nexsvers:
1556
+ self.cellvers.set('nexus:version', vers)
1557
+ self.nexsvers = vers
1558
+ await self.configNexsVers()
1559
+
1560
+ async def configNexsVers(self):
1561
+ for meth, orig in self.nexspatches:
1562
+ setattr(self, meth, orig)
1563
+
1564
+ if self.nexsvers == NEXUS_VERSION:
1565
+ return
1566
+
1567
+ patches = []
1568
+ if self.nexsvers < (2, 177):
1569
+ patches.extend([
1570
+ ('popUserVarValu', self._popUserVarValuV0),
1571
+ ('setUserVarValu', self._setUserVarValuV0),
1572
+ ('popUserProfInfo', self._popUserProfInfoV0),
1573
+ ('setUserProfInfo', self._setUserProfInfoV0),
1574
+ ])
1575
+
1576
+ self.nexspatches = []
1577
+ for meth, repl in patches:
1578
+ self.nexspatches.append((meth, getattr(self, meth)))
1579
+ setattr(self, meth, repl)
1580
+
1581
+ async def setCellVers(self, name, vers, nexs=True):
1582
+ if nexs:
1583
+ await self._push('cell:vers:set', name, vers)
1584
+ else:
1585
+ await self._setCellVers(name, vers)
1586
+
1587
+ @s_nexus.Pusher.onPush('cell:vers:set')
1588
+ async def _setCellVers(self, name, vers):
1589
+ self.cellvers.set(name, vers)
1590
+
1415
1591
  async def _bumpCellVers(self, name, updates, nexs=True):
1416
1592
 
1417
1593
  if self.inaugural:
1418
- await self.cellvers.set(name, updates[-1][0], nexs=nexs)
1594
+ await self.setCellVers(name, updates[-1][0], nexs=nexs)
1419
1595
  return
1420
1596
 
1421
1597
  curv = self.cellvers.get(name, 0)
@@ -1427,7 +1603,7 @@ class Cell(s_nexus.Pusher, s_telepath.Aware):
1427
1603
 
1428
1604
  await callback()
1429
1605
 
1430
- await self.cellvers.set(name, vers, nexs=nexs)
1606
+ await self.setCellVers(name, vers, nexs=nexs)
1431
1607
 
1432
1608
  curv = vers
1433
1609
 
@@ -1959,6 +2135,7 @@ class Cell(s_nexus.Pusher, s_telepath.Aware):
1959
2135
  self.onfini(self.activebase)
1960
2136
  self._fireActiveCoros()
1961
2137
  await self._execCellUpdates()
2138
+ await self.setNexsVers(NEXUS_VERSION)
1962
2139
  await self.initServiceActive()
1963
2140
  else:
1964
2141
  await self._killActiveCoros()
@@ -2361,7 +2538,7 @@ class Cell(s_nexus.Pusher, s_telepath.Aware):
2361
2538
  self.backupstreaming = False
2362
2539
 
2363
2540
  async def isUserAllowed(self, iden, perm, gateiden=None, default=False):
2364
- user = self.auth.user(iden) # type: s_hiveauth.HiveUser
2541
+ user = self.auth.user(iden) # type: s_auth.User
2365
2542
  if user is None:
2366
2543
  return False
2367
2544
 
@@ -2386,36 +2563,59 @@ class Cell(s_nexus.Pusher, s_telepath.Aware):
2386
2563
 
2387
2564
  async def getUserProfile(self, iden):
2388
2565
  user = await self.auth.reqUser(iden)
2389
- return user.profile.pack()
2566
+ return dict(user.profile.items())
2390
2567
 
2391
- async def getUserProfInfo(self, iden, name):
2568
+ async def getUserProfInfo(self, iden, name, default=None):
2392
2569
  user = await self.auth.reqUser(iden)
2393
- return user.profile.get(name)
2570
+ return user.profile.get(name, defv=default)
2571
+
2572
+ async def _setUserProfInfoV0(self, iden, name, valu):
2573
+ path = ('auth', 'users', iden, 'profile', name)
2574
+ return await self.hive._push('hive:set', path, valu)
2394
2575
 
2395
2576
  async def setUserProfInfo(self, iden, name, valu):
2396
2577
  user = await self.auth.reqUser(iden)
2397
- return await user.profile.set(name, valu)
2578
+ return await user.setProfileValu(name, valu)
2579
+
2580
+ async def _popUserProfInfoV0(self, iden, name, default=None):
2581
+ path = ('auth', 'users', iden, 'profile', name)
2582
+ return await self.hive._push('hive:pop', path)
2398
2583
 
2399
2584
  async def popUserProfInfo(self, iden, name, default=None):
2400
2585
  user = await self.auth.reqUser(iden)
2401
- return await user.profile.pop(name, default=default)
2586
+ return await user.popProfileValu(name, default=default)
2402
2587
 
2403
2588
  async def iterUserVars(self, iden):
2404
2589
  user = await self.auth.reqUser(iden)
2405
2590
  for item in user.vars.items():
2406
2591
  yield item
2592
+ await asyncio.sleep(0)
2407
2593
 
2408
- async def getUserVarValu(self, iden, name):
2594
+ async def iterUserProfInfo(self, iden):
2409
2595
  user = await self.auth.reqUser(iden)
2410
- return user.vars.get(name)
2596
+ for item in user.profile.items():
2597
+ yield item
2598
+ await asyncio.sleep(0)
2599
+
2600
+ async def getUserVarValu(self, iden, name, default=None):
2601
+ user = await self.auth.reqUser(iden)
2602
+ return user.vars.get(name, defv=default)
2603
+
2604
+ async def _setUserVarValuV0(self, iden, name, valu):
2605
+ path = ('auth', 'users', iden, 'vars', name)
2606
+ return await self.hive._push('hive:set', path, valu)
2411
2607
 
2412
2608
  async def setUserVarValu(self, iden, name, valu):
2413
2609
  user = await self.auth.reqUser(iden)
2414
- return await user.vars.set(name, valu)
2610
+ return await user.setVarValu(name, valu)
2611
+
2612
+ async def _popUserVarValuV0(self, iden, name, default=None):
2613
+ path = ('auth', 'users', iden, 'vars', name)
2614
+ return await self.hive._push('hive:pop', path)
2415
2615
 
2416
2616
  async def popUserVarValu(self, iden, name, default=None):
2417
2617
  user = await self.auth.reqUser(iden)
2418
- return await user.vars.pop(name, default=default)
2618
+ return await user.popVarValu(name, default=default)
2419
2619
 
2420
2620
  async def addUserRule(self, iden, rule, indx=None, gateiden=None):
2421
2621
  user = await self.auth.reqUser(iden)
@@ -2969,7 +3169,7 @@ class Cell(s_nexus.Pusher, s_telepath.Aware):
2969
3169
 
2970
3170
  async def _initCellHive(self):
2971
3171
  db = self.slab.initdb('hive')
2972
- hive = await s_hive.SlabHive.anit(self.slab, db=db, nexsroot=self.getCellNexsRoot())
3172
+ hive = await s_hive.SlabHive.anit(self.slab, db=db, nexsroot=self.getCellNexsRoot(), cell=self)
2973
3173
  self.onfini(hive)
2974
3174
 
2975
3175
  return hive
@@ -2992,37 +3192,27 @@ class Cell(s_nexus.Pusher, s_telepath.Aware):
2992
3192
 
2993
3193
  async def _initCellAuth(self):
2994
3194
 
3195
+ # Add callbacks
3196
+ self.on('user:del', self._onUserDelEvnt)
3197
+
2995
3198
  authctor = self.conf.get('auth:ctor')
2996
3199
  if authctor is not None:
2997
3200
  s_common.deprecated('auth:ctor cell config option', curv='2.157.0')
2998
3201
  ctor = s_dyndeps.getDynLocal(authctor)
2999
- auth = await ctor(self)
3000
- else:
3001
- auth = await self._initCellHiveAuth()
3002
-
3003
- # Add callbacks
3004
- self.on('user:del', self._onUserDelEvnt)
3005
-
3006
- return auth
3007
-
3008
- def getCellNexsRoot(self):
3009
- # the "cell scope" nexusroot only exists if we are *not* embedded
3010
- # (aka we dont have a self.cellparent)
3011
- if self.cellparent is None:
3012
- return self.nexsroot
3013
-
3014
- async def _initCellHiveAuth(self):
3202
+ return await ctor(self)
3015
3203
 
3016
3204
  maxusers = self.conf.get('max:users')
3205
+ policy = self.conf.get('auth:passwd:policy')
3017
3206
 
3018
3207
  seed = s_common.guid((self.iden, 'hive', 'auth'))
3019
3208
 
3020
- node = await self.hive.open(('auth',))
3021
- auth = await s_hiveauth.Auth.anit(
3022
- node,
3209
+ auth = await s_auth.Auth.anit(
3210
+ self.slab,
3211
+ 'auth',
3023
3212
  seed=seed,
3024
3213
  nexsroot=self.getCellNexsRoot(),
3025
- maxusers=maxusers
3214
+ maxusers=maxusers,
3215
+ policy=policy
3026
3216
  )
3027
3217
 
3028
3218
  auth.link(self.dist)
@@ -3035,6 +3225,12 @@ class Cell(s_nexus.Pusher, s_telepath.Aware):
3035
3225
  self.onfini(auth.fini)
3036
3226
  return auth
3037
3227
 
3228
+ def getCellNexsRoot(self):
3229
+ # the "cell scope" nexusroot only exists if we are *not* embedded
3230
+ # (aka we dont have a self.cellparent)
3231
+ if self.cellparent is None:
3232
+ return self.nexsroot
3233
+
3038
3234
  async def _initInauguralConfig(self):
3039
3235
  if self.inaugural:
3040
3236
  icfg = self.conf.get('inaugural')
@@ -3044,7 +3240,7 @@ class Cell(s_nexus.Pusher, s_telepath.Aware):
3044
3240
  name = rnfo.get('name')
3045
3241
  logger.debug(f'Adding inaugural role {name}')
3046
3242
  iden = s_common.guid((self.iden, 'auth', 'role', name))
3047
- role = await self.auth.addRole(name, iden) # type: s_hiveauth.HiveRole
3243
+ role = await self.auth.addRole(name, iden) # type: s_auth.Role
3048
3244
 
3049
3245
  for rule in rnfo.get('rules', ()):
3050
3246
  await role.addRule(rule)
@@ -3054,7 +3250,7 @@ class Cell(s_nexus.Pusher, s_telepath.Aware):
3054
3250
  email = unfo.get('email')
3055
3251
  iden = s_common.guid((self.iden, 'auth', 'user', name))
3056
3252
  logger.debug(f'Adding inaugural user {name}')
3057
- user = await self.auth.addUser(name, email=email, iden=iden) # type: s_hiveauth.HiveUser
3253
+ user = await self.auth.addUser(name, email=email, iden=iden) # type: s_auth.User
3058
3254
 
3059
3255
  if unfo.get('admin'):
3060
3256
  await user.setAdmin(True)
@@ -3221,7 +3417,7 @@ class Cell(s_nexus.Pusher, s_telepath.Aware):
3221
3417
 
3222
3418
  Args:
3223
3419
  link (s_link.Link): The link object.
3224
- user (s_hive.HiveUser): The heavy user object.
3420
+ user (s_auth.User): The heavy user object.
3225
3421
  path (str): The path requested.
3226
3422
 
3227
3423
  Notes:
@@ -3245,7 +3441,7 @@ class Cell(s_nexus.Pusher, s_telepath.Aware):
3245
3441
  '''
3246
3442
  extra = {**kwargs}
3247
3443
  sess = s_scope.get('sess') # type: s_daemon.Sess
3248
- user = s_scope.get('user') # type: s_hiveauth.HiveUser
3444
+ user = s_scope.get('user') # type: s_auth.User
3249
3445
  if user:
3250
3446
  extra['user'] = user.iden
3251
3447
  extra['username'] = user.name
@@ -3997,6 +4193,12 @@ class Cell(s_nexus.Pusher, s_telepath.Aware):
3997
4193
  async def _onLoadHiveTree(self, tree, path, trim):
3998
4194
  return await self.hive.loadHiveTree(tree, path=path, trim=trim)
3999
4195
 
4196
+ async def iterSlabData(self, name, prefix=''):
4197
+ slabkv = self.slab.getSafeKeyVal(name, prefix=prefix, create=False)
4198
+ for key, valu in slabkv.items():
4199
+ yield key, valu
4200
+ await asyncio.sleep(0)
4201
+
4000
4202
  @s_nexus.Pusher.onPushAuto('sync')
4001
4203
  async def sync(self):
4002
4204
  '''
synapse/lib/grammar.py CHANGED
@@ -15,6 +15,8 @@ formrestr = r'[a-z_][a-z0-9_]*(:[a-z0-9_]+)+'
15
15
  formre = regex.compile(formrestr)
16
16
  tagrestr = r'(\w+\.)*\w+'
17
17
  tagre = regex.compile(tagrestr)
18
+ edgerestr = r'[\w\.:]{1,200}'
19
+ edgere = regex.compile(edgerestr)
18
20
  basepropnopivpropstr = r'[a-z_][a-z0-9_]*(?:(\:|\.)[a-z_][a-z0-9_]*)*'
19
21
  basepropnopivpropre = regex.compile(basepropnopivpropstr)
20
22
 
@@ -38,6 +40,9 @@ def isFormName(name):
38
40
  def isBasePropNoPivprop(name):
39
41
  return basepropnopivpropre.fullmatch(name) is not None
40
42
 
43
+ def isEdgeVerb(verb):
44
+ return edgere.fullmatch(verb) is not None
45
+
41
46
  floatre = regex.compile(r'\s*-?\d+(\.\d+)?([eE][-+]\d+)?')
42
47
 
43
48
  def parse_float(text, off):
synapse/lib/hive.py CHANGED
@@ -91,7 +91,7 @@ class Hive(s_nexus.Pusher, s_telepath.Aware):
91
91
  An optionally persistent atomically accessed tree which implements
92
92
  primitives for use in making distributed/clustered services.
93
93
  '''
94
- async def __anit__(self, conf=None, nexsroot=None):
94
+ async def __anit__(self, conf=None, nexsroot=None, cell=None):
95
95
 
96
96
  await s_nexus.Pusher.__anit__(self, 'hive', nexsroot=nexsroot)
97
97
 
@@ -100,6 +100,7 @@ class Hive(s_nexus.Pusher, s_telepath.Aware):
100
100
  if conf is None:
101
101
  conf = {}
102
102
 
103
+ self.cell = cell
103
104
  self.conf = conf
104
105
  self.nodes = {} # full=Node()
105
106
 
@@ -340,6 +341,18 @@ class Hive(s_nexus.Pusher, s_telepath.Aware):
340
341
 
341
342
  @s_nexus.Pusher.onPush('hive:set')
342
343
  async def _set(self, full, valu):
344
+ if self.cell is not None:
345
+ if full[0] == 'auth':
346
+ if len(full) == 5:
347
+ _, _, iden, dtyp, name = full
348
+ if dtyp == 'vars':
349
+ await self.cell.auth._hndlsetUserVarValu(iden, name, valu)
350
+ elif dtyp == 'profile':
351
+ await self.cell.auth._hndlsetUserProfileValu(iden, name, valu)
352
+
353
+ elif full[0] == 'cellvers':
354
+ self.cell.setCellVers(full[-1], valu, nexs=False)
355
+
343
356
  node = await self._getHiveNode(full)
344
357
 
345
358
  oldv = node.valu
@@ -377,6 +390,14 @@ class Hive(s_nexus.Pusher, s_telepath.Aware):
377
390
  @s_nexus.Pusher.onPush('hive:pop')
378
391
  async def _pop(self, full):
379
392
 
393
+ if self.cell is not None and full[0] == 'auth':
394
+ if len(full) == 5:
395
+ _, _, iden, dtyp, name = full
396
+ if dtyp == 'vars':
397
+ await self.cell.auth._hndlpopUserVarValu(iden, name)
398
+ elif dtyp == 'profile':
399
+ await self.cell.auth._hndlpopUserProfileValu(iden, name)
400
+
380
401
  node = self.nodes.get(full)
381
402
  if node is None:
382
403
  return
@@ -434,10 +455,10 @@ class Hive(s_nexus.Pusher, s_telepath.Aware):
434
455
 
435
456
  class SlabHive(Hive):
436
457
 
437
- async def __anit__(self, slab, db=None, conf=None, nexsroot=None):
458
+ async def __anit__(self, slab, db=None, conf=None, nexsroot=None, cell=None):
438
459
  self.db = db
439
460
  self.slab = slab
440
- await Hive.__anit__(self, conf=conf, nexsroot=nexsroot)
461
+ await Hive.__anit__(self, conf=conf, nexsroot=nexsroot, cell=cell)
441
462
  self.slab.onfini(self.fini)
442
463
 
443
464
  async def _storLoadHive(self):