<?php
namespace App\Security\Voter;
use App\Entity\Authorization;
use App\Entity\InterventionRequest;
use App\Entity\User;
use App\Manager\InterventionRequestManager;
use Symfony\Component\Security\Core\Authentication\Token\TokenInterface;
use Symfony\Component\Security\Core\Authorization\Voter\Voter;
use Symfony\Component\Security\Core\Security;
class InterventionRequestVoter extends Voter
{
public const CREATE = 'CAN_CREATE';
public const READ = 'CAN_READ';
public const EDIT = 'CAN_EDIT';
public const DELETE = 'CAN_DELETE';
private Security $security;
private InterventionRequestManager $interventionRequestManager;
public function __construct(Security $security, InterventionRequestManager $interventionRequestManager)
{
$this->security = $security;
$this->interventionRequestManager = $interventionRequestManager;
}
protected function supports($attribute, $subject): bool
{
$supportsAttribute = in_array($attribute, [self::CREATE, self::DELETE, self::EDIT, self::READ]);
$supportsSubject = $subject instanceof InterventionRequest;
return $supportsAttribute && $supportsSubject;
}
/**
* @param mixed $subject
*/
protected function voteOnAttribute(string $attribute, $subject, TokenInterface $token): bool
{
$user = $this->security->getUser();
if (!$user) {
return false;
}
switch ($attribute) {
case self::CREATE:
return $this->canCreate($subject, $user);
case self::READ:
return $this->canRead($subject, $user);
case self::EDIT:
return $this->canEdit($subject, $user);
case self::DELETE:
return $this->canDelete($subject, $user);
}
return false;
}
private function canCreate(InterventionRequest $interventionRequest, User $user): bool
{
if ($this->security->isGranted(Authorization::ROLE_ADMIN)
|| $this->security->isGranted(Authorization::ROLE_OWNER_REQUESTER)
) {
return true;
}
return false;
}
private function canRead(InterventionRequest $interventionRequest, User $user): bool
{
if ($this->security->isGranted(Authorization::ROLE_ADMIN)) {
return true;
}
if ($this->security->isGranted(Authorization::ROLE_OWNER_ADMIN)) {
if ($user->getCompany()->getId() === $interventionRequest->getOwnerCompany()->getId()) {
return true;
}
}
if ($this->security->isGranted(Authorization::ROLE_SERVICE_PROVIDER_ADMIN)) {
if ($user->getCompany()->getId() === $interventionRequest->getServiceProviderCompany()->getId()) {
return true;
}
}
return $this->interventionRequestManager->hasAccess($interventionRequest, $this->security->getUser());
}
private function canEdit(InterventionRequest $interventionRequest, User $user): bool
{
if (!$this->security->isGranted(Authorization::ROLE_OWNER)
&& !$this->security->isGranted(Authorization::ROLE_SERVICE_PROVIDER)) {
return false;
}
return $this->canRead($interventionRequest, $user);
}
private function canDelete(InterventionRequest $interventionRequest, User $user): bool
{
if ($this->security->isGranted(Authorization::ROLE_ADMIN)) {
return true;
}
return false;
}
}