feat: hierarchical group & permission model (v1.25.0)
- Add utils/groups.js: the group schema + inheritance resolver (god_admin,
{site}_super_admin, {site}_hosts_*/{site}_apps_* aggregates, per-resource
admin/access/<capability>, meta everyone/{site}_everyone). admin implies
access; capabilities explicit; hosts/apps orthogonal; cross-site isolated.
- permission.js: recognize god_admin (legacy app_super_admin aliased) and add
onResource/requireResource for resource-level checks + everyone meta grants.
- user.js isAdmin: recognize god_admin + site-scoped super/app-admin groups.
- Remove the standalone Groups page (nav + route + view); groups are managed on
adopted Directory resources. Add a /docs/groups help link in the Directory
toolbar (GROUPS.md copied into the SSO docs).
- tests/groups.test.js: full resolver coverage (15 tests).
Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
@@ -37,6 +37,7 @@ const DOCS = {
|
||||
agents: {title: 'Plugins', file: path.join(__dirname, '../../docs/plugins.md')},
|
||||
plugins: {title: 'Plugins', file: path.join(__dirname, '../../docs/plugins.md')},
|
||||
vault: {title: 'Vault Secrets', file: path.join(__dirname, '../../docs/vault.md')},
|
||||
groups: {title: 'Groups & Permissions', file: path.join(__dirname, '../../docs/groups.md')},
|
||||
|
||||
overview: {title: 'Overview', file: path.join(__dirname, '../../README.md')},
|
||||
changelog: {title: 'Changelog', file: path.join(__dirname, '../../CHANGELOG.md')},
|
||||
|
||||
@@ -188,10 +188,6 @@ router.get('/users/:uid', function(req, res, next) {
|
||||
res.render('profile', {...values});
|
||||
});
|
||||
|
||||
router.get('/groups', function(req, res, next) {
|
||||
res.render('groups', {...values});
|
||||
});
|
||||
|
||||
router.get('/token', function(req, res, next) {
|
||||
res.render('token', {...values});
|
||||
});
|
||||
|
||||
@@ -90,7 +90,13 @@ router.get('/me', async function(req, res, next){
|
||||
// same answer in both modes.
|
||||
const groups = await groupCns(user);
|
||||
user.groups = groups;
|
||||
user.isAdmin = groups.includes('app_sso_admin') || groups.includes(permission.SUPER_ADMIN_GROUP);
|
||||
// Console admin under the group model (docs/GROUPS.md §11): god_admin,
|
||||
// a site super admin, the SSO-as-app admin ({site}_app_sso_admin), or the
|
||||
// legacy app_sso_admin/app_super_admin during migration.
|
||||
user.isAdmin = groups.some((g) =>
|
||||
g === 'app_sso_admin' || g === 'app_super_admin' ||
|
||||
g === permission.SUPER_ADMIN_GROUP ||
|
||||
g.endsWith('_super_admin') || g.endsWith('_app_sso_admin'));
|
||||
|
||||
return res.json(user);
|
||||
}catch(error){
|
||||
|
||||
Reference in New Issue
Block a user