<?php
namespace App\EventSubscriber;
use App\Domain\Exception\Restrict\RestrictException;
use App\Services\Clients\ClientSystemState\ClientSystemStateService;
use App\Services\Auth\TokenClientUserService;
use App\Entity\OA2User;
use Symfony\Component\DependencyInjection\ContainerInterface;
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
use Symfony\Component\HttpKernel\Event\FilterControllerEvent;
use Symfony\Component\Security\Core\Authentication\Token\Storage\TokenStorageInterface;
class AuthSubscriber implements EventSubscriberInterface
{
/**
* @var TokenClientUserService
*/
private $tokenService;
/**
* @var ClientSystemStateService
*/
private $systemStateService;
/**
* @var ContainerInterface
*/
private $container;
private $allowedForPasswordExpired = [
'loginBankUser', // /bank/login
'updateBankUserByOwner', // /bank/updateUser
'bankUserProfile', // /bank/getProfile
];
public function __construct(
TokenClientUserService $tokenService,
ClientSystemStateService $systemStateService,
ContainerInterface $container
) {
$this->tokenService = $tokenService;
$this->systemStateService = $systemStateService;
$this->container = $container;
}
public function onKernelController(FilterControllerEvent $event)
{
$controller = $event->getController();
/*
* $controller passed can be either a class or a Closure.
* This is not usual in Symfony but it may happen.
* If it is a class, it comes in array format
*/
if (!is_array($controller)) {
return;
}
$route = $event->getRequest()->attributes->get('_route');
/** @var TokenStorageInterface $tokenStorage */
$tokenStorage = $this->container->get('security.token_storage');
$token = $tokenStorage->getToken();
if ($token === null) {
return;
}
/** @var OA2User $user */
$user = $token->getUser();
if (!$user instanceof OA2User || !$user->isBankUser()) {
return;
}
// If bank user was authorized by permanent token we don't need to check expiration password
if ($user->getBankUser()->permanentTokenIsActive($event->getRequest()->headers->get('BANK-AUTH-TOKEN'))) {
return;
}
if ($user->isPasswordExpired() && !in_array($route, $this->allowedForPasswordExpired)) {
throw new RestrictException('Password is expired');
}
}
public static function getSubscribedEvents()
{
return [
'kernel.controller' => 'onKernelController',
];
}
}