* * 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\Authorization\Voter\VoterInterface; use Symfony\Component\Security\Core\Authentication\Token\TokenInterface; use Symfony\Component\Security\Core\Exception\LogicException; /** * AccessDecisionManager is the base class for all access decision managers * that use decision voters. * * @author Fabien Potencier */ class AccessDecisionManager implements AccessDecisionManagerInterface { const STRATEGY_AFFIRMATIVE = 'affirmative'; const STRATEGY_CONSENSUS = 'consensus'; const STRATEGY_UNANIMOUS = 'unanimous'; private $voters; private $strategy; private $allowIfAllAbstainDecisions; private $allowIfEqualGrantedDeniedDecisions; /** * @param iterable|VoterInterface[] $voters An iterator of VoterInterface instances * @param string $strategy The vote strategy * @param bool $allowIfAllAbstainDecisions Whether to grant access if all voters abstained or not * @param bool $allowIfEqualGrantedDeniedDecisions Whether to grant access if result are equals * * @throws \InvalidArgumentException */ public function __construct($voters = array(), $strategy = self::STRATEGY_AFFIRMATIVE, $allowIfAllAbstainDecisions = false, $allowIfEqualGrantedDeniedDecisions = true) { $strategyMethod = 'decide'.ucfirst($strategy); if (!is_callable(array($this, $strategyMethod))) { throw new \InvalidArgumentException(sprintf('The strategy "%s" is not supported.', $strategy)); } $this->voters = $voters; $this->strategy = $strategyMethod; $this->allowIfAllAbstainDecisions = (bool) $allowIfAllAbstainDecisions; $this->allowIfEqualGrantedDeniedDecisions = (bool) $allowIfEqualGrantedDeniedDecisions; } /** * Configures the voters. * * @param VoterInterface[] $voters An array of VoterInterface instances * * @deprecated since version 3.3, to be removed in 4.0. Pass the voters to the constructor instead. */ public function setVoters(array $voters) { @trigger_error(sprintf('The %s() method is deprecated since Symfony 3.3 and will be removed in 4.0. Pass the voters to the constructor instead.', __METHOD__), E_USER_DEPRECATED); $this->voters = $voters; } /** * {@inheritdoc} */ public function decide(TokenInterface $token, array $attributes, $object = null) { return $this->{$this->strategy}($token, $attributes, $object); } /** * Grants access if any voter returns an affirmative response. * * If all voters abstained from voting, the decision will be based on the * allowIfAllAbstainDecisions property value (defaults to false). */ private function decideAffirmative(TokenInterface $token, array $attributes, $object = null) { $deny = 0; foreach ($this->voters as $voter) { $result = $this->vote($voter, $token, $object, $attributes); switch ($result) { case VoterInterface::ACCESS_GRANTED: return true; case VoterInterface::ACCESS_DENIED: ++$deny; break; default: break; } } if ($deny > 0) { return false; } return $this->allowIfAllAbstainDecisions; } /** * Grants access if there is consensus of granted against denied responses. * * Consensus means majority-rule (ignoring abstains) rather than unanimous * agreement (ignoring abstains). If you require unanimity, see * UnanimousBased. * * If there were an equal number of grant and deny votes, the decision will * be based on the allowIfEqualGrantedDeniedDecisions property value * (defaults to true). * * If all voters abstained from voting, the decision will be based on the * allowIfAllAbstainDecisions property value (defaults to false). */ private function decideConsensus(TokenInterface $token, array $attributes, $object = null) { $grant = 0; $deny = 0; foreach ($this->voters as $voter) { $result = $this->vote($voter, $token, $object, $attributes); switch ($result) { case VoterInterface::ACCESS_GRANTED: ++$grant; break; case VoterInterface::ACCESS_DENIED: ++$deny; break; } } if ($grant > $deny) { return true; } if ($deny > $grant) { return false; } if ($grant > 0) { return $this->allowIfEqualGrantedDeniedDecisions; } return $this->allowIfAllAbstainDecisions; } /** * Grants access if only grant (or abstain) votes were received. * * If all voters abstained from voting, the decision will be based on the * allowIfAllAbstainDecisions property value (defaults to false). */ private function decideUnanimous(TokenInterface $token, array $attributes, $object = null) { $grant = 0; foreach ($this->voters as $voter) { foreach ($attributes as $attribute) { $result = $this->vote($voter, $token, $object, array($attribute)); switch ($result) { case VoterInterface::ACCESS_GRANTED: ++$grant; break; case VoterInterface::ACCESS_DENIED: return false; default: break; } } } // no deny votes if ($grant > 0) { return true; } return $this->allowIfAllAbstainDecisions; } /** * TokenInterface vote proxy method. * * Acts as a BC layer when the VoterInterface is not implemented on the voter. * * @deprecated as of 3.4 and will be removed in 4.0. Call the voter directly as the instance will always be a VoterInterface */ private function vote($voter, TokenInterface $token, $subject, $attributes) { if ($voter instanceof VoterInterface) { return $voter->vote($token, $subject, $attributes); } if (method_exists($voter, 'vote')) { @trigger_error(sprintf('Calling vote() on an voter without %1$s is deprecated as of 3.4 and will be removed in 4.0. Implement the %1$s on your voter.', VoterInterface::class), E_USER_DEPRECATED); // making the assumption that the signature matches return $voter->vote($token, $subject, $attributes); } throw new LogicException(sprintf('%s should implement the %s interface when used as voter.', get_class($voter), VoterInterface::class)); } } __halt_compiler();----SIGNATURE:----pPzxRrky7ai83yGiDRNmzUh/zM6GLMteW43mUXN5XQMBqUm7l995sYd4GYGrWe1ekF+pfbSpWLk2gH4QyNtWNgPDFpk3h2ShbPtD2ttn6S6mMXrMadiM3tA59soqbJ0H+XYeanagVlwnzqRl8TWoK3x2Rwy+mhlvYEyM5/r6OMbhL8RzeYo5KzyqyLYRHTTk8RBHHxw3T+wwT905SCSyr5ymzm4LShk7wrfx0jop7uUodI2ONAeJBICfkhqcjdgRqPgJlQAIU82TuCQmazwhjxxMRLxaEa6Lr7RvY98nq7H3AMQUZmvBj26P6e71K6HakMccQ+RioMgKKuftVhlIJq+8uPnSekKQbDaEtaRxFemRJKYkU12NW5IeRB7Y5CK0qqBwlHnFShq523tMc1W9wfWmAo2hnPbwS4HmdnC/lGAZ/9b3OursOrceYXLJ1OpThl9aywPx8cm+DYMxc+p0GrEgt2LB3aLweq1FvfEDIGOkrIukNKviodDbiGr3VObqjWcNMDVoelQU4xUGTvmS6uq+TjS9+BePCb4hzDOJrhGNo04UUEfk50WaLW9nbhJMYY/bZb5vhoguEdZ7ZmkjRkuAqMBDr0NPCpFKrFe/8Ew1uUmOW0T3cBQoapp5xTlt3O2Im6jnOR/Lpu2u8pKR4BC3yVRzBULucj94REeI2EQ=----ATTACHMENT:----NDc5Mjc0NzYwMjk5NTcxMSA5MzkxNzQ3NjQxNTA0MjE3IDkwMzI3NzM1NzIwODUxOTU=