From 29ad156ce11d9306365b6cc4de4c346910c4e577 Mon Sep 17 00:00:00 2001 From: Johannes Wachter Date: Wed, 4 Jul 2018 13:59:51 +0200 Subject: [PATCH] added social-media user-provider --- Entity/UserAccessToken.php | 71 +++++++++ Entity/UserAccessTokenRepository.php | 30 ++++ .../config/doctrine/UserAccessToken.orm.xml | 30 ++++ Resources/config/services.xml | 5 + SocialMedia/SocialMediaUserProvider.php | 140 ++++++++++++++++++ composer.json | 4 +- 6 files changed, 279 insertions(+), 1 deletion(-) create mode 100644 Entity/UserAccessToken.php create mode 100644 Entity/UserAccessTokenRepository.php create mode 100644 Resources/config/doctrine/UserAccessToken.orm.xml create mode 100644 SocialMedia/SocialMediaUserProvider.php diff --git a/Entity/UserAccessToken.php b/Entity/UserAccessToken.php new file mode 100644 index 00000000..7e7a1cbc --- /dev/null +++ b/Entity/UserAccessToken.php @@ -0,0 +1,71 @@ +user = $user; + $this->service = $service; + $this->identifier = $identifier; + } + + public function getUser(): UserInterface + { + return $this->user; + } + + public function getService(): string + { + return $this->service; + } + + public function getIdentifier(): string + { + return $this->identifier; + } + + public function getAccessToken(): string + { + return $this->accessToken; + } + + public function setAccessToken(string $accessToken): self + { + $this->accessToken = $accessToken; + + return $this; + } +} diff --git a/Entity/UserAccessTokenRepository.php b/Entity/UserAccessTokenRepository.php new file mode 100644 index 00000000..6608ce75 --- /dev/null +++ b/Entity/UserAccessTokenRepository.php @@ -0,0 +1,30 @@ +getClassName(); + + return new $class($user, $service, $identifier); + } + + public function findByIdentifier(string $service, string $identifier): ?UserAccessToken + { + return $this->findOneBy(['service' => $service, 'identifier' => $identifier]); + } +} diff --git a/Resources/config/doctrine/UserAccessToken.orm.xml b/Resources/config/doctrine/UserAccessToken.orm.xml new file mode 100644 index 00000000..bead643c --- /dev/null +++ b/Resources/config/doctrine/UserAccessToken.orm.xml @@ -0,0 +1,30 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Resources/config/services.xml b/Resources/config/services.xml index 57d58f0e..01807c5a 100644 --- a/Resources/config/services.xml +++ b/Resources/config/services.xml @@ -140,5 +140,10 @@ + + + + + diff --git a/SocialMedia/SocialMediaUserProvider.php b/SocialMedia/SocialMediaUserProvider.php new file mode 100644 index 00000000..1d6b0f82 --- /dev/null +++ b/SocialMedia/SocialMediaUserProvider.php @@ -0,0 +1,140 @@ +userAccessTokenRepository = $this->em->getRepository(UserAccessToken::class); + $this->userRepository = $this->em->getRepository($this->em->getClassMetadata(SuluUserInterface::class)->getName()); + $this->contactRepository = $this->em->getRepository($this->em->getClassMetadata(ContactInterface::class)->getName()); + } + + public function connect(UserInterface $user, UserResponseInterface $response) + { + // On connect, retrieve the access token and the user id + $service = $response->getResourceOwner()->getName(); + $username = $response->getUsername(); + + // Disconnect previously connected users + $previousAccessToken = $this->userAccessTokenRepository->findByIdentifier($service, $username); + if ($previousAccessToken) { + $this->em->remove($previousAccessToken); + + // FIXME necessary? + $this->em->flush(); + } + + $accessToken = $this->userAccessTokenRepository->create($user, $service, $username); + $accessToken->setAccessToken($response->getAccessToken()); + + // FIXME necessary? + $this->em->flush(); + } + + public function loadUserByOAuthUserResponse(UserResponseInterface $response) + { + $service = $response->getResourceOwner()->getName(); + $username = $response->getUsername(); + $email = $response->getEmail() ? $response->getEmail() : $username; + + $accessToken = $this->userAccessTokenRepository->findByIdentifier($service, $username); + + // If the user exists + if ($accessToken) { + // set access-token and return + $accessToken->setAccessToken($response->getAccessToken()); + + $user = $accessToken->getUser(); + $user->setEmail($email); + + $contact = $user->getContact(); + $contact->setFirstName($response->getFirstName()); + $contact->setLastName($response->getLastName()); + + // FIXME necessary? + $this->em->flush(); + + return $accessToken->getUser(); + } + + // else create new user + $user = $this->userRepository->createNew(); + + $accessToken = $this->userAccessTokenRepository->create($user, $service, $username); + $accessToken->setAccessToken($response->getAccessToken()); + + $contact = $this->contactRepository->createNew(); + $contact->setFirstName($response->getFirstName()); + $contact->setLastName($response->getLastName()); + $user->setContact($contact); + + $user->setUsername($this->generateRandomUsername($username, $service)); + $user->setEmail($email); + $user->setSalt(uniqid()); + $user->setPassword($username); + $user->setEnabled(true); + $user->setLocale('de'); // FIXME locale + + $this->em->persist($contact); + $this->em->persist($user); + $this->em->persist($accessToken); + + // FIXME necessary? + $this->em->flush(); + + return $user; + } + + private function generateRandomUsername($username, $serviceName) + { + if (!$username) { + $username = 'user' . uniqid((rand()), true) . $serviceName; + } + + return $username . '_' . $serviceName; + } +} diff --git a/composer.json b/composer.json index 1797884c..700dcb18 100644 --- a/composer.json +++ b/composer.json @@ -23,7 +23,9 @@ "symfony/routing": "^3.4", "symfony/security": "^3.4", "symfony/security-acl": "^2.8 || ^3.0", - "symfony/swiftmailer-bundle": "^2.6.4" + "symfony/swiftmailer-bundle": "^2.6.4", + "hwi/oauth-bundle": "^0.6.2", + "php-http/httplug-bundle": "^1.10" }, "require-dev": { "jackalope/jackalope-doctrine-dbal": "^1.2.5",