<?php/** * Created by PhpStorm. * User: matijajanc * Date: 22/05/2018 * Time: 15:18 */namespace App\Adapter\Api\EventListener;use App\Adapter\Api\Annotations\ApiAuthorization;use App\Adapter\Api\Exception\ApiException;use App\Adapter\Api\Service\Validators\ApiValidator;use Doctrine\Common\Annotations\Reader;use Doctrine\Common\Util\ClassUtils;use Nelmio\ApiDocBundle\Controller\SwaggerUiController;use ReflectionClass;use ReflectionObject;use Symfony\Bundle\FrameworkBundle\Controller\Controller;use Symfony\Component\HttpFoundation\Response;use Symfony\Component\HttpKernel\Event\FilterControllerEvent;class ApiAuthorizationListener{ /** * @var Reader */ private $reader; /** * @var ApiValidator */ private $validator; /** * ApiAuthorizationListener constructor. * @param Reader $reader * @param ApiValidator $validator */ public function __construct(Reader $reader, ApiValidator $validator) { $this->reader = $reader; $this->validator = $validator; } /** * @param FilterControllerEvent $event * @throws ApiException * @throws \ReflectionException */ public function onKernelController(FilterControllerEvent $event) { $controller = $event->getController(); $request = $event->getRequest(); if (!$controller instanceof SwaggerUiController) { /** @var Controller $controllerObject */ list($controllerObject, $methodName) = $controller; if ($controllerObject instanceof Controller && $this->hasApiAuthorizationAnnotation($controllerObject, $methodName) ) { if (!$this->validator->validateUserAgent($request)) { throw new ApiException(['ERR-301', 'User agent is required'], Response::HTTP_UNAUTHORIZED); } } } } /** * @param Controller $controllerObject * @param $methodName * @return bool * @throws \ReflectionException */ private function hasApiAuthorizationAnnotation(Controller $controllerObject, $methodName) { $tokenAnnotation = ApiAuthorization::class; $hasAnnotation = false; $classAnnotation = $this->reader->getClassAnnotation( new ReflectionClass(ClassUtils::getClass($controllerObject)), $tokenAnnotation ); if ($classAnnotation) { $hasAnnotation = true; } $controllerReflectionObject = new ReflectionObject($controllerObject); $reflectionMethod = $controllerReflectionObject->getMethod($methodName); $methodAnnotation = $this->reader->getMethodAnnotation($reflectionMethod, $tokenAnnotation); if ($methodAnnotation) { $hasAnnotation = true; } return $hasAnnotation; }}