[ 'onUserCheck' ], AuthenticationEvents::AUTHENTICATION_SUCCESS => [ 'onAuthenticationSuccess' ], StatsEvent::class => [ 'getExpiryStats', -10 ] ]; } public function __construct(EntityManagerInterface $em, PrimedTwigMailer $mailer, LoggerInterface $logger) { $this->em = $em; $this->mailer = $mailer; $this->logger = $logger; } /** * * @return EntityRepository */ private function getRepository() { return $this->em->getRepository(ExpiredUser::class); } /** * * @param User $user * @return ExpiredUser|null */ private function getExpiredUserForUser(User $user) { return $this->getRepository()->findOneBy([ 'user' => $user ]); } public function onUserCheck(UserCheckerEvent $event) { $user = $event->getUser(); $this->logger->debug("Checking expiry of user", [ 'user' => $user ]); if (!($user instanceof User)) { $this->logger->debug('Not applicable to this type of user', [ 'user' => $user ]); return; } /* @var $user User */ $expiredUser = $this->getExpiredUserForUser($user); $this->logger->debug('Fetched user expiry record', [ 'expired_user' => $expiredUser, 'is_expired' => $expiredUser ? $expiredUser->isExpired() : null ]); if ($expiredUser !== null && $expiredUser->isExpired()) { $emailAddresses = $user->getEmailAddresses()->toArray(); $this->logger->info('User marked as expired. Unverifying all email addresses.', [ 'user' => $user, 'email_addresses' => $emailAddresses ]); foreach ($emailAddresses as $emailAddress) { /* @var $emailAddress \App\Entity\EmailAddress */ $emailAddress->setVerified(false); if (!$this->mailer->sendMessage($emailAddress->getEmail(), $emailAddress)) { $this->logger->error('Verification email could not be sent.', [ 'email_address' => $emailAddress ]); } } $this->em->flush(); throw new AccountExpiredException('Email address verification expired. An email has been sent to your email addresses to reactivate your account.'); } } public function onAuthenticationSuccess(AuthenticationEvent $event) { $this->logger->debug("Updating last login time of user", [ 'token' => $event->getAuthenticationToken(), 'user' => $event->getAuthenticationToken() ->getUser() ]); $token = $event->getAuthenticationToken(); foreach ($token->getRoles() as $role) { if ($role instanceof SwitchUserRole) { $this->logger->info('Authentication success event is caused by an impersonation. Not registering a new login.', [ 'role' => $role ]); return; } } $user = $token->getUser(); if (!($user instanceof User)) { $this->logger->debug('Not applicable to this type of user', [ 'user' => $user ]); return; } $expiredUser = $this->getExpiredUserForUser($user); $this->logger->debug('Fetched user expiry record', [ 'expired_user' => $expiredUser, 'is_expired' => $expiredUser ? $expiredUser->isExpired() : null ]); if ($expiredUser === null) { $this->logger->debug('No user expiry record exists. Creating a new one.'); $expiredUser = new ExpiredUser($user); $this->em->persist($expiredUser); } $expiredUser->setLastLogin(new \DateTime()); $this->em->flush($expiredUser); } public function getExpiryStats(StatsEvent $event) { if (!$event->isEnabled('autoexpire')) return; $event->setMuninConfig('user', $event->getMuninConfig('user') + [ 'autoexpire.label' => 'Expired users', 'autoexpire.draw' => 'LINE' ]); $expiredUsers = $this->getRepository() ->createQueryBuilder('e') ->select('count(e.expiredAt)') ->where('e.expiredAt IS NOT NULL AND e.expiredAt < :now') ->setParameter('now', new \DateTime()) ->getQuery() ->getSingleScalarResult(); $event->addStatistic('user.autoexpire', $expiredUsers); } }