<?php
declare(strict_types=1);
namespace App\Security\Voters;
use App\Services\Clients\ClientSystemState\ClientSystemStateService;
use App\Entity\Client;
use App\Entity\Cluster;
use App\Entity\CompanyPerson;
use App\Entity\OA2User;
use App\Repository\ClientRepository;
use App\Repository\CompanyPersonRepository;
use Symfony\Component\Security\Core\Authentication\Token\TokenInterface;
use Symfony\Component\Security\Core\Authorization\Voter\Voter;
class ClusterVoter extends Voter
{
public const MODE_READ = 'read';
public const CAN_MAKE_CLUSTERS = 'can_make_clusters';
private $clientRepository;
private $clientSystemStateService;
private $companyPersonRepository;
public function __construct(
ClientRepository $clientRepository,
ClientSystemStateService $clientSystemStateService,
CompanyPersonRepository $companyPersonRepository
) {
$this->clientRepository = $clientRepository;
$this->clientSystemStateService = $clientSystemStateService;
$this->companyPersonRepository = $companyPersonRepository;
}
/**
* @param string $attribute
* @param mixed $subject
*
* @return bool
*/
protected function supports($attribute, $subject)
{
return !(!$subject instanceof Cluster)
;
}
protected function voteOnAttribute($attribute, $subject, TokenInterface $token)
{
if (!in_array($attribute, $this->getSupportedPermissions())) {
return false;
}
/** @var Cluster $cluster */
$cluster = $subject;
/** @var Client|null $currentClient */
$currentClient = $this->getCurrentClient($token);
if ($currentClient === null) {
return false;
}
if ($attribute === self::MODE_READ) {
return $this->canRead($currentClient, $cluster);
}
if ($attribute === self::CAN_MAKE_CLUSTERS) {
return $this->canMakeClusters($currentClient, $cluster);
}
return false;
}
private function getSupportedPermissions(): array
{
return [
self::MODE_READ,
self::CAN_MAKE_CLUSTERS,
];
}
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);
}
public function canRead(Client $currentClient, Cluster $cluster): bool
{
/** @var CompanyPerson $relationCompany */
$relationCompany = $this->companyPersonRepository->findOneByOwnerClient($currentClient, $cluster->getClient());
return (bool) $relationCompany;
}
public function canMakeClusters(Client $currentClient, Cluster $cluster): bool
{
/** @var CompanyPerson $relationCompany */
$relationCompany = $this->companyPersonRepository->findOneByOwnerClient($currentClient, $cluster->getClient());
return $relationCompany ? $relationCompany->getCanMakeClusters() : false;
}
}