Last active
August 29, 2015 14:10
-
-
Save RomanGorbatko/24b3673994d30c41d191 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php | |
namespace Uasector\UserBundle\UserProvider; | |
use HWI\Bundle\OAuthBundle\OAuth\Response\UserResponseInterface, | |
HWI\Bundle\OAuthBundle\Security\Core\User\OAuthAwareUserProviderInterface, | |
HWI\Bundle\OAuthBundle\Security\Core\User\FOSUBUserProvider as BaseClass; | |
use Symfony\Component\HttpFoundation\Session\Session; | |
use Symfony\Component\Security\Core\Exception\LockedException; | |
use Symfony\Component\Security\Core\User\UserInterface, | |
Symfony\Component\Security\Core\User\UserProviderInterface, | |
Symfony\Component\PropertyAccess\PropertyAccessor; | |
use Doctrine\DBAL\Types, | |
Doctrine\DBAL\DBALException; | |
use Uasector\UserBundle\UserProvider\FacebookProvider, | |
Uasector\UserBundle\UserProvider\VkontakteProvider, | |
Uasector\UserBundle\Entity\User; | |
class UserProvider extends BaseClass implements UserProviderInterface, OAuthAwareUserProviderInterface | |
{ | |
protected $session; | |
/** @var FacebookProvider $facebookProvider */ | |
protected $facebookProvider; | |
/** @var VkontakteProvider $vkontakteProvider */ | |
protected $vkontakteProvider; | |
/** | |
* {@inheritDoc} | |
*/ | |
public function connect(UserInterface $user, UserResponseInterface $response) | |
{ | |
$property = $this->getProperty($response); | |
$username = $response->getUsername(); | |
//on connect - get the access token and the user ID | |
$service = $response->getResourceOwner()->getName(); | |
$setter = 'set'.ucfirst($service); | |
$setterId = $setter.'Id'; | |
//we "disconnect" previously connected users | |
if (null !== $previousUser = $this->userManager->findUserBy(array($property => $username))) { | |
$previousUser->$setterId(null); | |
$this->updateEmails($user, $previousUser); | |
$this->updateOtherSocialIds($user, $previousUser); | |
$this->mergeDreams($user, $previousUser); | |
$this->mergeContributions($user, $previousUser); | |
$this->userManager->deleteUser($previousUser); | |
} | |
//we connect current user | |
$user->$setterId($username); | |
$this->userManager->updateUser($user); | |
} | |
/** | |
* {@inheritdoc} | |
*/ | |
public function loadUserByOAuthUserResponse(UserResponseInterface $response) | |
{ | |
$username = $response->getUsername(); | |
// $user = $this->loadUserByUsername($username); | |
$user = $this->userManager->findUserBy(array($this->getProperty($response) => $username)); | |
if (null === $user || null === $username) { | |
$service = $response->getResourceOwner()->getName(); | |
$setter = 'set'.ucfirst($service); | |
$setterId = $setter.'Id'; | |
$userDataServiceName = lcfirst($service).'Provider'; | |
$user = $this->userManager->createUser(); | |
$user->$setterId($username); | |
// I use different setters setters for each type of oath providers: | |
// for example setVkontakteUser(...), setFacebookUser(...) | |
// the actual name of setter is in the variable $setterUser. | |
$user = $this->$userDataServiceName->setUserData($user, $response); | |
$user->setUsername(uniqid()); | |
//$user->setEmail($username); | |
$user->setPassword($username); | |
$user->setEnabled(true); | |
if ($hasUser = $this->userManager->findUserByEmail($user->getEmail())) { | |
$user->setEmail($username."@example.com"); | |
} | |
return $user; | |
} | |
$user = parent::loadUserByOAuthUserResponse($response); | |
if (!$user->isAccountNonLocked()) { | |
$this->session->getFlashBag()->add( | |
'locked', | |
'user.locked' | |
); | |
throw new LockedException(); | |
} | |
return $user; | |
} | |
/** | |
* @param Session $session | |
*/ | |
public function setSession(Session $session) | |
{ | |
$this->session = $session; | |
} | |
public function setFacebookProvider(FacebookProvider $facebookProvider) | |
{ | |
$this->facebookProvider = $facebookProvider; | |
} | |
public function setVkontakteProvider(VkontakteProvider $vkontakteProvider) | |
{ | |
$this->vkontakteProvider = $vkontakteProvider; | |
} | |
protected function updateEmails(User $user, User $previousUser) | |
{ | |
if ($user->isFakeEmail() && !$previousUser->isFakeEmail()) { | |
$realEmail = $previousUser->getEmail(); | |
$previousUser->setEmail(uniqid() . $previousUser::FAKE_EMAIL_PART); | |
$previousUser->setEmailCanonical($previousUser->getEmail()); | |
$this->userManager->updateUser($previousUser); | |
$user->setEmail($realEmail); | |
$user->setEmailCanonical($realEmail); | |
} | |
} | |
protected function updateOtherSocialIds(User $user, User $previousUser) | |
{ | |
$propertyAccessor = new PropertyAccessor(); | |
$socialIds = $previousUser->getNotNullSocialIds(); | |
foreach ($socialIds as $socialKey => $socialId) { | |
$socialKey = $socialKey . 'Id'; | |
$propertyAccessor->setValue($previousUser, $socialKey, null); | |
} | |
$this->userManager->updateUser($previousUser); | |
foreach ($socialIds as $socialKey => $socialId) { | |
$socialKey = $socialKey . 'Id'; | |
$currentSocialId = $propertyAccessor->getValue($user, $socialKey); | |
if ($currentSocialId) { | |
throw new \Exception(sprintf('You already have registred by "%s" social network, and account "%s %s" can\t be merged'), $socialKey, $previousUser->getFirstName(), $previousUser->getLastName()); | |
} | |
$propertyAccessor->setValue($user, $socialKey, $socialId); | |
} | |
$this->userManager->updateUser($user); | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment