<?php
namespace Roothirsch\CoreBundle\EventSubscriber;
use ApiPlatform\Core\EventListener\EventPriorities;
use ApiPlatform\Core\Exception\ItemNotFoundException;
use Roothirsch\CoreBundle\Entity\User;
use Roothirsch\CoreBundle\Security\UserManager;
use Roothirsch\CoreBundle\Repository\UserRepository;
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
use Symfony\Component\HttpKernel\KernelEvents;
use Symfony\Component\Security\Core\Authentication\Token\Storage\TokenStorageInterface;
final class UserReadSubscriber implements EventSubscriberInterface
{
/**
* @var UserRepository
*/
private $userRepository;
/**
* @var UserManager
*/
private $userManager;
/**
* @var TokenStorageInterface
*/
private $tokenStorage;
public function __construct(
UserRepository $userRepository,
UserManager $userManager,
TokenStorageInterface $tokenStorage
) {
$this->userRepository = $userRepository;
$this->userManager = $userManager;
$this->tokenStorage = $tokenStorage;
}
public static function getSubscribedEvents()
{
return [
KernelEvents::REQUEST => ['load', EventPriorities::PRE_READ],
];
}
public function load(\Symfony\Component\HttpKernel\Event\RequestEvent $event)
{
if (strpos($event->getRequest()->getPathInfo(), '/api/users') !== 0) {
return;
}
if ($event->getRequest()->attributes->get('_api_item_operation_name') === 'reset-password') {
$this->loadUserFromEmail($event);
}
if ($event->getRequest()->get('id') === 'current'
|| $event->getRequest()->get('id') === 'me'
|| $event->getRequest()->attributes->get('_route') === 'api_users_current_item') {
$this->loadUserFromSession($event);
} elseif (strlen($event->getRequest()->get('id')) > 10) {
$this->loadUserFromToken($event);
}
}
/**
* @param \Roothirsch\CoreBundle\EventSubscriber\Api\GetResponseEvent $event
*/
private function loadUserFromEmail(\Symfony\Component\HttpKernel\Event\RequestEvent $event)
{
$payload = json_decode($event->getRequest()->getContent(), true);
$user = $this->userRepository->findOneBy(
[
'email' => $payload['email'],
]
);
$event->getRequest()->attributes->set('locale', $payload['language']);
if (!$user instanceof User) {
throw new ItemNotFoundException('Not found');
}
$event->getRequest()->attributes->set('id', $user->getId());
}
/**
* @param \Roothirsch\CoreBundle\EventSubscriber\Api\GetResponseEvent $event
*/
private function loadUserFromSession(\Symfony\Component\HttpKernel\Event\RequestEvent $event)
{
$user = $this->tokenStorage->getToken()->getUser();
if (!$user instanceof User) {
return;
}
$event->getRequest()->attributes->set('id', $user->getId());
}
/**
* @param \Roothirsch\CoreBundle\EventSubscriber\Api\GetResponseEvent $event
*/
private function loadUserFromToken(\Symfony\Component\HttpKernel\Event\RequestEvent $event)
{
$user = $this->userRepository->findOneBy(
[
'registrationToken' => $event->getRequest()->get('id'),
'active' => false,
]
);
if (!$user instanceof User) {
$user = $this->userRepository->findOneBy(
[
'securityToken' => $event->getRequest()->get('id'),
'active' => true,
]
);
}
if (!$user instanceof User) {
throw new ItemNotFoundException('Not found');
}
if ($user->getUpdated() < (time() - 60 * 60 * 24)) {
$user->setRegistrationToken('');
$this->userManager->persist($user);
throw new ItemNotFoundException('token invalid');
}
if (!$user instanceof User) {
return;
}
$event->getRequest()->attributes->set('token', $event->getRequest()->get('id'));
$event->getRequest()->attributes->set('id', $user->getId());
}
}