From 6f4be051b97faf7d814778e28134e26f1621c0ea Mon Sep 17 00:00:00 2001 From: Anselm McClain Date: Sat, 12 Oct 2024 07:05:57 -0700 Subject: [PATCH] Minor optimization to DefaultRoleService bootstrapAdminUser (#412) + Resolve possible bootstrapAdminUser setting once, on init, and log if active. + Simplify `getRolesForUser` accordingly - this can get called in hot loops with permission checks, want to do anything we can to keep it lean and mean. --- .../role/provided/DefaultRoleService.groovy | 49 ++++++++++++------- 1 file changed, 31 insertions(+), 18 deletions(-) diff --git a/src/main/groovy/io/xh/hoist/role/provided/DefaultRoleService.groovy b/src/main/groovy/io/xh/hoist/role/provided/DefaultRoleService.groovy index 0e9b69b3..6065184c 100644 --- a/src/main/groovy/io/xh/hoist/role/provided/DefaultRoleService.groovy +++ b/src/main/groovy/io/xh/hoist/role/provided/DefaultRoleService.groovy @@ -76,6 +76,8 @@ import static java.util.Collections.* */ class DefaultRoleService extends BaseRoleService { + static clearCachesConfigs = ['xhRoleModuleConfig'] + ConfigService configService LdapService ldapService DefaultRoleUpdateService defaultRoleUpdateService @@ -95,11 +97,22 @@ class DefaultRoleService extends BaseRoleService { // Local state for primary when computing role assignment protected Map _usersForDirectoryGroups = emptyMap() - static clearCachesConfigs = ['xhRoleModuleConfig'] + // Support granting key Hoist admin roles to an instance-configured user in local dev only, + // for initial bootstrapping during development when databased roles not yet created. + private String bootstrapAdminUser = null + private final Set bootstrapAdminRoles = ['HOIST_ADMIN', 'HOIST_ADMIN_READER', 'HOIST_ROLE_MANAGER'] void init() { ensureRequiredConfigAndRolesCreated() + if (isLocalDevelopment && !isProduction) { + bootstrapAdminUser = getInstanceConfig('bootstrapAdminUser')?.toLowerCase() + if (bootstrapAdminUser) { + logInfo("$bootstrapAdminUser configured as local development bootstrapAdminUser - will be granted $bootstrapAdminRoles") + } + } + + timer = createTimer( name: 'refreshRoles', runFn: this.&refreshRoleAssignments, @@ -129,13 +142,11 @@ class DefaultRoleService extends BaseRoleService { } ret = _roleAssignmentsByUser[username] = unmodifiableSet(userRoles) as Set } - if ( - getInstanceConfig('bootstrapAdminUser')?.toLowerCase() == username && - isLocalDevelopment && - !isProduction - ) { - ret += ['HOIST_ADMIN', 'HOIST_ADMIN_READER', 'HOIST_ROLE_MANAGER'] + + if (bootstrapAdminUser == username) { + ret += bootstrapAdminRoles } + ret } @@ -189,7 +200,7 @@ class DefaultRoleService extends BaseRoleService { protected Map doLoadUsersForDirectoryGroups(Set groups, boolean strictMode) { if (!groups) return emptyMap() if (!ldapService.enabled) { - return groups.collectEntries{[it, 'LdapService not enabled in this application']} + return groups.collectEntries { [it, 'LdapService not enabled in this application'] } } def foundGroups = new HashSet(), @@ -198,7 +209,7 @@ class DefaultRoleService extends BaseRoleService { // 1) Determine valid groups ldapService .lookupGroups(groups, strictMode) - .each {name, group -> + .each { name, group -> if (group) { foundGroups << name } else { @@ -209,7 +220,7 @@ class DefaultRoleService extends BaseRoleService { // 2) Search for members of valid groups ldapService .lookupGroupMembers(foundGroups, strictMode) - .each {name, members -> + .each { name, members -> ret[name] = members.collect(new HashSet()) { it.samaccountname?.toLowerCase() } // Exclude members without a samaccountname (e.g. email-only contacts within a DL) ret[name].remove(null) @@ -234,7 +245,7 @@ class DefaultRoleService extends BaseRoleService { xhRoleModuleConfig: [ valueType : 'json', defaultValue: [ - refreshIntervalSecs : 300 + refreshIntervalSecs: 300 ], groupName : 'xh.io', note : 'Configures built-in role management via DefaultRoleService.' @@ -344,8 +355,8 @@ class DefaultRoleService extends BaseRoleService { roles.collectEntries { role -> Set effectiveRoles = getEffectiveRoles(role), - users = new HashSet(), - groups = new HashSet() + users = new HashSet(), + groups = new HashSet() effectiveRoles.each { effRole -> if (userAssignmentSupported) users.addAll(effRole.users) @@ -396,10 +407,12 @@ class DefaultRoleService extends BaseRoleService { } - Map getAdminStats() {[ - roleAssignments: allRoleAssignments?.size(), - roleAssignmentsByUser: _roleAssignmentsByUser?.size(), - usersForDirectoryGroups: _usersForDirectoryGroups?.size() - ]} + Map getAdminStats() { + [ + roleAssignments : allRoleAssignments?.size(), + roleAssignmentsByUser : _roleAssignmentsByUser?.size(), + usersForDirectoryGroups: _usersForDirectoryGroups?.size() + ] + } }