<?php
namespace Harmonizely\Core\Security\Voter;
use Harmonizely\Core\Exception\AccessDeniedException;
use Harmonizely\Core\Security\Contract\ICsrfTokenValidator;
use Harmonizely\Core\Security\Contract\ISecurityHelper;
use Harmonizely\Core\Security\Contract\ISuperAdminSecurityHelper;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\Security\Core\Authentication\Token\TokenInterface;
use Symfony\Component\Security\Core\Authorization\Voter\VoterInterface;
class CsrfTokenVoter implements VoterInterface
{
/**
* @var ICsrfTokenValidator
*/
private ICsrfTokenValidator $csrfTokenValidator;
/**
* @var ISecurityHelper
*/
private ISecurityHelper $securityHelper;
/**
* CsrfTokenVoter constructor.
*
* @param ICsrfTokenValidator $csrfTokenValidator
* @param ISecurityHelper $securityHelper
*/
public function __construct(ICsrfTokenValidator $csrfTokenValidator, ISecurityHelper $securityHelper)
{
$this->csrfTokenValidator = $csrfTokenValidator;
$this->securityHelper = $securityHelper;
}
/**
* Returns the vote for the given parameters.
*
* This method must return one of the following constants:
* ACCESS_GRANTED, ACCESS_DENIED, or ACCESS_ABSTAIN.
*
* @param TokenInterface $token
* @param mixed $subject The subject to secure
* @param array $attributes An array of attributes associated with the method being invoked
*
* @return int either ACCESS_GRANTED, ACCESS_ABSTAIN, or ACCESS_DENIED
* @throws AccessDeniedException
*/
public function vote(TokenInterface $token, $subject, array $attributes): int
{
if ($subject instanceof Request) {
if (in_array(ISecurityHelper::IS_CSRF_REQUIRED, $attributes) || in_array(ISuperAdminSecurityHelper::IS_SUPER_ADMIN_CSRF_REQUIRED, $attributes)) {
if (!in_array($this->securityHelper->getLoginType(), [ISecurityHelper::LOGIN_TYPE_LINK, ISecurityHelper::LOGIN_TYPE_API_TOKEN, ISecurityHelper::LOGIN_TYPE_REMEMBER_ME])) {
$this->csrfTokenValidator->validate();
}
}
}
return self::ACCESS_ABSTAIN;
}
}