Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Adding a new interface that give voters access to AccessDecisionManager #14550

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
wants to merge 2 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ class AccessDecisionManager implements AccessDecisionManagerInterface
private $strategy;
private $allowIfAllAbstainDecisions;
private $allowIfEqualGrantedDeniedDecisions;
private $areVotersPrepared = false;

/**
* Constructor.
Expand Down Expand Up @@ -102,6 +103,7 @@ public function supportsClass($class)
*/
private function decideAffirmative(TokenInterface $token, array $attributes, $object = null)
{
$this->prepareVoters();
$deny = 0;
foreach ($this->voters as $voter) {
$result = $voter->vote($token, $object, $attributes);
Expand Down Expand Up @@ -142,6 +144,7 @@ private function decideAffirmative(TokenInterface $token, array $attributes, $ob
*/
private function decideConsensus(TokenInterface $token, array $attributes, $object = null)
{
$this->prepareVoters();
$grant = 0;
$deny = 0;
$abstain = 0;
Expand Down Expand Up @@ -189,6 +192,7 @@ private function decideConsensus(TokenInterface $token, array $attributes, $obje
*/
private function decideUnanimous(TokenInterface $token, array $attributes, $object = null)
{
$this->prepareVoters();
$grant = 0;
foreach ($attributes as $attribute) {
foreach ($this->voters as $voter) {
Expand Down Expand Up @@ -216,4 +220,23 @@ private function decideUnanimous(TokenInterface $token, array $attributes, $obje

return $this->allowIfAllAbstainDecisions;
}

/**
* Guarantees that AccessDecisionManagerAwareInterface voters have
* been prepared properly.
*/
private function prepareVoters()
{
if ($this->areVotersPrepared) {
return;
}

// inject this AccessDecisionManager into any voters that want it
foreach ($this->voters as $voter) {
if ($voter instanceof AccessDecisionManagerAwareInterface) {
$voter->setAccessDecisionManager($this);
}
}
$this->areVotersPrepared = true;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
<?php

namespace Symfony\Component\Security\Core\Authorization;

/**
* If a Voter implements this interface, AccessDecisionManager will call
* setAccessDecisionManager on the voter before calling vote().
*
* This allows Voters to get access to the AccessDecisionManager so that
* they can check the result of other voters internally.
*/
interface AccessDecisionManagerAwareInterface
{
/**
* This method is called on a voter that implements this interface
* before calling vote().
*
* @param AccessDecisionManagerInterface $decisionManager
*/
public function setAccessDecisionManager(AccessDecisionManagerInterface $decisionManager);
}
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
namespace Symfony\Component\Security\Core\Tests\Authorization;

use Symfony\Component\Security\Core\Authorization\AccessDecisionManager;
use Symfony\Component\Security\Core\Authorization\AccessDecisionManagerAwareInterface;
use Symfony\Component\Security\Core\Authorization\Voter\VoterInterface;

class AccessDecisionManagerTest extends \PHPUnit_Framework_TestCase
Expand Down Expand Up @@ -62,6 +63,25 @@ public function testSetUnsupportedStrategy()
new AccessDecisionManager(array($this->getVoter(VoterInterface::ACCESS_GRANTED)), 'fooBar');
}

public function testAccessDecisionManagerInterfaceSetting()
{
$strategies = array('affirmative', 'consensus', 'unanimous');

$token = $this->getMock('Symfony\Component\Security\Core\Authentication\Token\TokenInterface');
foreach ($strategies as $strategy) {
// mock our stub voter that implements the AccessDecisionManagerAwareInterface
$voter = $this->getMock('Symfony\Component\Security\Core\Tests\Authorization\VoterWithAccessDecisionManagerAwareInterfaceStub');

$manager = new AccessDecisionManager(array($voter), $strategy);

$voter->expects($this->once())
->method('setAccessDecisionManager')
->with($manager);

$manager->decide($token, array('ROLE_DOES_NOT_MATTER'));
}
}

/**
* @dataProvider getStrategyTests
*/
Expand Down Expand Up @@ -196,3 +216,8 @@ protected function getVoterSupportsAttribute($ret)
return $voter;
}
}

// stub class that implements AccessDecisionManagerAwareInterface
abstract class VoterWithAccessDecisionManagerAwareInterfaceStub implements VoterInterface, AccessDecisionManagerAwareInterface
{
}