fix: keep SUPER_ADMIN_GROUP as app_super_admin so resource auto-provisioning nesting works

api_directory_admin nests permission.SUPER_ADMIN_GROUP into every new resource's
_admin group. Changing it to the not-yet-existing 'god_admin' made that nesting
no-op, leaving the creator as the sole member (so the access_request test's
beforeAll could not remove the last member of a groupOfNames). Revert it to
'app_super_admin' and recognize 'god_admin' separately in isSuperAdmin + isAdmin.

Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
2026-08-04 16:31:00 -04:00
parent 6d9c2f05ba
commit f00d311029
2 changed files with 10 additions and 4 deletions
+1 -1
View File
@@ -95,7 +95,7 @@ router.get('/me', async function(req, res, next){
// 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 === 'god_admin' || g === permission.SUPER_ADMIN_GROUP ||
g.endsWith('_super_admin') || g.endsWith('_app_sso_admin'));
return res.json(user);
+9 -3
View File
@@ -3,12 +3,18 @@
const {Group} = require('../models/group_ldap');
const groups = require('./groups');
// The global god-admin group (everything, everywhere). During migration the
// legacy `app_super_admin` is recognized as an alias (docs/GROUPS.md §10).
const SUPER_ADMIN_GROUP = groups.GOD_ADMIN;
// The group nested into every resource's _admin group by api_directory_admin
// (cross-resource super-admin administration). KEEP the legacy `app_super_admin`
// here: it is the group that actually exists and gets nested. The new schema's
// global `god_admin` is recognized in isSuperAdmin() below, and api_directory_admin
// nests SUPER_ADMIN_GROUP -- so until `god_admin` is created during bootstrap, this
// must stay `app_super_admin` or resource auto-provisioning's nesting silently
// no-ops (leaving only the creator as the group's sole member).
const SUPER_ADMIN_GROUP = 'app_super_admin';
const LEGACY_SUPER_ADMIN_ALIASES = ['app_super_admin'];
// True if the user (by resolved member cns) is a global god/super admin.
// Recognizes BOTH the new schema's `god_admin` and the legacy `app_super_admin`.
async function isSuperAdmin(memberOfCns) {
return memberOfCns.includes(groups.GOD_ADMIN) ||
memberOfCns.some((cn) => LEGACY_SUPER_ADMIN_ALIASES.includes(cn));