<?php
declare(strict_types=1);
namespace App\Security\Voters;
use App\Entity\Client;
use App\Entity\OA2User;
use App\Repository\ClientRepository;
use App\Repository\Permissions\AccountPermissionSettingRepository;
use App\Repository\Permissions\ClientAccountPermissionRepository;
use App\Security\Dto\AccountListDto;
use Symfony\Component\Security\Core\Authentication\Token\TokenInterface;
use Symfony\Component\Security\Core\Authorization\Voter\Voter;
class AccountListVoter extends Voter
{
public const MODE_UPDATE = 'update';
public const MODE_READ = 'read';
private $accPermSettingRepository;
private $clientAccPermRepository;
private $clientRepository;
public function __construct(
AccountPermissionSettingRepository $accPermSettingRepository,
ClientAccountPermissionRepository $clientAccPermRepository,
ClientRepository $clientRepository
) {
$this->accPermSettingRepository = $accPermSettingRepository;
$this->clientAccPermRepository = $clientAccPermRepository;
$this->clientRepository = $clientRepository;
}
/**
* @param string $attribute
* @param mixed $subject
*
* @return bool
*/
protected function supports($attribute, $subject)
{
if (!in_array($attribute, $this->getSupportedPermissions())) {
return false;
}
return !(!$subject instanceof AccountListDto)
;
}
/**
* @param string $attribute
* @param mixed $subject
*
* @return bool
*/
protected function voteOnAttribute($attribute, $subject, TokenInterface $token)
{
/** @var AccountListDto $accountListDto */
$accountListDto = $subject;
$currentClient = $this->getCurrentClient($token);
if (!$currentClient) {
return false;
}
/** @var int[] $verificationAccountIds */
$verificationAccountIds = $accountListDto->getAccountIds();
$permissionId = $this->accPermSettingRepository->getIdByHardvalue(AccountVoter::PERMISSION_VIEW_ACCOUNT);
return $this->clientAccPermRepository->verifyAccountsByPermission($verificationAccountIds, $currentClient, $permissionId);
}
private function getSupportedPermissions(): array
{
return [
AccountVoter::MODE_UPDATE,
AccountVoter::MODE_READ,
];
}
private function getCurrentClient(TokenInterface $token): ?Client
{
/** @var OA2User $oa2User */
$oa2User = $token->getUser();
if (!$oa2User instanceof OA2User || $oa2User->isBankUser()) {
return null; // Client user only
}
return $this->clientRepository->findOneByOa2User($oa2User);
}
}