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;
+ }
+
}