<?php
declare(strict_types=1);
namespace App\Security\Voter;
use Symfony\Component\Security\Core\Authentication\Token\TokenInterface;
use Symfony\Component\Security\Core\Authorization\AccessDecisionManagerInterface;
use Symfony\Component\Security\Core\Authorization\AuthorizationCheckerInterface;
use Symfony\Component\Security\Core\Authorization\Voter\Voter;
final class KYCVoter extends Voter
{
// Backward compatibility roles. Should be removed in the future and replaced with proper security checking.
private const ALLOWED_ROLES = ['ROLE_KYC', 'ROLE_TRANSFERS', 'ROLE_SUPPORT', 'ROLE_SUPPORT_MANAGER', 'ROLE_TRANSFERS_MANAGER', 'ROLE_TRANSACTION_MANAGER', 'ROLE_CARD_OPS', 'ROLE_DISPUTE'];
public function __construct(
private AccessDecisionManagerInterface $accessDecisionManager,
private AuthorizationCheckerInterface $authorizationChecker,
) {}
protected function supports(string $attribute, $subject): bool
{
return in_array($attribute, ['KYC_VIEW', 'KYC_EDIT', 'KYC_REGIX'], true);
}
protected function voteOnAttribute(string $attribute, $subject, TokenInterface $token): bool
{
$user = $token->getUser();
if (!$user) {
return false;
}
$isKycManager = $this->accessDecisionManager->decide($token, ['ROLE_KYC_MANAGER']);
if ($isKycManager) {
return true;
}
if ($attribute === 'KYC_VIEW') {
foreach (self::ALLOWED_ROLES as $role) {
if ($this->authorizationChecker->isGranted($role)) {
return true;
}
}
return false;
}
// TODO: Extend for the rest of KYC related permissions
return false;
}
}