diff --git a/Entity/TemporaryUser.php b/Entity/TemporaryUser.php new file mode 100644 index 0000000..6a694c7 --- /dev/null +++ b/Entity/TemporaryUser.php @@ -0,0 +1,50 @@ +. + */ +namespace vierbergenlars\AuthserverOAuthAccountBundle\Entity; + +use vierbergenlars\AuthserverExternalAccountBundle\Entity\TemporaryUser as BaseTemporaryUser; + +class TemporaryUser extends BaseTemporaryUser +{ + + /** + * + * @var string + */ + private $email; + + /** + * + * @return string + */ + public function getEmail() + { + return $this->email; + } + + /** + * + * @param string $email + */ + public function setEmail($email) + { + $this->email = $email; + } +} diff --git a/EventListener/RegistrationHandlerListener.php b/EventListener/RegistrationHandlerListener.php new file mode 100644 index 0000000..6da310a --- /dev/null +++ b/EventListener/RegistrationHandlerListener.php @@ -0,0 +1,104 @@ +. + */ +namespace vierbergenlars\AuthserverOAuthAccountBundle\EventListener; + +use Registration\Event\RegistrationHandleEvent; +use Symfony\Component\EventDispatcher\EventSubscriberInterface; +use Registration\RegistrationEvents; +use Registration\Event\RegistrationFormEvent; +use Symfony\Component\Security\Core\Authentication\Token\Storage\TokenStorageInterface; +use vierbergenlars\AuthserverOAuthAccountBundle\Entity\TemporaryUser; +use Doctrine\ORM\EntityManagerInterface; +use App\Entity\EmailAddress; + +class RegistrationHandlerListener implements EventSubscriberInterface +{ + + /** + * + * @var TokenStorageInterface + */ + private $tokenStorage; + + /** + * + * @var EntityManagerInterface + */ + private $em; + + public static function getSubscribedEvents() + { + return [ + RegistrationEvents::BUILD_FORM => [ + 'onBuildForm', + 10 + ], + RegistrationEvents::HANDLE_FORM => [ + 'onHandleForm', + 0 + ] + ]; + } + + public function __construct(EntityManagerInterface $em, TokenStorageInterface $tokenStorage) + { + $this->em = $em; + $this->tokenStorage = $tokenStorage; + } + + private function getTemporaryUser() + { + $token = $this->tokenStorage->getToken(); + if (!$token) + return null; + $user = $token->getUser(); + if ($user instanceof TemporaryUser) + return $user; + return null; + } + + public function onBuildForm(RegistrationFormEvent $event) + { + if ($tempuser = $this->getTemporaryUser()) { + if ($tempuser->getEmail()) { + $user = $event->getFormBuilder()->getData(); + /* @var $user \App\Entity\User */ + if (!$user->getPrimaryEmailAddress()) + $user->addEmailAddress(new EmailAddress()); + $user->getPrimaryEmailAddress()->setEmail($tempuser->getEmail()); + } + } + } + + public function onHandleForm(RegistrationHandleEvent $event) + { + if ($event->isFailed()) + return; + $user = $event->getForm()->getData(); + if (!$user) + return; + /* @var $user \App\Entity\User */ + if ($temporaryUser = $this->getTemporaryUser()) { + if ($temporaryUser->getEmail() && $temporaryUser->getEmail() === $user->getPrimaryEmailAddress()->getEmail()) { + $user->getPrimaryEmailAddress()->setVerified(true); + } + } + } +} diff --git a/Security/Core/User/OAuthUserProvider.php b/Security/Core/User/OAuthUserProvider.php index 0cfd90a..132c489 100644 --- a/Security/Core/User/OAuthUserProvider.php +++ b/Security/Core/User/OAuthUserProvider.php @@ -17,11 +17,8 @@ * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see . */ - - namespace vierbergenlars\AuthserverOAuthAccountBundle\Security\Core\User; - use App\Entity\User; use App\Security\User\UserProvider; use Doctrine\Common\Persistence\ManagerRegistry; @@ -31,11 +28,13 @@ use HWI\Bundle\OAuthBundle\Connect\AccountConnectorInterface; use HWI\Bundle\OAuthBundle\OAuth\Response\UserResponseInterface; use HWI\Bundle\OAuthBundle\Security\Core\Exception\AccountNotLinkedException; use vierbergenlars\AuthserverExternalAccountBundle\Entity\ExternalUser; -use vierbergenlars\AuthserverExternalAccountBundle\Entity\TemporaryUser; +use vierbergenlars\AuthserverOAuthAccountBundle\Entity\TemporaryUser; class OAuthUserProvider extends UserProvider implements OAuthAwareUserProviderInterface, AccountConnectorInterface { + /** + * * @var ManagerRegistry */ private $registry; @@ -46,7 +45,6 @@ class OAuthUserProvider extends UserProvider implements OAuthAwareUserProviderIn $this->registry = $registry; } - /** * Loads the user by a given UserResponseInterface object. * @@ -64,6 +62,8 @@ class OAuthUserProvider extends UserProvider implements OAuthAwareUserProviderIn $user = new TemporaryUser(); $externalUser = $this->createExternalUser($response); $user->setExternalUser($externalUser); + if ($response->getEmail()) + $user->setEmail($response->getEmail()); return $user; } } @@ -102,6 +102,7 @@ class OAuthUserProvider extends UserProvider implements OAuthAwareUserProviderIn } /** + * * @return \Doctrine\Common\Persistence\ObjectRepository */ private function getRepo() @@ -110,6 +111,7 @@ class OAuthUserProvider extends UserProvider implements OAuthAwareUserProviderIn } /** + * * @return \Doctrine\Common\Persistence\ObjectManager|null */ private function getManager() @@ -118,6 +120,7 @@ class OAuthUserProvider extends UserProvider implements OAuthAwareUserProviderIn } /** + * * @param UserResponseInterface $response * @return ExternalUser */ @@ -126,15 +129,15 @@ class OAuthUserProvider extends UserProvider implements OAuthAwareUserProviderIn $repo = $this->getRepo(); $externalAccount = $repo->findOneBy([ - 'provider' => 'oauth_'. $response->getResourceOwner()->getName(), + 'provider' => 'oauth_' . $response->getResourceOwner() + ->getName(), 'provider_ref' => $response->getUsername() ]); - if(!$externalAccount) { + if (!$externalAccount) { throw new AccountNotLinkedException(sprintf('No external account registered for provider "%s", ref: "%s"', $response->getResourceOwner()->getName(), $response->getUsername())); } return $externalAccount; } - }