diff --git a/lib/Command/RecoveryWarningNotificationCommand.php b/lib/Command/RecoveryWarningNotificationCommand.php index 0a6f0d2ac490e252264b37b7127ac0bc594a5a7e..4c78bd171b2dd21e162da6f5b5afd2cc34832fbf 100644 --- a/lib/Command/RecoveryWarningNotificationCommand.php +++ b/lib/Command/RecoveryWarningNotificationCommand.php @@ -123,11 +123,16 @@ class RecoveryWarningNotificationCommand extends Command { // Initialize arrays $this->uids = []; - $this->disableUids = []; - $this->deleteUids = []; + // Only initialize disable/delete arrays if the options are set + if ($disableAccounts) { + $this->disableUids = []; + } + if ($deleteAccounts) { + $this->deleteUids = []; + } // Process users - $this->identifyUnverifiedUsers($output); + $this->identifyUnverifiedUsers($output, $disableAccounts, $deleteAccounts); $this->sendNotificationsAndEmails($output); if ($disableAccounts) { @@ -143,8 +148,12 @@ class RecoveryWarningNotificationCommand extends Command { $output->writeln('[' . $endTime . '] === Command Summary ==='); $output->writeln(' - Users for notifications: ' . count($this->uids)); - $output->writeln(' - Users for disable: ' . count($this->disableUids)); - $output->writeln(' - Users for deletion: ' . count($this->deleteUids)); + if ($disableAccounts) { + $output->writeln(' - Users for disable: ' . count($this->disableUids)); + } + if ($deleteAccounts) { + $output->writeln(' - Users for deletion: ' . count($this->deleteUids)); + } $output->writeln(' - Total execution time: ' . round($overallDuration, 2) . 's'); $output->writeln('[' . $endTime . '] Recovery warning notification command completed successfully.'); @@ -159,8 +168,30 @@ class RecoveryWarningNotificationCommand extends Command { } + /** + * Get user object without caching to avoid memory accumulation + * Uses getBackends to walk through all backends and get user with caching disabled + * + * @param string $username The username to retrieve + * @return \OCP\IUser|null The user object or null if not found + */ + private function getUser(string $username) { + $backends = $this->userManager->getBackends(); + + foreach ($backends as $backend) { + if ($backend->userExists($username)) { + // Use getUserObject with cacheUser = false to avoid caching + // This prevents the user object from being stored in the manager's cache + return $this->userManager->getUserObject($username, $backend, false); + } + } + + return null; + } - private function identifyUnverifiedUsers(OutputInterface $output): void { + private function identifyUnverifiedUsers(OutputInterface $output, bool $checkDisable = false, bool $checkDelete = false): void { + $identificationStart = microtime(true); + $users = $this->config->getUsersForUserValue(Application::APP_ID, 'recovery-email', ''); if (!is_array($users)) { $output->writeln('Error: Expected array for recovery-email users, got ' . gettype($users) . ''); @@ -181,7 +212,7 @@ class RecoveryWarningNotificationCommand extends Command { foreach ($users as $username) { try { - $user = $this->userManager->get($username); + $user = $this->getUser($username); if (!$user) { $invalidCount++; @@ -240,8 +271,13 @@ class RecoveryWarningNotificationCommand extends Command { $this->uids[] = $uid; } - $this->identifyForDisable($user, $age); - $this->identifyForDelete($user, $age); + // Only check for disable/delete if the options are set + if ($checkDisable) { + $this->identifyForDisable($user, $age); + } + if ($checkDelete) { + $this->identifyForDelete($user, $age); + } $disabledAtTimestamp = strtotime($existingDisableDate); $deleteDate = date('Y-m-d', $disabledAtTimestamp + ($this->deleteUserAfterDisableDays * 24 * 60 * 60)); @@ -264,6 +300,8 @@ class RecoveryWarningNotificationCommand extends Command { } } + $identificationDuration = microtime(true) - $identificationStart; + $output->writeln('User processing summary:'); $output->writeln(' - Total users: ' . count($users)); $output->writeln(' - Processed: ' . $processedCount); @@ -272,8 +310,13 @@ class RecoveryWarningNotificationCommand extends Command { $output->writeln(' - Invalid: ' . $invalidCount); $output->writeln(' - Errors: ' . $errorCount); $output->writeln(' - For notifications: ' . count($this->uids)); - $output->writeln(' - For disable: ' . count($this->disableUids)); - $output->writeln(' - For deletion: ' . count($this->deleteUids)); + if ($checkDisable) { + $output->writeln(' - For disable: ' . count($this->disableUids)); + } + if ($checkDelete) { + $output->writeln(' - For deletion: ' . count($this->deleteUids)); + } + $output->writeln(' - Identification time: ' . round($identificationDuration, 2) . 's'); } private function identifyForDisable($user, int $age): void {