<?php
namespace Platform\SecurityBundle\Security\Voter;
use App\Entity\System\School;
use Platform\SecurityBundle\Entity\Identity\Account;
use Platform\SecurityBundle\Model\PlatformSubject;
use Platform\SecurityBundle\Security\PlatformVoter;
use Products\NotificationsBundle\Entity\AbstractList;
use Products\NotificationsBundle\Entity\Lists\ConditionList;
use Products\NotificationsBundle\Entity\Lists\DistrictList;
use Products\NotificationsBundle\Entity\Lists\SchoolList;
use Symfony\Component\Security\Core\Authorization\Voter\VoterInterface;
final class NotificationsVoter extends PlatformVoter
{
/**
* {@inheritDoc}
*/
protected function supports(
Account $account,
string $attribute,
?PlatformSubject $subject = null
): bool
{
// for this to be a notifications vote, the permission should be prefixed a certain way
if ( ! $this->sentry->isNotificationsPermission($attribute)) {
return false;
}
// if a context is given, it should be a school or a list
if ($subject && $subject->getContext() && ! ($subject->getContext() instanceof School || $subject->getContext() instanceof AbstractList)) {
return false;
}
return true;
}
/**
* {@inheritdoc}
*/
protected function poll(
Account $account,
string $permission,
?PlatformSubject $subject = null
): int
{
// if the context is a list, first try to obtain the school for it and check against that
$context = $subject ? $subject->getContext() : null;
$school = null;
switch (true) {
case ($context instanceof DistrictList || $context instanceof SchoolList) && $context->getOneRosterId():
$school = $this->rm->getSchoolResolver()->resolveSchoolBySourcedId($context->getOneRosterId());
break;
case $context instanceof ConditionList:
$school = $context->getSchool();
break;
}
if ($school && $this->sentry->check($account, $permission, $school)) {
return VoterInterface::ACCESS_GRANTED;
}
// fall back to checking the specific list if school check didn't succeed
return $this->sentry->check($account, $permission, $subject ? $subject->getContext() : null)
? VoterInterface::ACCESS_GRANTED
: VoterInterface::ACCESS_ABSTAIN;
}
/**
* {@inheritdoc}
*/
protected function try(
Account $account,
string $permission
): int
{
return $this->sentry->try($account, $permission)
? VoterInterface::ACCESS_GRANTED
: VoterInterface::ACCESS_ABSTAIN;
}
}