<?php
/**
* Created by PhpStorm.
* User: MEDINA
* Date: 29/03/2019
* Time: 04:37 PM
*/
namespace App\EventSubscriber\User;
use App\Entity\App\VendorStaff;
use App\Services\UtilsService;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\Security\Core\Authentication\Token\Storage\TokenStorageInterface;
use Symfony\Component\Security\Core\Authorization\AuthorizationCheckerInterface;
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
use Symfony\Component\HttpKernel\Event\ViewEvent;
use Symfony\Component\HttpKernel\KernelEvents;
use Doctrine\ORM\EntityManagerInterface;
use ApiPlatform\Core\EventListener\EventPriorities;
use App\Repository\App\VendorRepository;
use App\Repository\App\UserRepository;
use App\Services\VendorService;
use App\Entity\App\Vendor;
use App\Entity\App\User;
use App\Entity\App\Role;
use Symfony\Contracts\Translation\TranslatorInterface;
class UserPreSerializerSubscriber implements EventSubscriberInterface
{
private $tokenStorage;
private $authorizationChecker;
private $entityManager;
private $userRepository;
private $vendorRepository;
private $vendorService;
private $utilsService;
private $translator;
public function __construct(
TokenStorageInterface $tokenStorage,
AuthorizationCheckerInterface $checker,
UserRepository $userRepository,
VendorRepository $vendorRepository,
VendorService $vendorService,
EntityManagerInterface $entityManager,
UtilsService $utilsService,
TranslatorInterface $translator)
{
$this->tokenStorage = $tokenStorage;
$this->authorizationChecker = $checker;
$this->entityManager = $entityManager;
$this->userRepository = $userRepository;
$this->vendorRepository = $vendorRepository;
$this->vendorService = $vendorService;
$this->utilsService = $utilsService;
$this->translator = $translator;
}
/**
* @param ViewEvent $event
* @throws \Exception
*/
public function onKernelView(ViewEvent $event)
{
if ($this->utilsService->isAPublicRequest($event)) {
return;
}
$request = $event->getRequest();
$user = $event->getControllerResult();
$route = $request->attributes->get('_route');
$routesItem = array(
'api_users_post_collection',
'api_users_get_item',
'api_users_put_item'
);
$routesCollection = array(
'api_users_get_collection',
'api_users_get_taskmasters_collection',
'api_users_get_operators_collection'
);
$ownRoutes = array(
'api_users_get_item',
'api_users_put_item'
);
$routesTask = array(
'api_users_get_taskmasters_collection',
'api_users_get_operators_collection'
);
if (!in_array($route, array_merge($routesItem, $routesCollection)))
return;
$vendor = null;
$vendorId = $request->query->get('vendorStaff_vendor');
$data = json_decode($request->getContent(), true);
if (isset($data['vendor']) &&
('api_users_post_collection' == $route || 'api_users_put_item' == $route)
)
$vendorId = $data['vendor'];
if ($vendorId) {
$vendor = $this->vendorRepository->find($vendorId);
if (!($vendor instanceof Vendor))
throw new \Exception('vendor not found');
}
if ($this->authorizationChecker->isGranted('ROLE_SUPERADMIN'))
return;
$locale = $request->getLocale();
if ($this->tokenStorage->getToken()) {
$userCurrent = $this->tokenStorage->getToken()->getUser();
if ($userCurrent instanceof User) {
$locale = $userCurrent->getLocale();
}
}
$authorization = false;
$userCurrent = $this->tokenStorage->getToken()->getUser();
if (is_null($vendor)) {
switch (true) {
case (in_array($route, $routesCollection)):
$authorization = true;
break;
case (in_array($route, $ownRoutes)):
if ($user->getId() == $userCurrent->getId()) {
$authorization = true;
}
break;
default:
$authorization = false;
}
}
$controlAccess = [Role::ROLE_ADMIN];
if ($vendor instanceof Vendor && $userCurrent instanceof User) {
if(in_array($route, $routesTask)) {
$controlAccess = [Role::ROLE_ADMIN, Role::ROLE_TASKMASTER];
}
if ($this->vendorService->isUserRoleInToVendor($vendor, $userCurrent, $controlAccess))
$authorization = true;
if (in_array($route, $ownRoutes) &&
$user->getId() == $userCurrent->getId()) {
$authorization = true;
}
}
if (!$authorization && is_null($vendor) && $userCurrent instanceof User && in_array($route, $ownRoutes)) {
$vendorUserCurrent = $this->vendorService->getVendorsOfUserByRole($userCurrent, Role::ROLE_ADMIN);
foreach ($user->getVendorStaff() as $userVendorStaff) {
if ($userVendorStaff instanceof VendorStaff && in_array($userVendorStaff->getVendor(), $vendorUserCurrent)) {
$authorization = true;
break;
}
}
}
if (!$authorization) {
$controlAccessTranslator = [];
foreach ($controlAccess as $roleName) {
$controlAccessTranslator[] = $this->translator->trans($roleName, [], null, $locale);
}
$response = new Response();
$response->setContent(
json_encode(
[
'detail' => $this->translator->trans('access_allowed_only_for', [], null, $locale) . (implode(
', ',
$controlAccessTranslator
))
]
)
);
$response->setStatusCode(Response::HTTP_NOT_ACCEPTABLE);
$event->setResponse($response);
return;
}
}
public static function getSubscribedEvents()
{
return [
KernelEvents::VIEW => ['onKernelView', EventPriorities::PRE_SERIALIZE]
];
}
}