<?php
namespace App\Security;
use App\Manager\TokenManager;
use App\Model\User\User;
use App\Service\APIKiwi;
use JMS\Serializer\DeserializationContext;
use JMS\Serializer\SerializerInterface;
use KnpU\OAuth2ClientBundle\Client\ClientRegistry;
use KnpU\OAuth2ClientBundle\Client\Provider\FacebookClient;
use KnpU\OAuth2ClientBundle\Security\Authenticator\SocialAuthenticator;
use League\OAuth2\Client\Provider\FacebookUser;
use Symfony\Component\HttpFoundation\RedirectResponse;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\RequestStack;
use Symfony\Component\Routing\Generator\UrlGeneratorInterface;
use Symfony\Component\Routing\RouterInterface;
use Symfony\Component\Security\Core\Authentication\Token\TokenInterface;
use Symfony\Component\Security\Core\Exception\AuthenticationException;
use Symfony\Component\Security\Core\Security;
use Symfony\Component\Security\Core\User\UserProviderInterface;
use Symfony\Component\Security\Http\Util\TargetPathTrait;
/**
* Class FacebookAuthenticator
* @package App\Security
*/
class FacebookAuthenticator extends SocialAuthenticator
{
use TargetPathTrait;
/**
* @var UrlGeneratorInterface $urlGenerator
*/
private UrlGeneratorInterface $urlGenerator;
/**
* @var APIKiwi $APIKiwi
*/
private APIKiwi $APIKiwi;
/**
* @var RouterInterface $router
*/
private RouterInterface $router;
/**
* @var ClientRegistry $clientRegistry
*/
private ClientRegistry $clientRegistry;
/**
* @var RequestStack $requestStack
*/
private RequestStack $requestStack;
/**
* @var SerializerInterface $serializer
*/
private SerializerInterface $serializer;
/**
* @var TokenManager
*/
private TokenManager $tokenManager;
/**
* FacebookAuthenticator constructor.
* @param RouterInterface $router
* @param ClientRegistry $clientRegistry
* @param APIKiwi $APIKiwi
* @param RequestStack $requestStack
* @param SerializerInterface $serializer
* @param TokenManager $tokenManager
*/
public function __construct(RouterInterface $router, ClientRegistry $clientRegistry, APIKiwi $APIKiwi,
RequestStack $requestStack, SerializerInterface $serializer,
UrlGeneratorInterface $urlGenerator, TokenManager $tokenManager)
{
$this->router = $router;
$this->clientRegistry = $clientRegistry;
$this->APIKiwi = $APIKiwi;
$this->requestStack = $requestStack;
$this->serializer = $serializer;
$this->urlGenerator = $urlGenerator;
$this->tokenManager = $tokenManager;
}
/**
* @inheritDoc
*/
public function start(Request $request, AuthenticationException $authException = null)
{
return new RedirectResponse($this->router->generate('app_login'));
}
/**
* @inheritDoc
*/
public function supports(Request $request): bool
{
return 'oauth_check_facebook' === $request->attributes->get('_route') && $request->get('service') === 'facebook';
}
/**
* @inheritDoc
*/
public function getCredentials(Request $request)
{
return $this->fetchAccessToken($this->getClient());
}
/**
* @inheritDoc
* @throws \Exception
*/
public function getUser($credentials, UserProviderInterface $userProvider): ?User
{
/** @var FacebookUser $facebookUser */
$facebookUser = $this->getClient()
->fetchUserFromToken($credentials);
$email = str_replace('%40', '@', $facebookUser->getEmail());
try{
$response = $this->APIKiwi->postPublicKiwi(['path' =>'/public/users/facebook_check', 'data' =>['email' => $email]]);
$apiToken = $this->tokenManager->decodeContent($response)['token'];
$content = $this->tokenManager->decodeIgnoreExpired($apiToken);
}catch (\Exception $exception)
{
$this->requestStack->getSession()->set('kiwi_facebook_user', $this->serializer->serialize($facebookUser, 'json'));
return null;
}
$response = $this->APIKiwi->getKiwi(['path' => '/users/'.$content['user_uuid'], 'token' => $apiToken]);
$user = $this->serializer->deserialize(
$response->getContent(),
User::class,
'json',
DeserializationContext::create()->setGroups(['get_user'])
);
$user->setToken($apiToken);
//if empty there is a problem
if( !$user->getId() || !$user->getEmail() ) {
return null;
}
return $user;
}
/**
* @inheritDoc
*/
public function onAuthenticationFailure(Request $request, AuthenticationException $exception): RedirectResponse
{
if ($request->hasSession()) {
$request->getSession()->set(Security::AUTHENTICATION_ERROR, $exception);
}
return new RedirectResponse($this->router->generate('kiwi_register_user'));
}
/**
* @inheritDoc
*/
public function onAuthenticationSuccess(Request $request, TokenInterface $token, $providerKey): ?RedirectResponse
{
return new RedirectResponse($this->urlGenerator->generate('kiwi_homepage'));
}
/**
* @return FacebookClient
*/
private function getClient (): FacebookClient {
return $this->clientRegistry->getClient('facebook');
}
}