From c0bf17968858f36d536a0f51236e54585864b942 Mon Sep 17 00:00:00 2001 From: roadiz-ci Date: Wed, 18 Sep 2024 08:19:01 +0000 Subject: [PATCH] Merge pull request #12 from roadiz/feature/passwordless-public-user --- config/services.yaml | 3 - ...wtAuthenticationSuccessEventSubscriber.php | 41 +++++++++++ .../JwtAuthenticationSuccessHandler.php | 34 ---------- .../LoginLink/EmailLoginLinkSender.php | 68 +++++++++++++++++++ .../LoginLink/LoginLinkSenderInterface.php | 16 +++++ src/Security/User/UserViewer.php | 34 ++-------- 6 files changed, 132 insertions(+), 64 deletions(-) create mode 100644 src/EventSubscriber/JwtAuthenticationSuccessEventSubscriber.php delete mode 100644 src/Security/Authentication/JwtAuthenticationSuccessHandler.php create mode 100644 src/Security/LoginLink/EmailLoginLinkSender.php create mode 100644 src/Security/LoginLink/LoginLinkSenderInterface.php diff --git a/config/services.yaml b/config/services.yaml index 5d0d030b..d4b1e318 100644 --- a/config/services.yaml +++ b/config/services.yaml @@ -468,9 +468,6 @@ services: Solarium\Core\Client\Client: factory: ['RZ\Roadiz\CoreBundle\SearchEngine\ClientRegistry', 'getClient'] - RZ\Roadiz\CoreBundle\Security\Authentication\JwtAuthenticationSuccessHandler: - decorates: 'lexik_jwt_authentication.handler.authentication_success' - RZ\Roadiz\CoreBundle\Security\Authorization\Chroot\NodeChrootResolver: alias: RZ\Roadiz\CoreBundle\Security\Authorization\Chroot\NodeChrootChainResolver diff --git a/src/EventSubscriber/JwtAuthenticationSuccessEventSubscriber.php b/src/EventSubscriber/JwtAuthenticationSuccessEventSubscriber.php new file mode 100644 index 00000000..3624b404 --- /dev/null +++ b/src/EventSubscriber/JwtAuthenticationSuccessEventSubscriber.php @@ -0,0 +1,41 @@ + 'onAuthenticationSuccess', + AuthenticationSuccessEvent::class => 'onAuthenticationSuccess', + ]; + } + + public function onAuthenticationSuccess(AuthenticationSuccessEvent $event): void + { + $user = $event->getUser(); + + if (!($user instanceof User)) { + return; + } + + $user->setLastLogin(new \DateTime()); + $this->managerRegistry->getManager()->flush(); + } +} diff --git a/src/Security/Authentication/JwtAuthenticationSuccessHandler.php b/src/Security/Authentication/JwtAuthenticationSuccessHandler.php deleted file mode 100644 index d21a2a3d..00000000 --- a/src/Security/Authentication/JwtAuthenticationSuccessHandler.php +++ /dev/null @@ -1,34 +0,0 @@ -decorated->onAuthenticationSuccess($request, $token); - $user = $token->getUser(); - - if ($user instanceof User) { - $user->setLastLogin(new \DateTime()); - $this->managerRegistry->getManager()->flush(); - } - return $response; - } -} diff --git a/src/Security/LoginLink/EmailLoginLinkSender.php b/src/Security/LoginLink/EmailLoginLinkSender.php new file mode 100644 index 00000000..d58c49eb --- /dev/null +++ b/src/Security/LoginLink/EmailLoginLinkSender.php @@ -0,0 +1,68 @@ +isEnabled()) { + throw new \InvalidArgumentException('User must be enabled to send a login link.'); + } + + if (!\method_exists($user, 'getEmail')) { + throw new \InvalidArgumentException('User implementation must have getEmail method.'); + } + + if (null === $user->getEmail()) { + throw new \InvalidArgumentException('User must have an email to send a login link.'); + } + + $emailManager = $this->emailManagerFactory->create(); + $emailContact = $this->settingsBag->get('email_sender', null); + if (!\is_string($emailContact)) { + throw new \InvalidArgumentException('Email sender must be a string.'); + } + $siteName = $this->settingsBag->get('site_name', null); + if (!\is_string($siteName)) { + throw new \InvalidArgumentException('Site name must be a string.'); + } + + $emailManager->setAssignation([ + 'loginLink' => $loginLinkDetails->getUrl(), + 'expiresAt' => $loginLinkDetails->getExpiresAt(), + 'user' => $user, + 'site' => $siteName, + 'mailContact' => $emailContact, + ]); + $emailManager->setEmailTemplate($this->htmlTemplate); + $emailManager->setEmailPlainTextTemplate($this->txtTemplate); + $emailManager->setSubject($this->translator->trans( + 'login_link.request' + )); + + $emailManager->setReceiver($user->getEmail()); + $emailManager->setSender([$emailContact => $siteName]); + + // Send the message + $emailManager->send(); + } +} diff --git a/src/Security/LoginLink/LoginLinkSenderInterface.php b/src/Security/LoginLink/LoginLinkSenderInterface.php new file mode 100644 index 00000000..894eeda1 --- /dev/null +++ b/src/Security/LoginLink/LoginLinkSenderInterface.php @@ -0,0 +1,16 @@ +isEnabled())) { - throw new \InvalidArgumentException('User must be enabled to send a login link.'); - } - - $emailManager = $this->emailManagerFactory->create(); - $emailContact = $this->getContactEmail(); - $siteName = $this->getSiteName(); - - $emailManager->setAssignation([ - 'loginLink' => $loginLinkDetails->getUrl(), - 'expiresAt' => $loginLinkDetails->getExpiresAt(), - 'user' => $user, - 'site' => $siteName, - 'mailContact' => $emailContact, - ]); - $emailManager->setEmailTemplate($htmlTemplate); - $emailManager->setEmailPlainTextTemplate($txtTemplate); - $emailManager->setSubject($this->translator->trans( - 'login_link.request' - )); - - $emailManager->setReceiver($user->getEmail()); - $emailManager->setSender([$emailContact => $siteName]); - - // Send the message - $emailManager->send(); + $this->loginLinkSender->sendLoginLink($user, $loginLinkDetails); } /**