<?php
namespace App\Security;
use Symfony\Component\Security\Core\Authentication\Token\TokenInterface;
use Symfony\Component\Security\Core\Authorization\Voter\Voter;
use Symfony\Component\Security\Core\Security;
use Doctrine\ORM\EntityManagerInterface;
use App\Entity\Project;
use App\Entity\User;
use App\Util\SecurityUtil;
/**
*
* @author wendell.zheng <wxzheng@ustc.edu.cn>
*/
class ProjectVoter extends Voter
{
const APPLICANT_VIEW = 'applicant_view';
const APPLICANT_EDIT = 'applicant_edit';
const APPLICANT_DELETE = 'applicant_delete';
const COLLEGE_VIEW = 'college_view';
const COLLEGE_ACTION = 'college_action';
const COLLEGE_SORT = 'college_sort';
protected $security;
protected $em;
public function __construct(Security $security, EntityManagerInterface $em)
{
$this->security = $security;
$this->em = $em;
}
protected function supports($attribute, $subject): bool
{
if (! in_array($attribute, [
self::APPLICANT_VIEW,
self::APPLICANT_EDIT,
self::APPLICANT_DELETE,
self::COLLEGE_VIEW,
self::COLLEGE_ACTION,
self::COLLEGE_SORT
])) {
return false;
}
if (! $subject instanceof Project) {
return false;
}
return true;
}
protected function voteOnAttribute($attribute, $subject, TokenInterface $token): bool
{
$user = $token->getUser();
if (! $user instanceof User) {
return false;
}
if ($user->getUserIdentifier() == 'P0336') {
return true;
}
/** @var Project $project */
$project = $subject;
switch ($attribute) {
case self::APPLICANT_VIEW:
return $this->canApplicantView($project, $user);
case self::APPLICANT_EDIT:
return $this->canApplicantEdit($project, $user);
case self::APPLICANT_DELETE:
return $this->canApplicantDelete($project, $user);
case self::COLLEGE_VIEW:
return $this->canCollegeView($project, $user);
case self::COLLEGE_ACTION:
return $this->canCollegeAction($project, $user);
case self::COLLEGE_SORT:
return $this->canCollegeSort($project, $user);
}
throw new \LogicException('This code should not be reached!');
}
protected function canApplicantView(Project $project, User $user): bool
{
return $user == $project->getUser();
}
protected function canApplicantEdit(Project $project, User $user): bool
{
if (! $this->canApplicantView($project, $user)) {
return false;
}
if (! $this->security->isGranted(BatchVoter::APPLICANT_ACTION, $project->getBatch())) {
return false;
}
return in_array($project->getStatus(), [
Project::STATUS_NEW,
Project::STATUS_SCHOOL_RECOMMEND
]);
}
protected function canApplicantDelete(Project $project, User $user): bool
{
if (! $this->canApplicantView($project, $user)) {
return false;
}
if (! $this->security->isGranted(BatchVoter::APPLICANT_ACTION, $project->getBatch())) {
return false;
}
return $project->isNew();
}
protected function canCollegeView(Project $project, User $user): bool
{
return $this->security->isGranted('ROLE_ADMIN') && $user->getAdminCollege() == $project->getCollege();
}
protected function canCollegeAction(Project $project, User $user): bool
{
$batch = $project->getBatch();
if (! $this->security->isGranted(BatchVoter::COLLEGE_ACTION, $batch)) {
return false;
}
if (! $this->canCollegeView($project, $user)) {
return false;
}
return in_array($project->getStatus(), [
Project::STATUS_NEW,
Project::STATUS_COLLEGE_RECOMMEND
]);
}
protected function canCollegeSort(Project $project, User $user): bool
{
if (! $this->canCollegeAction($project, $user)) {
return false;
}
return $project->getStatus() == Project::STATUS_COLLEGE_RECOMMEND;
}
}