<?php
namespace App\Controller\OAuth;
use GuzzleHttp\Utils;
use App\Service\CartService;
use App\OAuth\OAuth2 as OAuth2;
use App\Entity\OAuth\AccessToken;
use App\Repository\CartRepository;
use League\OAuth2\Server\CryptKey;
use App\OAuth\GoogleGrantExtension;
use App\Repository\PersonRepository;
use App\OAuth\FacebookGrantExtension;
use Doctrine\Persistence\ManagerRegistry;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
use App\Repository\OAuth\AccessTokenRepository;
use Menke\UserBundle\Repository\UserRepository;
use Symfony\Component\Routing\Annotation\Route;
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use League\OAuth2\Server\AuthorizationValidators\BearerTokenValidator;
use League\Bundle\OAuth2ServerBundle\Controller\TokenController as BaseTokenController;
use League\Bundle\OAuth2ServerBundle\Manager\AccessTokenManagerInterface;
class TokenController extends AbstractController
{
private $baseTokenController;
private $manager;
private $accessTokenManagerInterface;
private $accessTokenRepository;
private $cartRepo;
private $personRepo;
private $cartService;
private $userRepo;
private $bearerTokenValidator;
public function __construct(
BaseTokenController $baseTokenController,
ManagerRegistry $manager,
AccessTokenManagerInterface $accessTokenManagerInterface,
AccessTokenRepository $accessTokenRepository,
CartRepository $cartRepo,
PersonRepository $personRepo,
CartService $cartService,
UserRepository $userRepo,
BearerTokenValidator $bearerTokenValidator
) {
$this->baseTokenController = $baseTokenController;
$this->manager = $manager->getManager();
$this->accessTokenManagerInterface = $accessTokenManagerInterface;
$this->accessTokenRepository = $accessTokenRepository;
$this->cartRepo = $cartRepo;
$this->personRepo = $personRepo;
$this->cartService = $cartService;
$this->userRepo = $userRepo;
$this->bearerTokenValidator = $bearerTokenValidator;
}
/**
* @Route("/oauth/v2/token", name="oauth_v2_token", methods="POST")
*/
public function indexAction(Request $request): Response
{
$result = $this->baseTokenController->indexAction($request);
if ($request->getMethod() === 'POST') {
$inputData = $request->request->all();
if (
($inputData['grant_type'] == OAuth2::GRANT_TYPE_USER_CREDENTIALS ||
$inputData['grant_type'] == FacebookGrantExtension::GRANT_TYPE ||
$inputData['grant_type'] == GoogleGrantExtension::GRANT_TYPE) &&
$result->getStatusCode() == 200 &&
array_key_exists('access_token', $inputData) &&
!empty($inputData['access_token'])
) {
$this->bearerTokenValidator->setPublicKey(new CryptKey($this->getParameter('kernel.project_dir')."/config/jwt/public.key"));
$old_token = $this->bearerTokenValidator->getJwtConfiguration()->parser()->parse($inputData['access_token']);
$oldAccessToken = $this->accessTokenRepository->findOneBy(['identifier' => $old_token->claims()->get('jti')]);
if (!$oldAccessToken) {
return $result;
}
$resultObj = json_decode($result->getContent());
$new_token = $this->bearerTokenValidator->getJwtConfiguration()->parser()->parse($resultObj->access_token);
$accessTokenManager = $this->accessTokenManagerInterface->find($new_token->claims()->get('jti'));
$user = $this->userRepo->findOneBy(['username' => $inputData['username']]);
if (!$accessTokenManager && !$user) {
return $result;
}
$newAccessToken = new AccessToken();
$newAccessToken->setIdentifier($accessTokenManager->getIdentifier());
$newAccessToken->setClient($accessTokenManager->getClient());
$newAccessToken->setExpiry(new \DateTime());
$newAccessToken->setUser($user);
$newAccessToken->setUserIdentifier($user->getUsername());
$this->manager->persist($newAccessToken);
$this->manager->flush();
$cart = $this->cartRepo->findOneBy(['accessToken' => $oldAccessToken]);
if (!$cart) {
return $result;
}
$customer = $this->personRepo->findOneBy(['user' => $newAccessToken->getUser()]);
$customerCart = $this->cartRepo->findOneBy(['customer' => $customer]);
if (!$customerCart) {
$cart->setCustomer($customer);
$cart->setAccessToken(null);
} else {
foreach ($cart->getItems() as $item) {
$customerItem = $this->cartService->getCartItemIfExists($item->getCourseOccurrence(), $customerCart, $item->getCourseItem() ? true : false);
if ($customerItem) {
$customerItem->increaseQuantity($item->getQuantity());
if ($item->getCourseItem()) {
$item->setCourseItem(null);
}
foreach ($item->getParticipants() as $participant) {
$item->removeParticipant($participant);
$customerItem->addParticipant($participant);
}
$cart->removeItem($item);
} else {
$cart->removeItem($item);
$customerCart->addItem($item);
}
}
$this->manager->remove($cart);
}
$this->manager->flush();
}
}
if ($result->getStatusCode() == 400) {
$content = json_decode($result->getContent());
if ($content->error == OAuth2::ERROR_INVALID_GRANT) {
$inputData = $request->request->all();
if (array_key_exists('username', $inputData)) {
try {
$user = $this->userRepo->findOneBy(['username' => $inputData['username']]);
if ($user && !$user->isEnabled()) {
$content->error_description = 'Der angegebene Benutzer ist nicht aktiviert.';
$result->setContent(Utils::jsonEncode($content));
}
} catch (\Exception $e) {
}
}
}
}
return $result;
}
}