![]() Server : Apache System : Linux server2.corals.io 4.18.0-348.2.1.el8_5.x86_64 #1 SMP Mon Nov 15 09:17:08 EST 2021 x86_64 User : corals ( 1002) PHP Version : 7.4.33 Disable Function : exec,passthru,shell_exec,system Directory : /home/corals/mautic.corals.io/vendor/symfony/security-core/Authorization/ |
<?php /* * This file is part of the Symfony package. * * (c) Fabien Potencier <[email protected]> * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. */ namespace Symfony\Component\Security\Core\Authorization; use Symfony\Component\Security\Core\Authentication\Token\TokenInterface; use Symfony\Component\Security\Core\Authorization\Strategy\AccessDecisionStrategyInterface; use Symfony\Component\Security\Core\Authorization\Strategy\AffirmativeStrategy; use Symfony\Component\Security\Core\Authorization\Strategy\ConsensusStrategy; use Symfony\Component\Security\Core\Authorization\Strategy\PriorityStrategy; use Symfony\Component\Security\Core\Authorization\Strategy\UnanimousStrategy; use Symfony\Component\Security\Core\Authorization\Voter\CacheableVoterInterface; use Symfony\Component\Security\Core\Authorization\Voter\VoterInterface; use Symfony\Component\Security\Core\Exception\InvalidArgumentException; /** * AccessDecisionManager is the base class for all access decision managers * that use decision voters. * * @author Fabien Potencier <[email protected]> * * @final since Symfony 5.4 */ class AccessDecisionManager implements AccessDecisionManagerInterface { /** * @deprecated use {@see AffirmativeStrategy} instead */ public const STRATEGY_AFFIRMATIVE = 'affirmative'; /** * @deprecated use {@see ConsensusStrategy} instead */ public const STRATEGY_CONSENSUS = 'consensus'; /** * @deprecated use {@see UnanimousStrategy} instead */ public const STRATEGY_UNANIMOUS = 'unanimous'; /** * @deprecated use {@see PriorityStrategy} instead */ public const STRATEGY_PRIORITY = 'priority'; private const VALID_VOTES = [ VoterInterface::ACCESS_GRANTED => true, VoterInterface::ACCESS_DENIED => true, VoterInterface::ACCESS_ABSTAIN => true, ]; private $voters; private $votersCacheAttributes; private $votersCacheObject; private $strategy; /** * @param iterable<mixed, VoterInterface> $voters An array or an iterator of VoterInterface instances * @param AccessDecisionStrategyInterface|null $strategy The vote strategy * * @throws \InvalidArgumentException */ public function __construct(iterable $voters = [], /* AccessDecisionStrategyInterface */ $strategy = null) { $this->voters = $voters; if (\is_string($strategy)) { trigger_deprecation('symfony/security-core', '5.4', 'Passing the access decision strategy as a string is deprecated, pass an instance of "%s" instead.', AccessDecisionStrategyInterface::class); $allowIfAllAbstainDecisions = 3 <= \func_num_args() && func_get_arg(2); $allowIfEqualGrantedDeniedDecisions = 4 > \func_num_args() || func_get_arg(3); $strategy = $this->createStrategy($strategy, $allowIfAllAbstainDecisions, $allowIfEqualGrantedDeniedDecisions); } elseif (null !== $strategy && !$strategy instanceof AccessDecisionStrategyInterface) { throw new \TypeError(sprintf('"%s": Parameter #2 ($strategy) is expected to be an instance of "%s" or null, "%s" given.', __METHOD__, AccessDecisionStrategyInterface::class, get_debug_type($strategy))); } $this->strategy = $strategy ?? new AffirmativeStrategy(); } /** * @param bool $allowMultipleAttributes Whether to allow passing multiple values to the $attributes array * * {@inheritdoc} */ public function decide(TokenInterface $token, array $attributes, $object = null/* , bool $allowMultipleAttributes = false */) { $allowMultipleAttributes = 3 < \func_num_args() && func_get_arg(3); // Special case for AccessListener, do not remove the right side of the condition before 6.0 if (\count($attributes) > 1 && !$allowMultipleAttributes) { throw new InvalidArgumentException(sprintf('Passing more than one Security attribute to "%s()" is not supported.', __METHOD__)); } return $this->strategy->decide( $this->collectResults($token, $attributes, $object) ); } /** * @param mixed $object * * @return \Traversable<int, int> */ private function collectResults(TokenInterface $token, array $attributes, $object): \Traversable { foreach ($this->getVoters($attributes, $object) as $voter) { $result = $voter->vote($token, $object, $attributes); if (!\is_int($result) || !(self::VALID_VOTES[$result] ?? false)) { trigger_deprecation('symfony/security-core', '5.3', 'Returning "%s" in "%s::vote()" is deprecated, return one of "%s" constants: "ACCESS_GRANTED", "ACCESS_DENIED" or "ACCESS_ABSTAIN".', var_export($result, true), get_debug_type($voter), VoterInterface::class); } yield $result; } } /** * @throws \InvalidArgumentException if the $strategy is invalid */ private function createStrategy(string $strategy, bool $allowIfAllAbstainDecisions, bool $allowIfEqualGrantedDeniedDecisions): AccessDecisionStrategyInterface { switch ($strategy) { case self::STRATEGY_AFFIRMATIVE: return new AffirmativeStrategy($allowIfAllAbstainDecisions); case self::STRATEGY_CONSENSUS: return new ConsensusStrategy($allowIfAllAbstainDecisions, $allowIfEqualGrantedDeniedDecisions); case self::STRATEGY_UNANIMOUS: return new UnanimousStrategy($allowIfAllAbstainDecisions); case self::STRATEGY_PRIORITY: return new PriorityStrategy($allowIfAllAbstainDecisions); } throw new \InvalidArgumentException(sprintf('The strategy "%s" is not supported.', $strategy)); } /** * @return iterable<mixed, VoterInterface> */ private function getVoters(array $attributes, $object = null): iterable { $keyAttributes = []; foreach ($attributes as $attribute) { $keyAttributes[] = \is_string($attribute) ? $attribute : null; } // use `get_class` to handle anonymous classes $keyObject = \is_object($object) ? \get_class($object) : get_debug_type($object); foreach ($this->voters as $key => $voter) { if (!$voter instanceof CacheableVoterInterface) { yield $voter; continue; } $supports = true; // The voter supports the attributes if it supports at least one attribute of the list foreach ($keyAttributes as $keyAttribute) { if (null === $keyAttribute) { $supports = true; } elseif (!isset($this->votersCacheAttributes[$keyAttribute][$key])) { $this->votersCacheAttributes[$keyAttribute][$key] = $supports = $voter->supportsAttribute($keyAttribute); } else { $supports = $this->votersCacheAttributes[$keyAttribute][$key]; } if ($supports) { break; } } if (!$supports) { continue; } if (!isset($this->votersCacheObject[$keyObject][$key])) { $this->votersCacheObject[$keyObject][$key] = $supports = $voter->supportsType($keyObject); } else { $supports = $this->votersCacheObject[$keyObject][$key]; } if (!$supports) { continue; } yield $voter; } } }