<?php
declare(strict_types=1);
namespace App\Security\Voter\Procedure;
use App\ReadModel\Contract\DetailView;
use App\Security\UserIdentity;
use Symfony\Component\Security\Core\Authentication\Token\TokenInterface;
use Symfony\Component\Security\Core\Authorization\Voter\Voter;
use Symfony\Component\Security\Core\Exception\AccessDeniedException;
use Symfony\Component\Security\Core\Security;
class ContractVoter extends Voter
{
public const CONTRACT_SHOW = 'contract_show';
/** @var Security */
private Security $security;
/**
* @param Security $security
*/
public function __construct(Security $security)
{
$this->security = $security;
}
protected function supports(string $attribute, $subject): bool
{
return in_array($attribute, [
self::CONTRACT_SHOW,
]) && $subject instanceof DetailView;
}
/**
* @param string $attribute
* @param DetailView $subject
* @param TokenInterface $token
* @return bool
*/
protected function voteOnAttribute(string $attribute, $subject, TokenInterface $token): bool
{
// Moderators have full access
if ($this->security->isGranted('ROLE_MODERATOR')) {
return true;
}
$user = $token->getUser();
if (!$user instanceof UserIdentity) {
return false;
}
/*** Список разрешенных профиль ид*/
$accessProfileIds = [];
$accessProfileIds[] = $subject->getOrganizerProfileId();
$accessProfileIds[] = $subject->getParticipantProfileId();
if (in_array($user->getProfileId(), $accessProfileIds) === false) {
throw new AccessDeniedException('Доступ запрещен. У вас недостаточно прав для совершения этого действия.');
}
switch ($attribute) {
case self::CONTRACT_SHOW:
//is owner contract
if ($subject->getParticipantProfileId() === $user->getProfileId()) {
if ($subject->getStatus()->isNew()) {
throw new AccessDeniedException('Доступ запрещен. У вас недостаточно прав для совершения этого действия.');
}
}
break;
}
return true;
}
}