diff --git a/appinfo/info.xml b/appinfo/info.xml index 35a9b216ad75861c84ebdedff327b494c024ec54..078c564170272a8fcc4ddb08e9122fc7fbeb1e78 100644 --- a/appinfo/info.xml +++ b/appinfo/info.xml @@ -28,5 +28,6 @@ OCA\EcloudAccounts\Command\Migrate2FASecrets OCA\EcloudAccounts\Command\MigrateWebmailAddressbooks OCA\EcloudAccounts\Command\MapActiveAttributetoLDAP + OCA\EcloudAccounts\Command\ResetUserPreferences diff --git a/lib/Command/ResetUserPreferences.php b/lib/Command/ResetUserPreferences.php new file mode 100644 index 0000000000000000000000000000000000000000..1bef4c863970f51ad40f71bd6c98c5b984eb0539 --- /dev/null +++ b/lib/Command/ResetUserPreferences.php @@ -0,0 +1,99 @@ +ldapService = $ldapService; + $this->db = $db; + parent::__construct(); + } + /** + * run: occ ecloud-accounts:reset-user-preferences --date='2024-12-01 00:00:00' + * @return void + */ + protected function configure(): void { + $this + ->setName('ecloud-accounts:reset-user-preferences') + ->setDescription('Invalidate sessions and remove preferences for users created after a specific date') + ->addOption( + 'date', + null, + InputOption::VALUE_REQUIRED, + 'Date in YYYY-MM-DD HH-MM-SS format (e.g., 2024-12-01 00:00:00)', + null + ); + } + + protected function execute(InputInterface $input, OutputInterface $output): int { + $date = $input->getOption('date'); + + if (!$date) { + $output->writeln('Date option is required.'); + return Command::INVALID; + } + + try { + // Fetch users from LDAP + $users = $this->ldapService->getUsersCreatedAfter($date); + + foreach ($users as $user) { + if (!$user['username']) { + continue; + } + + $username = $user['username']; + $output->writeln("Processing user: $username"); + + // Invalidate user sessions + $this->invalidateUserSessions($username); + $output->writeln("Invalidated session for user: $username"); + + // Delete specific preferences + $this->deletePreference($username, 'firstLoginAccomplished'); + $output->writeln("Deleted 'firstLoginAccomplished' preference for user: $username"); + + $this->deletePreference($username, 'lastLogin'); + $output->writeln("Deleted 'lastLogin' preference for user: $username"); + } + + $output->writeln('All sessions invalidated and preferences deleted for eligible users.'); + return Command::SUCCESS; + } catch (\Exception $e) { + $output->writeln('Error: ' . $e->getMessage()); + return Command::FAILURE; + } + } + + private function invalidateUserSessions(string $username): void { + $qb = $this->db->getQueryBuilder(); + + $qb->delete('authtoken') + ->where($qb->expr()->eq('uid', $qb->createNamedParameter($username, IQueryBuilder::PARAM_STR))); + + $qb->executeStatement(); + } + + private function deletePreference(string $username, string $key): void { + $qb = $this->db->getQueryBuilder(); + + $qb->delete('preferences') + ->where($qb->expr()->eq('userid', $qb->createNamedParameter($username, IQueryBuilder::PARAM_STR))) + ->andWhere($qb->expr()->eq('configkey', $qb->createNamedParameter($key, IQueryBuilder::PARAM_STR))); + + $qb->executeStatement(); + } +} diff --git a/lib/Service/LDAPConnectionService.php b/lib/Service/LDAPConnectionService.php index f7609941af21cc77e50b6ec2de74a61732f0fa0f..7aa6315747a275c8c71a8148921cc212f6d87975 100644 --- a/lib/Service/LDAPConnectionService.php +++ b/lib/Service/LDAPConnectionService.php @@ -122,4 +122,39 @@ class LDAPConnectionService { $this->closeLDAPConnection($conn); } + public function getUsersCreatedAfter(string $date): array { + if (!$this->isLDAPEnabled()) { + throw new Exception('LDAP backend is not enabled'); + } + + // Convert the provided date to LDAP Generalized Time format: YYYYMMDDHHMMSSZ + $formattedDate = (new \DateTime($date))->format('YmdHis') . 'Z'; + + $conn = $this->getLDAPConnection(); + $baseDn = implode(',', $this->getLDAPBaseUsers()); + $filter = sprintf('(createTimestamp>=%s)', $formattedDate); + + $searchResult = ldap_search($conn, $baseDn, $filter, ['dn', 'username', 'createTimestamp']); + if (!$searchResult) { + $this->closeLDAPConnection($conn); + throw new Exception('LDAP search failed for createTimestamp after: ' . $date); + } + + $entries = ldap_get_entries($conn, $searchResult); + $this->closeLDAPConnection($conn); + + $users = []; + if ($entries['count'] > 0) { + for ($i = 0; $i < $entries['count']; $i++) { + $users[] = [ + 'dn' => $entries[$i]['dn'], + 'username' => $entries[$i]['username'][0] ?? null, + 'createTimestamp' => $entries[$i]['createtimestamp'][0] ?? null, + ]; + } + } + + return $users; + } + }