<?php
namespace Nen\Bundle\QuestionnaireBundle\Security\Voter;
use App\Entity\Respondent;
use App\Entity\User;
use Nen\Bundle\KennisbankPlatformBundle\Service\PlatformUserRolesProvider;
use Symfony\Component\Security\Core\Authentication\Token\TokenInterface;
use Symfony\Component\Security\Core\Authentication\Token\UsernamePasswordToken;
use Symfony\Component\Security\Core\Authorization\Voter\RoleHierarchyVoter;
use Symfony\Component\Security\Core\Authorization\Voter\Voter;
use Symfony\Component\Security\Core\Security;
class RespondentVoter extends Voter
{
private Security $security;
private RoleHierarchyVoter $roleVoter;
public function __construct(Security $security, RoleHierarchyVoter $roleVoter)
{
$this->security = $security;
$this->roleVoter = $roleVoter;
}
protected function supports(string $attribute, $subject): bool
{
return $subject instanceof Respondent;
}
protected function voteOnAttribute(string $attribute, $subject, TokenInterface $token): bool
{
/** @var Respondent $respondent */
$respondent = $subject;
$user = $token->getUser();
if (!$user instanceof User) {
return false;
}
switch ($attribute) {
case 'update':
return $this->update($respondent, $user);
case 'remove':
return $this->remove($respondent);
}
return false;
}
private function getRespondentToken(Respondent $respondent): TokenInterface
{
return new UsernamePasswordToken($respondent->getUser(), null, 'main', $respondent->getUser()->getRoles());
}
private function remove(Respondent $respondent): bool
{
// You cannot remove respondents that are connected to questionnaires.
if ($respondent->getQuestionnaires()->count() > 0) {
return false;
}
// You cannot remove respondents that are also license users.
$result = $this->roleVoter->vote($this->getRespondentToken($respondent), null, [PlatformUserRolesProvider::ROLE_LICENSE_USER]);
if ($result >= 1) {
return false;
}
// Users with the customer service role can remove respondents.
if ($this->security->isGranted(PlatformUserRolesProvider::ROLE_CUSTOMER_SERVICE)) {
return true;
}
// User needs to be a license manager.
if (!$this->security->isGranted(PlatformUserRolesProvider::ROLE_LICENSE_MANAGER)) {
return false;
}
return true;
}
private function update(Respondent $respondent, User $user): bool
{
// Users with the customer service role can update respondents.
if ($this->security->isGranted(PlatformUserRolesProvider::ROLE_CUSTOMER_SERVICE)) {
return true;
}
// User needs to be a license manager.
if (!$this->security->isGranted(PlatformUserRolesProvider::ROLE_LICENSE_MANAGER)) {
return false;
}
// Return true when the user is from the same company as the respondent.
return $respondent->getUser()->getCompany()->getId() === $user->getCompany()->getId();
}
}