From 6888539f595ad26ab1ec4adef38fd57c5be50b7b Mon Sep 17 00:00:00 2001 From: Lars Vierbergen Date: Fri, 20 Oct 2017 22:48:31 +0200 Subject: [PATCH] Provide a temporary user when a user logs in with an unlinked external account --- Security/Core/User/OAuthUserProvider.php | 36 +++++++++++++++++------- 1 file changed, 26 insertions(+), 10 deletions(-) diff --git a/Security/Core/User/OAuthUserProvider.php b/Security/Core/User/OAuthUserProvider.php index 624a0b5..0cfd90a 100644 --- a/Security/Core/User/OAuthUserProvider.php +++ b/Security/Core/User/OAuthUserProvider.php @@ -25,12 +25,13 @@ namespace vierbergenlars\AuthserverOAuthAccountBundle\Security\Core\User; use App\Entity\User; use App\Security\User\UserProvider; use Doctrine\Common\Persistence\ManagerRegistry; +use Symfony\Component\Security\Core\User\UserInterface; +use HWI\Bundle\OAuthBundle\Security\Core\User\OAuthAwareUserProviderInterface; use HWI\Bundle\OAuthBundle\Connect\AccountConnectorInterface; use HWI\Bundle\OAuthBundle\OAuth\Response\UserResponseInterface; use HWI\Bundle\OAuthBundle\Security\Core\Exception\AccountNotLinkedException; -use HWI\Bundle\OAuthBundle\Security\Core\User\OAuthAwareUserProviderInterface; -use Symfony\Component\Security\Core\User\UserInterface; use vierbergenlars\AuthserverExternalAccountBundle\Entity\ExternalUser; +use vierbergenlars\AuthserverExternalAccountBundle\Entity\TemporaryUser; class OAuthUserProvider extends UserProvider implements OAuthAwareUserProviderInterface, AccountConnectorInterface { @@ -57,24 +58,39 @@ class OAuthUserProvider extends UserProvider implements OAuthAwareUserProviderIn */ public function loadUserByOAuthUserResponse(UserResponseInterface $response) { - return $this->getExternalAccount($response)->getUser(); + try { + return $this->getExternalAccount($response)->getUser(); + } catch (AccountNotLinkedException $ex) { + $user = new TemporaryUser(); + $externalUser = $this->createExternalUser($response); + $user->setExternalUser($externalUser); + return $user; + } + } + + private function createExternalUser(UserResponseInterface $response) + { + $externalUser = new ExternalUser(); + $externalUser->setProvider('oauth_' . $response->getResourceOwner() + ->getName()); + $externalUser->setProviderRef($response->getUsername()); + $externalUser->setProviderFriendlyName($response->getRealName()); + + return $externalUser; } public function connect(UserInterface $user, UserResponseInterface $response) { - if(!$user instanceof User) - throw new \UnexpectedValueException('User must be instance of '.User::class.', got '.get_class($username)); + if (!$user instanceof User) + throw new \UnexpectedValueException('User must be instance of ' . User::class . ', got ' . get_class($user)); try { $externalUser = $this->getExternalAccount($response); $this->disconnect($externalUser); - } catch(AccountNotLinkedException $ex) { + } catch (AccountNotLinkedException $ex) { // do nothing } - $externalUser = new ExternalUser(); + $externalUser = $this->createExternalUser($response); $externalUser->setUser($user); - $externalUser->setProvider('oauth_'.$response->getResourceOwner()->getName()); - $externalUser->setProviderRef($response->getUsername()); - $externalUser->setProviderFriendlyName($response->getRealName()); $this->getManager()->persist($externalUser); $this->getManager()->flush(); }