<?php
namespace App\Security\Voter;
use App\Entity\Project;
use App\Entity\ProjectPhase;
use App\Entity\ProjectPhaseDocument;
use App\Entity\ProjectStageDeploy;
use App\Entity\User;
use Symfony\Component\Security\Core\Authentication\Token\TokenInterface;
use Symfony\Component\Security\Core\Authorization\Voter\Voter;
use Symfony\Component\Security\Core\Security;
class ProjectVoter extends Voter
{
public const ACCESS_PROJECT = 'ACCESS_PROJECT';
public const PROJECT_OWNER_OR_SUPERADMIN = 'PROJECT_OWNER_OR_SUPERADMIN';
private Security $security;
public function __construct(Security $security)
{
$this->security = $security;
}
protected function supports(string $attribute, $subject): bool
{
return in_array($attribute, [self::ACCESS_PROJECT, self::PROJECT_OWNER_OR_SUPERADMIN]) && ($subject instanceof Project || $subject instanceof ProjectStageDeploy || $subject === null);
}
/**
* @param Project $subject
*/
protected function voteOnAttribute(string $attribute, $subject, TokenInterface $token): bool
{
/** @var User $user */
$user = $token->getUser();
// if the user is anonymous, do not grant access
if (!$user instanceof User) {
return false;
}
$project = null;
if ($subject instanceof Project) {
$project = $subject;
}
if ($subject instanceof ProjectStageDeploy) {
$project = $subject->getProjectStage()->getProject();
}
switch ($attribute) {
case self::ACCESS_PROJECT:
if ($this->security->isGranted(User::ROLE_SUPER_ADMIN)) {
return true;
}
if ($project) {
if ($this->isOwner($user, $project)) {
return true;
}
if ($user->getProjects()->contains($project)) {
return true;
}
}
break;
case self::PROJECT_OWNER_OR_SUPERADMIN:
if ($this->security->isGranted(User::ROLE_SUPER_ADMIN)) {
return true;
}
if ($project) {
if ($this->isOwner($user, $project)) {
return true;
}
}
break;
}
return false;
}
private function isOwner(User $user, ?Project $project): bool
{
if ($project && (int) $project->getCreatedBy()->getId() === $user->getId()) {
return true;
}
return false;
}
}