diff --git a/public/main/admin/user_add.php b/public/main/admin/user_add.php index 6c14b1d81fb..06ae31a8e98 100644 --- a/public/main/admin/user_add.php +++ b/public/main/admin/user_add.php @@ -403,6 +403,7 @@ function updateStatus(){ $template = isset($user['email_template_option']) ? $user['email_template_option'] : []; $roles = $user['roles'] ?? []; + $roles = array_values(array_unique(array_map('api_normalize_role_code', $roles))); $status = api_status_from_roles($roles); if ((int) ($user['admin']['platform_admin'] ?? 0) === 1) { $status = COURSEMANAGER; @@ -467,6 +468,7 @@ function updateStatus(){ } $repo = Container::getUserRepository(); + /* @var User $userEntity */ $userEntity = $repo->find($user_id); if ($userEntity) { @@ -474,6 +476,12 @@ function updateStatus(){ $repo->updateUser($userEntity); } + if (api_has_admin_role($roles)) { + UserManager::addUserAsAdmin($userEntity); + } else { + UserManager::removeUserAdmin($userEntity); + } + $extraFieldValues = new ExtraFieldValue('user'); $user['item_id'] = $user_id; $extraFieldValues->saveFieldValues($user); diff --git a/public/main/admin/user_edit.php b/public/main/admin/user_edit.php index 07ec6639bec..db1c4525741 100644 --- a/public/main/admin/user_edit.php +++ b/public/main/admin/user_edit.php @@ -415,6 +415,7 @@ function confirmation(name) { } $roles = $user['roles'] ?? []; + $roles = array_values(array_unique(array_map('api_normalize_role_code', $roles))); $newStatus = api_status_from_roles($roles); if ($newStatus === DRH && CourseManager::is_user_subscribed_in_course((int) $user_id)) { $error_drh = true; @@ -556,12 +557,19 @@ function confirmation(name) { } $repo = Container::getUserRepository(); + /* @var User $userEntity */ $userEntity = $repo->find($user_id); if ($userEntity) { $userEntity->setRoles($roles); $repo->updateUser($userEntity); } + if (api_has_admin_role($roles)) { + UserManager::addUserAsAdmin($userEntity); + } else { + UserManager::removeUserAdmin($userEntity); + } + $extraFieldValue = new ExtraFieldValue('user'); $extraFieldValue->saveFieldValues($user); $userInfo = api_get_user_info($user_id); diff --git a/public/main/inc/lib/api.lib.php b/public/main/inc/lib/api.lib.php index 6efa8d82b98..ada7bbf1ae8 100644 --- a/public/main/inc/lib/api.lib.php +++ b/public/main/inc/lib/api.lib.php @@ -6425,39 +6425,58 @@ function api_get_roles(): array /** * Normalizes a role code to canonical "ROLE_*" uppercase form. */ -function api_normalize_role_code(string $code): string -{ - $code = strtoupper(trim($code)); - return str_starts_with($code, 'ROLE_') ? $code : 'ROLE_'.$code; +function api_normalize_role_code(string $code): string { + $c = strtoupper(trim($code)); + $map = [ + 'STUDENT' => 'ROLE_STUDENT', + 'TEACHER' => 'ROLE_TEACHER', + 'HR' => 'ROLE_HR', + 'SESSION_MANAGER' => 'ROLE_SESSION_MANAGER', + 'STUDENT_BOSS' => 'ROLE_STUDENT_BOSS', + 'INVITEE' => 'ROLE_INVITEE', + 'QUESTION_MANAGER' => 'ROLE_QUESTION_MANAGER', + 'ADMIN' => 'ROLE_ADMIN', + 'GLOBAL_ADMIN' => 'ROLE_GLOBAL_ADMIN', + 'SUPER_ADMIN' => 'ROLE_GLOBAL_ADMIN', + 'ROLE_SUPER_ADMIN' => 'ROLE_GLOBAL_ADMIN', + ]; + if (!str_starts_with($c, 'ROLE_')) { + return $map[$c] ?? ('ROLE_'.$c); + } + return $map[$c] ?? $c; } /** * Priority when deriving legacy status from roles (first match wins). */ -function api_roles_priority(): array -{ +function api_roles_priority(): array { return [ + 'ROLE_GLOBAL_ADMIN', + 'ROLE_ADMIN', 'ROLE_SESSION_MANAGER', - 'ROLE_HR', 'ROLE_TEACHER', + 'ROLE_HR', 'ROLE_STUDENT_BOSS', 'ROLE_INVITEE', 'ROLE_STUDENT', ]; } -/** - * Canonical role -> legacy status map. - */ -function api_role_status_map(): array -{ +function api_has_admin_role(array $roles): bool { + $n = array_map('api_normalize_role_code', $roles); + return in_array('ROLE_ADMIN', $n, true) || in_array('ROLE_GLOBAL_ADMIN', $n, true); +} + +function api_role_status_map(): array { return [ - 'ROLE_SESSION_MANAGER' => SESSIONADMIN, - 'ROLE_HR' => DRH, - 'ROLE_TEACHER' => COURSEMANAGER, - 'ROLE_STUDENT_BOSS' => STUDENT_BOSS, - 'ROLE_INVITEE' => INVITEE, - 'ROLE_STUDENT' => STUDENT, + 'ROLE_GLOBAL_ADMIN' => COURSEMANAGER, // 1 + 'ROLE_ADMIN' => COURSEMANAGER, // 1 + 'ROLE_SESSION_MANAGER'=> COURSEMANAGER, // 1 + 'ROLE_TEACHER' => COURSEMANAGER, // 1 + 'ROLE_HR' => DRH, // 4 + 'ROLE_STUDENT_BOSS' => STUDENT_BOSS, + 'ROLE_INVITEE' => INVITEE, + 'ROLE_STUDENT' => STUDENT, // 5 (fallback) ]; } diff --git a/public/main/install/install.lib.php b/public/main/install/install.lib.php index 33a778bb08f..5871c82282a 100644 --- a/public/main/install/install.lib.php +++ b/public/main/install/install.lib.php @@ -1546,19 +1546,45 @@ function finishInstallationWithContainer( ->setTimezone($timezone) ; + $existingRoles = method_exists($admin, 'getRoles') ? $admin->getRoles() : []; + $normalized = array_map('api_normalize_role_code', $existingRoles); + $mustHave = ['ROLE_ADMIN', 'ROLE_GLOBAL_ADMIN']; + $roles = array_values(array_unique(array_merge($normalized, $mustHave))); + + $admin->setRoles($roles); $repo->updateUser($admin); + if (in_array('ROLE_ADMIN', $roles, true) || in_array('ROLE_GLOBAL_ADMIN', $roles, true)) { + UserManager::addUserAsAdmin($admin); + } else { + UserManager::removeUserAdmin($admin); + } + /** @var User $anonUser */ $anonUser = $repo->findOneBy(['username' => 'anon']); - $anonUser->addAuthSourceByAuthentication(UserAuthSource::PLATFORM, $accessUrl); - - $repo->updateUser($anonUser); + if ($anonUser) { + $anonUser->addAuthSourceByAuthentication(UserAuthSource::PLATFORM, $accessUrl); + $anonRoles = method_exists($anonUser, 'getRoles') ? (array) $anonUser->getRoles() : []; + if (empty($anonRoles)) { + $anonUser->setRoles(['ROLE_USER']); + } else { + $anonUser->setRoles(array_values(array_unique(array_map('api_normalize_role_code', $anonRoles)))); + } + $repo->updateUser($anonUser); + } /** @var User $fallbackUser */ $fallbackUser = $repo->findOneBy(['username' => 'fallback_user']); - $fallbackUser->addAuthSourceByAuthentication(UserAuthSource::PLATFORM, $accessUrl); - - $repo->updateUser($fallbackUser); + if ($fallbackUser) { + $fallbackUser->addAuthSourceByAuthentication(UserAuthSource::PLATFORM, $accessUrl); + $fallbackRoles = method_exists($fallbackUser, 'getRoles') ? $fallbackUser->getRoles() : []; + if (empty($fallbackRoles)) { + $fallbackUser->setRoles(['ROLE_USER']); + } else { + $fallbackUser->setRoles(array_values(array_unique(array_map('api_normalize_role_code', $fallbackRoles)))); + } + $repo->updateUser($fallbackUser); + } // Set default language Database::update(