vendor/symfony/security/Core/Authorization/AccessDecisionManager.php line 60

Open in your IDE?
  1. <?php
  2. /*
  3.  * This file is part of the Symfony package.
  4.  *
  5.  * (c) Fabien Potencier <fabien@symfony.com>
  6.  *
  7.  * For the full copyright and license information, please view the LICENSE
  8.  * file that was distributed with this source code.
  9.  */
  10. namespace Symfony\Component\Security\Core\Authorization;
  11. use Symfony\Component\Security\Core\Authentication\Token\TokenInterface;
  12. use Symfony\Component\Security\Core\Authorization\Voter\VoterInterface;
  13. /**
  14.  * AccessDecisionManager is the base class for all access decision managers
  15.  * that use decision voters.
  16.  *
  17.  * @author Fabien Potencier <fabien@symfony.com>
  18.  */
  19. class AccessDecisionManager implements AccessDecisionManagerInterface
  20. {
  21.     const STRATEGY_AFFIRMATIVE 'affirmative';
  22.     const STRATEGY_CONSENSUS 'consensus';
  23.     const STRATEGY_UNANIMOUS 'unanimous';
  24.     private $voters;
  25.     private $strategy;
  26.     private $allowIfAllAbstainDecisions;
  27.     private $allowIfEqualGrantedDeniedDecisions;
  28.     /**
  29.      * @param iterable|VoterInterface[] $voters                             An array or an iterator of VoterInterface instances
  30.      * @param string                    $strategy                           The vote strategy
  31.      * @param bool                      $allowIfAllAbstainDecisions         Whether to grant access if all voters abstained or not
  32.      * @param bool                      $allowIfEqualGrantedDeniedDecisions Whether to grant access if result are equals
  33.      *
  34.      * @throws \InvalidArgumentException
  35.      */
  36.     public function __construct(iterable $voters = [], string $strategy self::STRATEGY_AFFIRMATIVEbool $allowIfAllAbstainDecisions falsebool $allowIfEqualGrantedDeniedDecisions true)
  37.     {
  38.         $strategyMethod 'decide'.ucfirst($strategy);
  39.         if ('' === $strategy || !\is_callable([$this$strategyMethod])) {
  40.             throw new \InvalidArgumentException(sprintf('The strategy "%s" is not supported.'$strategy));
  41.         }
  42.         $this->voters $voters;
  43.         $this->strategy $strategyMethod;
  44.         $this->allowIfAllAbstainDecisions $allowIfAllAbstainDecisions;
  45.         $this->allowIfEqualGrantedDeniedDecisions $allowIfEqualGrantedDeniedDecisions;
  46.     }
  47.     /**
  48.      * {@inheritdoc}
  49.      */
  50.     public function decide(TokenInterface $token, array $attributes$object null)
  51.     {
  52.         return $this->{$this->strategy}($token$attributes$object);
  53.     }
  54.     /**
  55.      * Grants access if any voter returns an affirmative response.
  56.      *
  57.      * If all voters abstained from voting, the decision will be based on the
  58.      * allowIfAllAbstainDecisions property value (defaults to false).
  59.      */
  60.     private function decideAffirmative(TokenInterface $token, array $attributes$object null)
  61.     {
  62.         $deny 0;
  63.         foreach ($this->voters as $voter) {
  64.             $result $voter->vote($token$object$attributes);
  65.             switch ($result) {
  66.                 case VoterInterface::ACCESS_GRANTED:
  67.                     return true;
  68.                 case VoterInterface::ACCESS_DENIED:
  69.                     ++$deny;
  70.                     break;
  71.                 default:
  72.                     break;
  73.             }
  74.         }
  75.         if ($deny 0) {
  76.             return false;
  77.         }
  78.         return $this->allowIfAllAbstainDecisions;
  79.     }
  80.     /**
  81.      * Grants access if there is consensus of granted against denied responses.
  82.      *
  83.      * Consensus means majority-rule (ignoring abstains) rather than unanimous
  84.      * agreement (ignoring abstains). If you require unanimity, see
  85.      * UnanimousBased.
  86.      *
  87.      * If there were an equal number of grant and deny votes, the decision will
  88.      * be based on the allowIfEqualGrantedDeniedDecisions property value
  89.      * (defaults to true).
  90.      *
  91.      * If all voters abstained from voting, the decision will be based on the
  92.      * allowIfAllAbstainDecisions property value (defaults to false).
  93.      */
  94.     private function decideConsensus(TokenInterface $token, array $attributes$object null)
  95.     {
  96.         $grant 0;
  97.         $deny 0;
  98.         foreach ($this->voters as $voter) {
  99.             $result $voter->vote($token$object$attributes);
  100.             switch ($result) {
  101.                 case VoterInterface::ACCESS_GRANTED:
  102.                     ++$grant;
  103.                     break;
  104.                 case VoterInterface::ACCESS_DENIED:
  105.                     ++$deny;
  106.                     break;
  107.             }
  108.         }
  109.         if ($grant $deny) {
  110.             return true;
  111.         }
  112.         if ($deny $grant) {
  113.             return false;
  114.         }
  115.         if ($grant 0) {
  116.             return $this->allowIfEqualGrantedDeniedDecisions;
  117.         }
  118.         return $this->allowIfAllAbstainDecisions;
  119.     }
  120.     /**
  121.      * Grants access if only grant (or abstain) votes were received.
  122.      *
  123.      * If all voters abstained from voting, the decision will be based on the
  124.      * allowIfAllAbstainDecisions property value (defaults to false).
  125.      */
  126.     private function decideUnanimous(TokenInterface $token, array $attributes$object null)
  127.     {
  128.         $grant 0;
  129.         foreach ($this->voters as $voter) {
  130.             foreach ($attributes as $attribute) {
  131.                 $result $voter->vote($token$object, [$attribute]);
  132.                 switch ($result) {
  133.                     case VoterInterface::ACCESS_GRANTED:
  134.                         ++$grant;
  135.                         break;
  136.                     case VoterInterface::ACCESS_DENIED:
  137.                         return false;
  138.                     default:
  139.                         break;
  140.                 }
  141.             }
  142.         }
  143.         // no deny votes
  144.         if ($grant 0) {
  145.             return true;
  146.         }
  147.         return $this->allowIfAllAbstainDecisions;
  148.     }
  149. }