src/Handler/AccessTokenHandler.php line 96

Open in your IDE?
  1. <?php
  2. namespace App\Handler;
  3. use App\Entity\User;
  4. use App\Util\EsUtil;
  5. use App\Service\EsCache;
  6. use App\Entity\AccessToken;
  7. use Doctrine\ORM\EntityManagerInterface;
  8. use Symfony\Component\Security\Core\Security;
  9. use Lexik\Bundle\JWTAuthenticationBundle\Services\JWTTokenManagerInterface;
  10. class AccessTokenHandler
  11. {
  12.     public function __construct(
  13.         private EntityManagerInterface $_em,
  14.         private EsCache $esCache,
  15.         private Security $security,
  16.         private JWTTokenManagerInterface $jwtManager
  17.     ) {
  18.     }
  19.     public function create($token$user null$container null$prevRefreshToken null)
  20.     {
  21.         if (!$user) {
  22.             $user $this->security->getUser();
  23.         }
  24.         if (!$user) {
  25.             $payload EsUtil::decodeJWTPayloadOnly($token);
  26.             $user $this->_em->getRepository(User::class)
  27.                 ->findOneBy([
  28.                     'email' => $payload['username'],
  29.                     'client' => $payload['cid']
  30.                 ]);
  31.         }
  32.         if (!$user && $prevRefreshToken) {
  33.             $accessToken $this->_em->getRepository(AccessToken::class)
  34.                 ->findOneBy([
  35.                     'refreshToken' => $prevRefreshToken,
  36.                     'isActive' => true
  37.                 ]);
  38.             if ($accessToken) {
  39.                 $user $accessToken->getUser();
  40.             }
  41.         }
  42.         if (!$user) {
  43.             throw new \Exception('User not found !');
  44.         }
  45.         if (!$container) {
  46.             $container $this->esCache->getContainer();
  47.         }
  48.         $authTokenTimeout $container->getConfiguration('authTokenTimeout'720);
  49.         if (empty($authTokenTimeout)) {
  50.             $authTokenTimeout 720;
  51.         }
  52.         $expireAt = new \DateTime();
  53.         $expireAt->add(new \DateInterval('PT'.$authTokenTimeout.'M'));
  54.         $expireAt->setTimezone(new \DateTimeZone('UTC'));
  55.         $authRefreshTokenTimeout $container->getConfiguration('authRefreshTokenTimeout'43200);
  56.         if (empty($authRefreshTokenTimeout)) {
  57.             $authRefreshTokenTimeout 43200;
  58.         }
  59.         $rtExpireAt = new \DateTime();
  60.         $rtExpireAt->add(new \DateInterval('PT'.$authRefreshTokenTimeout.'M'));
  61.         $rtExpireAt->setTimezone(new \DateTimeZone('UTC'));
  62.         /*
  63.         $accessToken = new AccessToken();
  64.         $accessToken
  65.             ->setToken($token)
  66.             ->setExpireAt($expireAt)
  67.             ->setRefreshToken(self::getRefreshToken($token))
  68.             ->setRtExpireAt($rtExpireAt)
  69.             ->setIsActive(true)
  70.             ->setUser($user)
  71.             //->setContainer($container)
  72.         ;
  73.         $this->_em->persist($accessToken);
  74.         $this->_em->flush();
  75.         */
  76.         $now = new \DateTime();
  77.         $now->setTimezone(new \DateTimeZone('UTC'));
  78.         $query "INSERT INTO access_token(`token`, `refresh_token`, `container_id`, `user_id`, `is_active`, `created_at`, `expire_at`, `rt_expire_at`) VALUES ('".$token."', '".self::getRefreshToken($token)."', '".$container->getId()."', '".$user->getId()."', 1, '".$now->format('Y-m-d H:i:s')."', '".$expireAt->format('Y-m-d H:i:s')."', '".$rtExpireAt->format('Y-m-d H:i:s')."')";
  79.         $statement $this->_em->getConnection()->prepare($query);
  80.         $statement->execute();
  81.     }
  82.     public function makeInactive($token$user null$container null)
  83.     {
  84.     }
  85.     public function isValid($token$container null)
  86.     {
  87.         if (!$container) {
  88.             $container $this->esCache->getContainer();
  89.         }
  90.         $accessToken $this->_em->getRepository(AccessToken::class)
  91.             ->findOneBy([
  92.                 'token' => $token,
  93.                 'container' => $container,
  94.                 'isActive' => true
  95.             ]);
  96.         if ($accessToken && $accessToken->getExpireAt() > new \DateTime()) {
  97.             return true;
  98.         }
  99.         return false;
  100.     }
  101.     public function getNewToken($refreshToken$container null)
  102.     {
  103.         if (!$container) {
  104.             $container $this->esCache->getContainer();
  105.         }
  106.         $accessToken $this->_em->getRepository(AccessToken::class)
  107.             ->findOneBy([
  108.                 'refreshToken' => $refreshToken,
  109.                 'container' => $container,
  110.                 'isActive' => true
  111.             ]);
  112.         if ($accessToken && $accessToken->getRtExpireAt() > new \DateTime()) {
  113.             $token $this->jwtManager->create($accessToken->getUser());
  114.             $newAccessToken $this->_em->getRepository(AccessToken::class)
  115.                 ->findOneBy([
  116.                     'token' => $token,
  117.                     'container' => $container,
  118.                     'isActive' => true,
  119.                     'user' => $accessToken->getUser()
  120.                 ]);
  121.             if (!$newAccessToken) {
  122.                 throw new \Exception('Can not generate new token !');
  123.             }
  124.             return [
  125.                 'token' => $newAccessToken->getToken(),
  126.                 'refresh_token' => $newAccessToken->getRefreshToken()
  127.             ];
  128.         }
  129.         return false;
  130.     }
  131.     public function logoutUser($token$user null$container null)
  132.     {
  133.         if (!$user) {
  134.             $user $this->security->getUser();
  135.         }
  136.         if (!$container) {
  137.             $container $this->esCache->getContainer();
  138.         }
  139.         $accessToken $this->_em->getRepository(AccessToken::class)
  140.             ->findOneBy([
  141.                 'token' => $token,
  142.                 'user' => $user,
  143.                 'container' => $container,
  144.                 'isActive' => true
  145.             ]);
  146.         if ($accessToken) {
  147.             $accessToken->setIsActive(false);
  148.             $this->_em->persist($accessToken);
  149.             $this->_em->flush();
  150.             return true;
  151.         }
  152.         return false;
  153.     }
  154.     public static function getRefreshToken($token)
  155.     {
  156.         $pk \file_get_contents(__DIR__.'/../../config/jwt/public.pem');
  157.         return sha1($token.$pk);
  158.     }
  159. }