<?php
declare(strict_types=1);
namespace App\Access\Security\Voter;
use App\Security\Doctrine\Entity\User;
use App\Security\Security\Store\Roles;
use Symfony\Component\Security\Core\Authentication\Token\TokenInterface;
use Symfony\Component\Security\Core\Authorization\AccessDecisionManagerInterface;
use Symfony\Component\Security\Core\Authorization\Voter\Voter;
final class AccessVoter extends Voter
{
public const DELETE = 'delete';
public const SUSPEND = 'suspend';
public const ACTIVATE = 'activate';
public function __construct(private AccessDecisionManagerInterface $accessDecisionManager)
{
}
protected function supports(string $attribute, mixed $subject): bool
{
if (!$subject instanceof User) {
return false;
}
return in_array($attribute, [self::DELETE, self::SUSPEND, self::ACTIVATE], true);
}
protected function voteOnAttribute(string $attribute, mixed $subject, TokenInterface $token): bool
{
if (!$subject instanceof User) {
return false;
}
return match ($attribute) {
self::DELETE => $token->getUser() !== $subject
&& $this->accessDecisionManager->decide($token, [Roles::ACCESS_DELETE], $subject),
self::SUSPEND => $token->getUser() !== $subject
&& !$subject->isSuspended()
&& $this->accessDecisionManager->decide($token, [Roles::ACCESS_SUSPEND], $subject),
self::ACTIVATE => $token->getUser() !== $subject
&& $subject->isSuspended()
&& $this->accessDecisionManager->decide($token, [Roles::ACCESS_ACTIVATE], $subject),
default => false // @codeCoverageIgnore
};
}
}