src/Security/SocialAuthenticator.php line 43

Open in your IDE?
  1. <?php
  2. namespace App\Security;
  3. use App\Entity\User;
  4. use Doctrine\ORM\EntityManagerInterface;
  5. use KnpU\OAuth2ClientBundle\Client\ClientRegistry;
  6. use KnpU\OAuth2ClientBundle\Security\Authenticator\OAuth2Authenticator;
  7. use Symfony\Component\HttpFoundation\RedirectResponse;
  8. use Symfony\Component\HttpFoundation\Request;
  9. use Symfony\Component\HttpFoundation\Response;
  10. use Symfony\Component\PasswordHasher\Hasher\UserPasswordHasherInterface;
  11. use Symfony\Component\Routing\RouterInterface;
  12. use Symfony\Component\Security\Core\Authentication\Token\TokenInterface;
  13. use Symfony\Component\Security\Core\Exception\AuthenticationException;
  14. use Symfony\Component\Security\Http\Authenticator\Passport\Badge\UserBadge;
  15. use Symfony\Component\Security\Http\Authenticator\Passport\Passport;
  16. use Symfony\Component\Security\Http\Authenticator\Passport\SelfValidatingPassport;
  17. use Symfony\Component\Security\Http\EntryPoint\AuthenticationEntryPointInterface;
  18. class SocialAuthenticator extends OAuth2Authenticator implements AuthenticationEntrypointInterface
  19. {
  20.     private $clientRegistry;
  21.     private $entityManager;
  22.     private $router;
  23.     private $passwordEncoder;
  24.     public function __construct(ClientRegistry $clientRegistryEntityManagerInterface $entityManagerRouterInterface $routerUserPasswordHasherInterface $passwordEncoder)
  25.     {
  26.         $this->clientRegistry $clientRegistry;
  27.         $this->entityManager $entityManager;
  28.         $this->router $router;
  29.         $this->passwordEncoder $passwordEncoder;
  30.     }
  31.     public function supports(Request $request): ?bool
  32.     {
  33.         // continue ONLY if the current ROUTE matches the check ROUTE
  34.         return $request->attributes->get('_route') === 'connect_facebook_check' 
  35.         || $request->attributes->get('_route') === 'connect_google_check';
  36.     }
  37.     public function authenticate(Request $request): Passport
  38.     {
  39.         if ($request->attributes->get('_route') === 'connect_facebook_check') {
  40.             $client $this->clientRegistry->getClient('facebook_main');
  41.         } elseif ($request->attributes->get('_route') === 'connect_google_check') {
  42.             $client $this->clientRegistry->getClient('google_main');
  43.         }
  44.         $accessToken $this->fetchAccessToken($client);
  45.         return new SelfValidatingPassport(
  46.             new UserBadge($accessToken->getToken(), function() use ($accessToken$client) {
  47.                 
  48.                 /** @var FacebookUser $facebookUser */
  49.                 $facebookUser $client->fetchUserFromToken($accessToken);
  50.                 $email $facebookUser->getEmail();
  51.                 $firstName $facebookUser->getFirstName();
  52.                 $lastName $facebookUser->getLastName();
  53.                 $social_id $facebookUser->getId();
  54.                 $role 'ROLE_PARENT';
  55.                 // Generate random bytes
  56.                 $randomBytes random_bytes(10);
  57.                 // Convert random bytes to a password using base64 encoding
  58.                 $password base64_encode($randomBytes);
  59.                 // Optionally, you can remove characters that are not suitable for a password
  60.                 $password strtr($password'+/''-_');
  61.                 // 1) have they logged in with Facebook before? Easy!
  62. /*                 $existingUser = $this->entityManager->getRepository(User::class)->findOneBy(['facebookId' => $facebookUser->getId()]);
  63.                 if ($existingUser) {
  64.                     return $existingUser;
  65.                 }
  66.  */
  67.                 // 2) do we have a matching user by email?
  68.                 $user $this->entityManager->getRepository(User::class)->findOneBy(['username' => $email]);
  69.                 
  70.                 if ($user) {
  71.                     return $user;
  72.                 }
  73.                 // 3) Maybe you just want to "register" them by creating
  74.                 // a User object
  75.                 $user = new User();
  76.                 $user->setNom($lastName);
  77.                 $user->setPrenom($firstName);
  78.                 $user->setUsername($email);
  79.                 $user->setMailnotif(1);
  80.                 $user->setShowpubprod(true);
  81.                 //$user->setNummobile('');
  82.                 $user->setEmail(trim($email));
  83.                 $user->setDateCreation(new \DateTime());
  84.                 $user->addRole($role);
  85.                 $user->setPassword(
  86.                     $this->passwordEncoder->hashPassword(
  87.                         $user,
  88.                         $password
  89.                     )
  90.                 );
  91.                 $this->entityManager->persist($user);
  92.                 $this->entityManager->flush();
  93.                 return $user;
  94.             })
  95.         );
  96.     }
  97.     public function onAuthenticationSuccess(Request $requestTokenInterface $tokenstring $firewallName): ?Response
  98.     {
  99.         // change "app_homepage" to some route in your app
  100.         $targetUrl $this->router->generate('CodeSejour');
  101.         return new RedirectResponse($targetUrl);
  102.     
  103.         // or, on success, let the request continue to be handled by the controller
  104.         //return null;
  105.     }
  106.     public function onAuthenticationFailure(Request $requestAuthenticationException $exception): ?Response
  107.     {
  108.         $message strtr($exception->getMessageKey(), $exception->getMessageData());
  109.         return new Response($messageResponse::HTTP_FORBIDDEN);
  110.     }
  111.     
  112.    /**
  113.      * Called when authentication is needed, but it's not sent.
  114.      * This redirects to the 'login'.
  115.      */
  116.     public function start(Request $requestAuthenticationException $authException null): Response
  117.     {
  118.         return new RedirectResponse(
  119.             '/connect/'// might be the site, where users choose their oauth provider
  120.             Response::HTTP_TEMPORARY_REDIRECT
  121.         );
  122.     }
  123. }