From f2f431b9a695809a0ce23e0998a6857237035d35 Mon Sep 17 00:00:00 2001 From: Lars Vierbergen Date: Sat, 12 May 2018 16:17:30 +0200 Subject: [PATCH] Add command to expire users --- Command/ExpireUsersCommand.php | 108 ++++++++++++++++++++++++++ EventListener/CheckExpiryListener.php | 4 +- 2 files changed, 110 insertions(+), 2 deletions(-) create mode 100644 Command/ExpireUsersCommand.php diff --git a/Command/ExpireUsersCommand.php b/Command/ExpireUsersCommand.php new file mode 100644 index 0000000..0a0a6c9 --- /dev/null +++ b/Command/ExpireUsersCommand.php @@ -0,0 +1,108 @@ +setName('expire:users') + ->addOption('username', null, InputOption::VALUE_REQUIRED, 'The username of the user to expire') + ->addOption('last-login-before', null, InputOption::VALUE_REQUIRED, 'Users with a last login before this date will be expired') + ->addOption('exclude-admins', null, InputOption::VALUE_NONE, 'Exclude admins from expiry') + ->addOption('expire-date', null, InputOption::VALUE_REQUIRED, 'Set the expiry date of expired users to an other date.') + ->addOption('dry-run', null, InputOption::VALUE_NONE, 'Do not actually execute the expiration.'); + } + + protected function execute(InputInterface $input, OutputInterface $output) + { + $em = $this->getApplication() + ->getKernel() + ->getContainer() + ->get('doctrine.orm.entity_manager'); + /* @var $em \Doctrine\ORM\EntityManager */ + $userRepo = $em->getRepository(User::class); + + $queryBuilder = $userRepo->createQueryBuilder('u'); + $queryBuilder->leftJoin(ExpiredUser::class, 'eu', Join::WITH, 'eu.user = u.id'); + $queryBuilder->where('eu.expiredAt IS NULL'); + + if ($input->getOption('username')) { + $queryBuilder->andWhere('u.username = :username')->setParameter('username', $input->getOption('username')); + } + + if ($input->getOption('exclude-admins')) { + $queryBuilder->andWhere('u.role NOT IN (:admin_roles)')->setParameter('admin_roles', [ + 'ROLE_ADMIN', + 'ROLE_SUPER_ADMIN' + ]); + } + + if ($input->getOption('last-login-before')) { + $queryBuilder->andWhere('eu.lastLogin < :lastLogin OR eu.lastLogin IS NULL')->setParameter('lastLogin', new \DateTime($input->getOption('last-login-before'))); + } + + $expireDate = new \DateTime(); + if ($input->getOption('expire-date')) { + $expireDate = new \DateTime($input->getOption('expire-date')); + } + + $style = new SymfonyStyle($input, $output); + $style->comment('Query: ' . $queryBuilder->getDQL()); + $countBuilder = clone $queryBuilder; + $countBuilder->select('count(u.id)'); + $count = $countBuilder->getQuery()->getSingleScalarResult(); + + if ($count == 0) { + $style->warning('No users match these filters.'); + return 0; + } + + if (!$input->getOption('dry-run') && !$style->confirm('Will expire ' . $count . ' users. Continue?', true)) { + $style->error('Expiration cancelled.'); + return 1; + } + if ($input->getOption('dry-run')) { + $style->note('Doing a dry-run.'); + } + $progressBar = $style->createProgressBar($count); + + $usersIterator = $queryBuilder->getQuery()->iterate(); + + foreach ($usersIterator as list ($user)) { + /* @var $user \App\Entity\User */ + $progressBar->clear(); + $style->text('Expired user ' . $user->getUsername()); + $progressBar->display(); + $progressBar->advance(); + $progressBar->setMessage($user->getUsername()); + $expiryRecord = $em->find(ExpiredUser::class, $user); + if (!$expiryRecord) { + $expiryRecord = new ExpiredUser($user); + $em->persist($expiryRecord); + } + $expiryRecord->setExpiredAt($expireDate); + if (!$input->getOption('dry-run')) { + $em->flush($expiryRecord); + } + } + + $progressBar->finish(); + + $style->success('Expired ' . $count . ' users'); + } +} \ No newline at end of file diff --git a/EventListener/CheckExpiryListener.php b/EventListener/CheckExpiryListener.php index 549caf6..d517abf 100644 --- a/EventListener/CheckExpiryListener.php +++ b/EventListener/CheckExpiryListener.php @@ -100,7 +100,7 @@ class CheckExpiryListener implements EventSubscriberInterface $this->logger->debug('Fetched user expiry record', [ 'expired_user' => $expiredUser, - 'is_expired' => $expiredUser->isExpired() + 'is_expired' => $expiredUser ? $expiredUser->isExpired() : null ]); if ($expiredUser !== null && $expiredUser->isExpired()) { @@ -152,7 +152,7 @@ class CheckExpiryListener implements EventSubscriberInterface $this->logger->debug('Fetched user expiry record', [ 'expired_user' => $expiredUser, - 'is_expired' => $expiredUser->isExpired() + 'is_expired' => $expiredUser ? $expiredUser->isExpired() : null ]); if ($expiredUser === null) {