Skip to content

Rename DebugAccessDecisionManager to TraceableAccessDecisionManager #21088

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 10 commits into from
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@
use Symfony\Component\Security\Core\Role\RoleInterface;
use Symfony\Component\Security\Http\Logout\LogoutUrlGenerator;
use Symfony\Component\Security\Core\Authorization\AccessDecisionManagerInterface;
use Symfony\Component\Security\Core\Authorization\DebugAccessDecisionManager;
use Symfony\Component\Security\Core\Authorization\TraceableAccessDecisionManager;
use Symfony\Component\VarDumper\Cloner\Data;
use Symfony\Component\Security\Http\FirewallMapInterface;
use Symfony\Bundle\SecurityBundle\Security\FirewallMap;
Expand Down Expand Up @@ -120,7 +120,7 @@ public function collect(Request $request, Response $response, \Exception $except
}

// collect voters and access decision manager information
if ($this->accessDecisionManager instanceof DebugAccessDecisionManager) {
if ($this->accessDecisionManager instanceof TraceableAccessDecisionManager) {
$this->data['access_decision_log'] = array_map(function ($decision) {
$decision['object'] = $this->cloneVar($decision['object']);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
xsi:schemaLocation="http://symfony.com/schema/dic/services http://symfony.com/schema/dic/services/services-1.0.xsd">

<services>
<service id="debug.security.access.decision_manager" class="Symfony\Component\Security\Core\Authorization\DebugAccessDecisionManager" decorates="security.access.decision_manager" public="false">
<service id="debug.security.access.decision_manager" class="Symfony\Component\Security\Core\Authorization\TraceableAccessDecisionManager" decorates="security.access.decision_manager" public="false">
<argument type="service" id="debug.security.access.decision_manager.inner" />
</service>
</services>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,88 +11,11 @@

namespace Symfony\Component\Security\Core\Authorization;

use Symfony\Component\Security\Core\Authentication\Token\TokenInterface;

/**
* Decorates the original AccessDecisionManager class to log information
* about the security voters and the decisions made by them.
*
* @author Javier Eguiluz <javier.eguiluz@gmail.com>
*
* @internal
* @deprecated The DebugAccessDecisionManager class has been renamed and is deprecated since version 3.3 and will be removed in 4.0. Use the TraceableAccessDecisionManager class instead.
*
* This is a placeholder for the old class, that got renamed; this is not a BC break since the class is internal, this
* placeholder is here just to help backward compatibility with older SecurityBundle versions.
*/
class DebugAccessDecisionManager implements AccessDecisionManagerInterface
{
private $manager;
private $strategy;
private $voters = array();
private $decisionLog = array();

public function __construct(AccessDecisionManagerInterface $manager)
{
$this->manager = $manager;

if ($this->manager instanceof AccessDecisionManager) {
// The strategy is stored in a private property of the decorated service
$reflection = new \ReflectionProperty(AccessDecisionManager::class, 'strategy');
$reflection->setAccessible(true);
$this->strategy = $reflection->getValue($manager);
}
}

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

$this->decisionLog[] = array(
'attributes' => $attributes,
'object' => $object,
'result' => $result,
);

return $result;
}

/**
* {@inheritdoc}
*/
public function setVoters(array $voters)
{
if (!method_exists($this->manager, 'setVoters')) {
return;
}

$this->voters = $voters;
$this->manager->setVoters($voters);
}

/**
* @return string
*/
public function getStrategy()
{
// The $strategy property is misleading because it stores the name of its
// method (e.g. 'decideAffirmative') instead of the original strategy name
// (e.g. 'affirmative')
return null === $this->strategy ? '-' : strtolower(substr($this->strategy, 6));
}

/**
* @return array
*/
public function getVoters()
{
return $this->voters;
}

/**
* @return array
*/
public function getDecisionLog()
{
return $this->decisionLog;
}
}
class_exists(TraceableAccessDecisionManager::class);
Original file line number Diff line number Diff line change
@@ -0,0 +1,101 @@
<?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 Symfony\Component\Security\Core\Authorization;

use Symfony\Component\Security\Core\Authentication\Token\TokenInterface;
use Symfony\Component\Security\Core\Authorization\DebugAccessDecisionManager;

/**
* Decorates the original AccessDecisionManager class to log information
* about the security voters and the decisions made by them.
*
* @author Javier Eguiluz <javier.eguiluz@gmail.com>
*
* @internal
*/
class TraceableAccessDecisionManager implements AccessDecisionManagerInterface
{
private $manager;
private $strategy;
private $voters = array();
private $decisionLog = array();

public function __construct(AccessDecisionManagerInterface $manager)
{
$this->manager = $manager;

if ($this->manager instanceof AccessDecisionManager) {
// The strategy is stored in a private property of the decorated service
$reflection = new \ReflectionProperty(AccessDecisionManager::class, 'strategy');
$reflection->setAccessible(true);
$this->strategy = $reflection->getValue($manager);
}
}

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

$this->decisionLog[] = array(
'attributes' => $attributes,
'object' => $object,
'result' => $result,
);

return $result;
}

/**
* {@inheritdoc}
*/
public function setVoters(array $voters)
{
if (!method_exists($this->manager, 'setVoters')) {
return;
}

$this->voters = $voters;
$this->manager->setVoters($voters);
}

/**
* @return string
*/
public function getStrategy()
{
// The $strategy property is misleading because it stores the name of its
// method (e.g. 'decideAffirmative') instead of the original strategy name
// (e.g. 'affirmative')
return null === $this->strategy ? '-' : strtolower(substr($this->strategy, 6));
}

/**
* @return array
*/
public function getVoters()
{
return $this->voters;
}

/**
* @return array
*/
public function getDecisionLog()
{
return $this->decisionLog;
}
}

class_alias(TraceableAccessDecisionManager::class, DebugAccessDecisionManager::class);
Original file line number Diff line number Diff line change
Expand Up @@ -13,16 +13,17 @@

use Symfony\Component\Security\Core\Authorization\AccessDecisionManager;
use Symfony\Component\Security\Core\Authorization\DebugAccessDecisionManager;
use Symfony\Component\Security\Core\Authorization\TraceableAccessDecisionManager;
use Symfony\Component\Security\Core\Authentication\Token\TokenInterface;

class DebugAccessDecisionManagerTest extends \PHPUnit_Framework_TestCase
class TraceableAccessDecisionManagerTest extends \PHPUnit_Framework_TestCase
{
/**
* @dataProvider provideObjectsAndLogs
*/
public function testDecideLog($expectedLog, $object)
{
$adm = new DebugAccessDecisionManager(new AccessDecisionManager());
$adm = new TraceableAccessDecisionManager(new AccessDecisionManager());
$adm->decide($this->getMockBuilder(TokenInterface::class)->getMock(), array('ATTRIBUTE_1'), $object);

$this->assertSame($expectedLog, $adm->getDecisionLog());
Expand All @@ -40,4 +41,13 @@ public function provideObjectsAndLogs()
yield array(array(array('attributes' => array('ATTRIBUTE_1'), 'object' => $x = array(), 'result' => false)), $x);
yield array(array(array('attributes' => array('ATTRIBUTE_1'), 'object' => $object, 'result' => false)), $object);
}

public function testDebugAccessDecisionManagerAliasExistsForBC()
{
$adm = new TraceableAccessDecisionManager(new AccessDecisionManager());

if (!$adm instanceof DebugAccessDecisionManager) {
$this->fail('For BC, TraceableAccessDecisionManager must be an instance of DebugAccessDecisionManager');
}
}
}