<?php
/**
* Created by PhpStorm.
* User: MEDINA
* Date: 29/03/2019
* Time: 04:08 PM
*/
namespace App\EventSubscriber\User;
use App\Exception\AccessDeniedException;
use App\Exception\CaptchaTokenInvalidException;
use App\Exception\NotFoundException;
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 Symfony\Component\HttpFoundation\Request;
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\User;
use App\Entity\App\Role;
use App\Entity\App\Vendor;
use Symfony\Contracts\Translation\TranslatorInterface;
class UserPreValidateSubscriber 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,
TranslatorInterface $translator,
UtilsService $utilsService)
{
$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 AccessDeniedException
* @throws CaptchaTokenInvalidException
* @throws NotFoundException
*/
public function onKernelView(ViewEvent $event)
{
if ($this->utilsService->isAPublicRequest($event)) {
return;
}
$user = $event->getControllerResult();
$request = $event->getRequest();
$route = $request->attributes->get('_route');
$method = $event->getRequest()->getMethod();
if (!($user instanceof User) ||
(Request::METHOD_POST !== $method && Request::METHOD_PUT !== $method))
return;
$locale = $request->getLocale();
if ($this->tokenStorage->getToken()) {
$userCurrent = $this->tokenStorage->getToken()->getUser();
if ($userCurrent instanceof User) {
$locale = $userCurrent->getLocale();
}
}
$userCurrent = $this->tokenStorage->getToken()->getUser();
$content = $request->getContent();
$data = json_decode($content, true);
if (Request::METHOD_POST == $method && isset($data['captchaToken'])) {
if (!$this->utilsService->checkRecaptchaTokenIsValid($data['captchaToken'])) {
throw new CaptchaTokenInvalidException('Sent token is not valid');
}
}
$vendor = null;
if (isset($data['vendor'])) {
$vendor = $this->vendorRepository->find($data['vendor']);
if (!($vendor instanceof Vendor)) {
$response = new Response();
$response->setContent(json_encode([
'detail' => $this->translator->trans(
'entity not found',
[
'%entity%' => 'vendor',
'%entityId%' => $data['vendor']
],
null,
$locale
)
]));
$response->setStatusCode(Response::HTTP_BAD_REQUEST);
$event->setResponse($response);
return;
}
}
$authorization = false;
if ($this->authorizationChecker->isGranted('ROLE_SUPERADMIN'))
$authorization = true;
$controlAccess = [Role::ROLE_ADMIN];
if ($userCurrent instanceof User && $vendor instanceof Vendor) {
if ($this->vendorService->isUserRoleInToVendor($vendor, $userCurrent, $controlAccess)) {
$authorization = true;
}
} elseif (is_null($vendor) && $userCurrent instanceof User && Request::METHOD_PUT === $method) {
$vendorUserCurrent = $this->vendorService->getVendorsOfUserByRole($userCurrent, Role::ROLE_ADMIN);
foreach ($user->getVendorStaff() as $userVendorStaff) {
if (in_array($userVendorStaff->getVendor(), $vendorUserCurrent)) {
$authorization = true;
break;
}
}
}
if (!$authorization &&
Request::METHOD_PUT === $method &&
$userCurrent instanceof User &&
$user->getId() === $userCurrent->getId()
) {
$authorization = true;
}
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;
}
$phone = null;
if (!empty($user->getPhoneNumber())) {
$phone = str_replace([' ', '+', '-', '(', ')', '-'], '', $user->getPhoneNumber());
$user->setPhoneNumber($phone);
}
if (!empty($user->getPhonePrefix()) && empty($user->getPhoneNumber())) {
$response = new Response();
$response->setContent(
json_encode(
[
'detail' => $this->translator->trans(
'phoneNumber is required if phonePrefix is not blank',
[],
null,
$locale
)
]
)
);
$response->setStatusCode(Response::HTTP_NOT_ACCEPTABLE);
$event->setResponse($response);
return;
}
if (!empty($user->getPhonePrefix()) && !empty($user->getPhoneNumber())) {
$phone =
$user->setPhonePrefixAndPhone(sprintf("%s%s", $user->getPhonePrefix(), $phone));
}
if (empty($user->getPhonePrefix()) && empty($user->getPhoneNumber())) {
$user->setPhonePrefixAndPhone(null);
}
if (empty($user->getCostPerHour()) && is_null($user->getCostPerHour())) {
$user->setCostPerHour(0);
}
}
public static function getSubscribedEvents()
{
return [
KernelEvents::VIEW => ['onKernelView', EventPriorities::PRE_VALIDATE]
];
}
}