<?php
namespace Roothirsch\CoreBundle\EventSubscriber;
use ApiPlatform\Core\EventListener\EventPriorities;
use Roothirsch\CoreBundle\Entity\User;
use Roothirsch\CoreBundle\Messaging\MessagingService;
use Roothirsch\CoreBundle\Security\UserManager;
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
use Symfony\Component\HttpKernel\KernelEvents;
use Symfony\Component\Security\Core\Authentication\Token\Storage\TokenStorageInterface;
final class UserWriteSubscriber implements EventSubscriberInterface
{
/**
* @var UserManager
*/
private $userManager;
/**
* @var TokenStorageInterface
*/
private $tokenStorage;
/**
* @var MessagingService
*/
private $messagingService;
public function __construct(
UserManager $userManager,
TokenStorageInterface $tokenStorage,
MessagingService $messagingService
) {
$this->userManager = $userManager;
$this->tokenStorage = $tokenStorage;
$this->messagingService = $messagingService;
}
public static function getSubscribedEvents()
{
return [
KernelEvents::VIEW => ['validate', EventPriorities::POST_VALIDATE],
];
}
public function validate(\Symfony\Component\HttpKernel\Event\ViewEvent $event)
{
if ($event->getRequest()->attributes->get('_route') === 'api_users_register_item') {
$this->register($event);
}
if ($event->getRequest()->attributes->get('_api_item_operation_name') === 'reset-password') {
$this->resetPassword($event);
}
if ($event->getRequest()->attributes->get('_api_item_operation_name') === 'change-password') {
$this->changePassword($event);
}
if (
$event->getRequest()->attributes->get('_api_resource_class') == User::class
&& (
$event->getRequest()->attributes->get('_api_item_operation_name') === 'put'
|| $event->getRequest()->attributes->get('_api_collection_operation_name') === 'post'
)
) {
if (in_array('ROLE_ADMIN', $this->tokenStorage->getToken()->getUser()->getRoles())) {
/** @var User $user */
$user = $event->getControllerResult();
if ($user instanceof User) {
$this->userManager->encodePassword($user, $event->getRequest()->get('plaintextPassword'));
}
}
}
}
/**
* @param \Roothirsch\CoreBundle\EventSubscriber\Api\GetResponseForControllerResultEvent $event
*
* @return User
*/
private function register(\Symfony\Component\HttpKernel\Event\ViewEvent $event)
{
/** @var User $user */
$user = $event->getControllerResult();
if ($event->getRequest()->attributes->has('token')) {
$user->setRegistrationToken(null);
$user->setActive(true);
$this->messagingService->sendRegistrationNotification($user, $event->getRequest()->getLocale());
$this->userManager->encodePassword($user, $event->getRequest()->get('plaintextPassword'));
}
}
/**
* @param \Roothirsch\CoreBundle\EventSubscriber\Api\GetResponseForControllerResultEvent $event
*
* @return User
*/
private function resetPassword(\Symfony\Component\HttpKernel\Event\ViewEvent $event)
{
/** @var User $user */
$user = $event->getControllerResult();
$this->userManager->sendPasswordResetEmail($user->getEmail(), $event->getRequest()->attributes->get('locale'));
}
/**
* @param \Roothirsch\CoreBundle\EventSubscriber\Api\GetResponseForControllerResultEvent $event
*/
private function changePassword(\Symfony\Component\HttpKernel\Event\ViewEvent $event)
{
/** @var User $user */
$user = $event->getControllerResult();
if (empty($event->getRequest()->get('token'))
&& (
empty($event->getRequest()->get('currentPassword'))
|| $this->userManager->isPasswordValid($user, $event->getRequest()->get('currentPassword')) !== true
)) {
throw new \Exception('wrong password');
}
$user->setSecurityToken(null);
$this->userManager->encodePassword($user, $event->getRequest()->get('plaintextPassword'));
}
}