Provide a temporary user when a user logs in with an unlinked external account

master
Lars Vierbergen 7 years ago
parent 42b48bc79b
commit 6888539f59
  1. 30
      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)
{
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));
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) {
// 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();
}