2024-04-10 21:15:57 +02:00

95 lines
2.9 KiB
PHP

<?php
declare(strict_types=1);
/*
* Chill is a software for social workers
*
* For the full copyright and license information, please view
* the LICENSE file that was distributed with this source code.
*/
namespace Chill\BudgetBundle\Security\Authorization;
use Chill\BudgetBundle\Entity\AbstractElement;
use Chill\MainBundle\Security\Authorization\VoterHelperFactoryInterface;
use Chill\MainBundle\Security\Authorization\VoterHelperInterface;
use Chill\MainBundle\Security\ProvideRoleHierarchyInterface;
use Chill\PersonBundle\Entity\Household\Household;
use Chill\PersonBundle\Entity\Person;
use Symfony\Component\Security\Core\Authentication\Token\TokenInterface;
use Symfony\Component\Security\Core\Authorization\Voter\Voter;
class BudgetElementVoter extends Voter implements ProvideRoleHierarchyInterface
{
final public const CREATE = 'CHILL_BUDGET_ELEMENT_CREATE';
final public const DELETE = 'CHILL_BUDGET_ELEMENT_DELETE';
final public const ROLES = [
self::CREATE,
self::DELETE,
self::SEE,
self::UPDATE,
];
final public const SEE = 'CHILL_BUDGET_ELEMENT_SEE';
final public const UPDATE = 'CHILL_BUDGET_ELEMENT_UPDATE';
protected VoterHelperInterface $voter;
public function __construct(VoterHelperFactoryInterface $voterFactory)
{
$this->voter = $voterFactory
->generate(self::class)
->addCheckFor(AbstractElement::class, self::ROLES)
->addCheckFor(Person::class, [self::CREATE, self::SEE])
->addCheckFor(Household::class, [self::CREATE, self::SEE])
->build();
}
public function getRoles(): array
{
return self::ROLES;
}
public function getRolesWithHierarchy(): array
{
return ['Budget elements' => self::ROLES];
}
public function getRolesWithoutScope(): array
{
return self::ROLES;
}
protected function supports($attribute, $subject)
{
return $this->voter->supports($attribute, $subject);
}
protected function voteOnAttribute($attribute, $subject, TokenInterface $token)
{
if (
$subject instanceof Person
|| ($subject instanceof AbstractElement && null !== $person = $subject->getPerson())) {
return $this->voter->voteOnAttribute($attribute, $person ?? $subject, $token);
}
if (
$subject instanceof Household
|| ($subject instanceof AbstractElement && null !== $household = $subject->getHousehold())) {
foreach (($household ?? $subject)->getCurrentPersons() as $person) {
if ($this->voter->voteOnAttribute($attribute, $person, $token)) {
return true;
}
}
return false;
}
throw new \UnexpectedValueException('This subject is not supported, or is an element not associated with person or household');
}
}