get_handler_field_info_by_field_variable('cas_user'); if (empty($extraFieldData)) { if ('y' === readline("Create missing 'cas_user' extra field ? (type 'y' to confirm) ")) { $fieldId = $extraField->save( [ 'variable' => 'cas_user', 'field_type' => ExtraField::FIELD_TYPE_TEXT, 'visible_to_self' => true, 'filter' => true, 'display_text' => get_lang('CAS User Identifier'), ] ); if (false === $fieldId) { exit("failed to create extra field\n"); } } else { exit("Required extra field is missing\n"); } } else { $fieldId = $extraFieldData['id']; } echo "'cas_user' extra field id is $fieldId.\n"; // read cas_user extra field existing values as an associative array ( user id => CAS code ) $extraFieldValueModel = new ExtraFieldValue('user'); $recordList = $extraFieldValueModel->getValuesByFieldId($fieldId); $existingCasUserValues = []; if (false !== $recordList) { foreach ($recordList as $value) { $existingCasUserValues[$value['item_id']] = $value['value']; } } echo count($existingCasUserValues)." users have their cas_user value set already.\n"; // read all users from the internal database and check their LDAP CAS code to build a to-do list $userRepository = Database::getManager()->getRepository('ChamiloUserBundle:User'); $databaseUsers = $userRepository->findAll(); $count = count($databaseUsers); echo "$count users are registered in the internal database.\n"; $userNamesInUse = []; foreach ($databaseUsers as $user) { $userNamesInUse[$user->getUsername()] = $user->getId(); } $missingCASCodes = []; $wrongCASCodes = []; $wrongUserNames = []; $wrongAuthSources = []; $checked = 0; foreach ($databaseUsers as $user) { $username = $user->getUsername(); echo "Checked $checked / $count users - now checking '$username'…\r"; $filter = '(&(' .join( ')(', array_merge($filters, ["|($ldapUsernameAttribute=$username)($ldapCASUserAttribute=$username)"]) ) .'))'; $searchResult = ldap_search($ldap, $baseDn, $filter, [$ldapCASUserAttribute, $ldapUsernameAttribute]); if (false === $searchResult) { exit('ldap_search() failed: '.ldap_error($ldap)."\n"); } $userId = $user->getId(); echo "$username ($userId): "; switch (ldap_count_entries($ldap, $searchResult)) { case 0: print "does not exist in the LDAP directory, skipping.\n"; break; case 1: $entry = ldap_first_entry($ldap, $searchResult); if (false === $entry) { exit('ldap_first_entry() failed: '.ldap_error($ldap)."\n"); } $ldapCASUser = ldap_get_values($ldap, $entry, $ldapCASUserAttribute)[0]; if (false === $ldapCASUser) { exit('cannot read CAS user code from LDAP entry: '.ldap_error($ldap)."\n"); } $ldapUsername = ldap_get_values($ldap, $entry, $ldapUsernameAttribute)[0]; if (false === $ldapUsername) { exit('cannot read username from LDAP entry: '.ldap_error($ldap)."\n"); } echo "\033[2K\r$ldapUsernameAttribute: $ldapUsername, $ldapCASUserAttribute: $ldapCASUser, "; $problems = []; if ($username === $ldapUsername) { true; // fine } elseif (in_array( strtolower(trim($username)), [strtolower(trim($ldapUsername)), strtolower(trim($ldapCASUser))] )) { if (array_key_exists($ldapUsername, $userNamesInUse)) { echo "wrong username but '$ldapUsername' is already taken, skipping.\n"; break; } else { $problems[] = "wrong username"; $wrongUserNames[$userId] = $ldapUsername; $userNamesInUse[$ldapUsername] = $userId; } } else { exit("LDAP search result does not match username; our filter is wrong: $filter\n"); } if (array_key_exists($userId, $existingCasUserValues)) { $currentValue = $existingCasUserValues[$userId]; if ($currentValue !== $ldapCASUser) { $problems[] = "wrong current CAS user code '$currentValue'"; $wrongCASCodes[$userId] = $ldapCASUser; } } else { $problems[] = "CAS user code missing in database"; $missingCASCodes[$userId] = $ldapCASUser; } $currentAuthSource = $user->getAuthSource(); if (CAS_AUTH_SOURCE !== $currentAuthSource) { $problems[] = "wrong auth source '$currentAuthSource'"; $wrongAuthSources[$userId] = true; } echo empty($problems) ? "ok\r" : (join(', ', $problems)."\n"); break; default: print "more than 1 entries for username '$username' in the LDAP directory for user id=$userId, skipping.\n"; } $checked++; } echo "\033[2K\r"; // ask for confirmation and write changes to the database $fixUsernames = ( !empty($wrongUserNames) && ('y' === readline("Fix wrong user names for ".count($wrongUserNames)." users ? (type 'y' to confirm) ")) ); if ($fixUsernames) { echo "I will fix user names.\n"; } $fixMissingCASCodes = ( !empty($missingCASCodes) && ('y' === readline("Fix missing CAS codes for ".count($missingCASCodes)." users ? (type 'y' to confirm) ")) ); if ($fixMissingCASCodes) { echo "I will fix missing CAS codes.\n"; } $fixWrongCASCodes = ( !empty($wrongCASCodes) && ('y' === readline("Fix wrong CAS codes for ".count($wrongCASCodes)." users ? (type 'y' to confirm) ")) ); if ($fixWrongCASCodes) { echo "I will fix wrong CAS codes.\n"; } $fixWrongAuthSources = ( !empty($wrongAuthSources) && ('y' === readline("Fix auth source for ".count($wrongAuthSources)." users ? (type 'y' to confirm) ")) ); if ($fixWrongAuthSources) { echo "I will fix wrong authentication sources.\n"; } if ($fixUsernames || $fixWrongAuthSources || $fixWrongCASCodes || $fixMissingCASCodes) { $usersToFix = []; foreach ($databaseUsers as $user) { $userId = $user->getId(); if ($fixUsernames && array_key_exists($userId, $wrongUserNames) || $fixWrongAuthSources && array_key_exists($userId, $wrongAuthSources) || $fixMissingCASCodes && array_key_exists($userId, $missingCASCodes) || $fixWrongCASCodes && array_key_exists($userId, $wrongCASCodes) ) { $usersToFix[] = $user; } } $fixCount = count($usersToFix); echo "Now fixing $fixCount out of $count database users…\n"; $done = 0; foreach ($usersToFix as $user) { $userId = $user->getId(); $dirty = false; if ($fixUsernames && array_key_exists($userId, $wrongUserNames)) { $user->setUsername($wrongUserNames[$userId]); $dirty = true; } if ($fixWrongAuthSources && array_key_exists($userId, $wrongAuthSources)) { $user->setAuthSource(CAS_AUTH_SOURCE); $dirty = true; } if ($dirty) { try { UserManager::getManager()->save($user); } catch (Exception $exception) { echo $exception->getMessage()."\n"; exit("Script stopped before the end.\n"); } } if ($fixMissingCASCodes && array_key_exists($userId, $missingCASCodes)) { UserManager::update_extra_field_value($userId, 'cas_user', $missingCASCodes[$userId]); } elseif ($fixWrongCASCodes && array_key_exists($userId, $wrongCASCodes)) { UserManager::update_extra_field_value($userId, 'cas_user', $wrongCASCodes[$userId]); } $done++; echo "Fixed $done / $fixCount users\r"; } echo "\n"; } echo "End of script.\n";