Вход Регистрация
Файл: symfony-2.7/src/Symfony/Component/Security/Core/Authorization/AccessDecisionManager.php
Строк: 254
<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace SymfonyComponentSecurityCoreAuthorization;

use 
SymfonyComponentSecurityCoreAuthorizationVoterVoterInterface;
use 
SymfonyComponentSecurityCoreAuthenticationTokenTokenInterface;

/**
 * AccessDecisionManager is the base class for all access decision managers
 * that use decision voters.
 *
 * @author Fabien Potencier <fabien@symfony.com>
 */
class AccessDecisionManager implements AccessDecisionManagerInterface
{
    const 
STRATEGY_AFFIRMATIVE 'affirmative';
    const 
STRATEGY_CONSENSUS 'consensus';
    const 
STRATEGY_UNANIMOUS 'unanimous';

    private 
$voters;
    private 
$strategy;
    private 
$allowIfAllAbstainDecisions;
    private 
$allowIfEqualGrantedDeniedDecisions;

    
/**
     * Constructor.
     *
     * @param VoterInterface[] $voters                             An array 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(array $voters$strategy self::STRATEGY_AFFIRMATIVE$allowIfAllAbstainDecisions false$allowIfEqualGrantedDeniedDecisions true)
    {
        if (!
$voters) {
            throw new 
InvalidArgumentException('You must at least add one voter.');
        }

        
$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;
    }

    
/**
     * {@inheritdoc}
     */
    
public function decide(TokenInterface $token, array $attributes$object null)
    {
        return 
$this->{$this->strategy}($token$attributes$object);
    }

    
/**
     * {@inheritdoc}
     */
    
public function supportsAttribute($attribute)
    {
        foreach (
$this->voters as $voter) {
            if (
$voter->supportsAttribute($attribute)) {
                return 
true;
            }
        }

        return 
false;
    }

    
/**
     * {@inheritdoc}
     */
    
public function supportsClass($class)
    {
        foreach (
$this->voters as $voter) {
            if (
$voter->supportsClass($class)) {
                return 
true;
            }
        }

        return 
false;
    }

    
/**
     * 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 $voter->vote($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;
        
$abstain 0;
        foreach (
$this->voters as $voter) {
            
$result $voter->vote($token$object$attributes);

            switch (
$result) {
                case 
VoterInterface::ACCESS_GRANTED:
                    ++
$grant;

                    break;

                case 
VoterInterface::ACCESS_DENIED:
                    ++
$deny;

                    break;

                default:
                    ++
$abstain;

                    break;
            }
        }

        if (
$grant $deny) {
            return 
true;
        }

        if (
$deny $grant) {
            return 
false;
        }

        if (
$grant == $deny && $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 (
$attributes as $attribute) {
            foreach (
$this->voters as $voter) {
                
$result $voter->vote($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;
    }
}
Онлайн: 3
Реклама