src/Voter/AccessVoter.php line 13

Open in your IDE?
  1. <?php
  2. namespace App\Voter;
  3. use App\Exception\AppException;
  4. use Psr\Log\LoggerInterface;
  5. use Symfony\Component\HttpFoundation\Request;
  6. use Symfony\Component\Security\Core\Authentication\Token\TokenInterface;
  7. use Symfony\Component\Security\Core\Authorization\Voter\Voter;
  8. use Symfony\Contracts\HttpClient\HttpClientInterface;
  9. class AccessVoter extends Voter
  10. {
  11.     public const UPLOAD 'upload';
  12.     public const STREAM 'stream';
  13.     public const INTERVIEW 'interview';
  14.     public const INTERVIEW_LIST 'interview-list';
  15.     private const ATTRIBUTES = [
  16.         self::UPLOAD,
  17.         self::STREAM,
  18.         self::INTERVIEW,
  19.         self::INTERVIEW_LIST,
  20.     ];
  21.     private HttpClientInterface $client;
  22.     private LoggerInterface $logger;
  23.     public function __construct(HttpClientInterface $clientLoggerInterface $logger)
  24.     {
  25.         $this->client $client;
  26.         $this->logger $logger;
  27.     }
  28.     protected function supports(string $attribute$subject): bool
  29.     {
  30.         return $subject instanceof Request && in_array($attributeself::ATTRIBUTES);
  31.     }
  32.     protected function voteOnAttribute(string $attribute$subjectTokenInterface $token): bool
  33.     {
  34.         switch ($attribute) {
  35.             case self::UPLOAD:
  36.                 return $this->isUploadAllowed($subject);
  37.             case self::STREAM:
  38.                 return $this->isStreamAllowed($subject);
  39.             case self::INTERVIEW:
  40.                 return $this->isInterviewAllowed($subject);
  41.             case self::INTERVIEW_LIST:
  42.                 return $this->isInterviewListAllowed($subject);
  43.         }
  44.         throw new AppException('Invalid attribute: '.$attribute);
  45.     }
  46.     private function isUploadAllowed(Request $request): bool
  47.     {
  48.         if ((null === $request->headers->get('apptoken')) || !$this->isValidApplication($request->headers->get('apptoken'))) {
  49.             throw new AppException('Access restricted.'403);
  50.         }
  51.         return true;
  52.     }
  53.     private function isStreamAllowed(Request $request): bool
  54.     {
  55.         $content json_decode($request->getContent(), true);
  56.         if ($content['appKey'] !== $_ENV['APP_KEY']) {
  57.             return false;
  58.         }
  59.         if (!isset($content['custom']['appToken']) || !$this->isValidApplication($content['custom']['appToken'])) {
  60.             return false;
  61.         }
  62.         return true;
  63.     }
  64.     private function isValidApplication($appToken): bool
  65.     {
  66.         /** dev environment token check */
  67.         if ($appToken === 'T-49d2016b-e492-4851-b9b4-d103244a2fdd') {
  68.             return true;
  69.         }
  70.         $response $this->client->request(
  71.             'GET',
  72.             $_ENV['API_URL'] . '/api/v1/_self',
  73.             [
  74.                 'headers' => [
  75.                     'SpxAuth' => 'Bearer ' $appToken,
  76.                 ]
  77.             ]
  78.         );
  79.         if ($response->getStatusCode() < 300) {
  80.             return true;
  81.         }
  82.         $response $this->client->request(
  83.             'GET',
  84.             $_ENV['API_URL'] . '/api/v1/video_questions/allow_recording/' $appToken
  85.         );
  86.         if ($response->getStatusCode() < 300) {
  87.             return true;
  88.         }
  89.         $response $this->client->request(
  90.             'GET',
  91.             $_ENV['API_URL'] . '/api/v1/video_questions/allow_update_universal_job/' $appToken
  92.         );
  93.         return $response->getStatusCode() < 300;
  94.     }
  95.     private function isInterviewAllowed(Request $request)
  96.     {
  97.         $content json_decode($request->getContent(), true);
  98.         $this->logger->info(json_encode($content));
  99.         $customerToken $content['custom']['token'];
  100.         $response $this->client->request(
  101.             'GET',
  102.             $_ENV['API_URL'] . '/api/v1/_self',
  103.             [
  104.                 'headers' => [
  105.                     'SpxAuth' => 'Bearer ' $customerToken,
  106.                 ]
  107.             ]
  108.         );
  109.         return $response->getStatusCode() < 300;
  110.     }
  111.     private function isInterviewListAllowed(Request $request)
  112.     {
  113.         $appToken $request->headers->get('Apptoken');
  114.         if (empty($appToken)) {
  115.             $appToken $request->headers->get('SpxAuth');
  116.             if (empty($appToken)) {
  117.                 throw new AppException('Missing authorization'403);
  118.             }
  119.             $appToken str_replace('Bearer '''$appToken);
  120.         }
  121.         $response $this->client->request(
  122.             'GET',
  123.             $_ENV['API_URL'] . '/api/v1/_self',
  124.             [
  125.                 'headers' => [
  126.                     'SpxAuth' => 'Bearer ' $appToken,
  127.                 ]
  128.             ]
  129.         );
  130.         return $response->getStatusCode() < 300;
  131.     }
  132. }