From d0eaf5d50445e78abb3eb9d1d126ca1435993aa0 Mon Sep 17 00:00:00 2001 From: tiran133 Date: Wed, 24 Jun 2026 08:54:13 +1000 Subject: [PATCH] Detach unmapped OIDC roles during user sync Update OIDC role synchronisation, so existing users lose mapped global roles when their provider claims no longer match the configured role mapping. Keep role matching behaviour for new users unchanged, while writing a Role detach action for existing users when a mapped claim is missing or does not contain the configured value. --- .../classes/class.ilOpenIdConnectUserSync.php | 35 +++++++++++++------ 1 file changed, 24 insertions(+), 11 deletions(-) diff --git a/components/ILIAS/OpenIdConnect/classes/class.ilOpenIdConnectUserSync.php b/components/ILIAS/OpenIdConnect/classes/class.ilOpenIdConnectUserSync.php index 6b3b31b40e37..b395365891ad 100755 --- a/components/ILIAS/OpenIdConnect/classes/class.ilOpenIdConnectUserSync.php +++ b/components/ILIAS/OpenIdConnect/classes/class.ilOpenIdConnectUserSync.php @@ -304,17 +304,15 @@ protected function parseRoleAssignments(): array continue; } - if (!isset($this->user_info->{$role_attribute})) { - $this->logger->debug('No user info passed'); - continue; - } - if (!$role_info['update'] && !$this->needsCreation()) { $this->logger->debug('No user role update for role: ' . $role_id); continue; } - if (is_array($this->user_info->{$role_attribute})) { + $role_matches = false; + if (!isset($this->user_info->{$role_attribute})) { + $this->logger->debug('No user info passed'); + } elseif (is_array($this->user_info->{$role_attribute})) { $roles_claim = array_map( static function (mixed $value): string { return match (true) { @@ -329,12 +327,27 @@ static function (mixed $value): string { }, $this->user_info->{$role_attribute} ); - if (!in_array($role_value, $roles_claim, true)) { - $this->logger->debug('User account has no ' . $role_value); - continue; - } - } elseif (strcmp(trim((string) $this->user_info->{$role_attribute}), $role_value) !== 0) { + $role_matches = in_array($role_value, $roles_claim, true); + } else { + $role_matches = strcmp(trim((string) $this->user_info->{$role_attribute}), $role_value) === 0; + } + + if (!$role_matches) { $this->logger->debug('User account has no ' . $role_value); + if (!$this->needsCreation()) { + $roles_assignable[(int) $role_id] = (int) $role_id; + $long_role_id = ('il_' . IL_INST_ID . '_role_' . $role_id); + + $this->writer->xmlElement( + 'Role', + [ + 'Id' => $long_role_id, + 'Type' => 'Global', + 'Action' => 'Detach' + ], + null + ); + } continue; }