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

Skip to content

Commit f527790

Browse files
author
Hugo Hamon
committed
[Security] remove support for defining voters that don't implement the VoterInterface interface.
1 parent 8483564 commit f527790

File tree

8 files changed

+15
-129
lines changed

8 files changed

+15
-129
lines changed

UPGRADE-4.0.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -455,6 +455,8 @@ Security
455455
* The `AccessDecisionManager::setVoters()` method has been removed. Pass the
456456
voters to the constructor instead.
457457

458+
* Support for defining voters that don't implement the `VoterInterface` has been removed.
459+
458460
SecurityBundle
459461
--------------
460462

src/Symfony/Bundle/SecurityBundle/CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ CHANGELOG
88
* made `FirewallMap::$container` and `::$map` private
99
* made the first `UserPasswordEncoderCommand::_construct()` argument mandatory
1010
* `UserPasswordEncoderCommand` does not extend `ContainerAwareCommand` anymore
11+
* removed support for voters that don't implement the `VoterInterface`
1112

1213
3.4.0
1314
-----

src/Symfony/Bundle/SecurityBundle/DependencyInjection/Compiler/AddSecurityVotersPass.php

Lines changed: 2 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -38,19 +38,14 @@ public function process(ContainerBuilder $container)
3838

3939
$voters = $this->findAndSortTaggedServices('security.voter', $container);
4040
if (!$voters) {
41-
throw new LogicException('No security voters found. You need to tag at least one with "security.voter"');
41+
throw new LogicException('No security voters found. You need to tag at least one with "security.voter".');
4242
}
4343

4444
foreach ($voters as $voter) {
4545
$class = $container->getDefinition((string) $voter)->getClass();
4646

4747
if (!is_a($class, VoterInterface::class, true)) {
48-
@trigger_error(sprintf('Using a security.voter tag on a class without implementing the %1$s is deprecated as of 3.4 and will be removed in 4.0. Implement the %1$s instead.', VoterInterface::class), E_USER_DEPRECATED);
49-
}
50-
51-
if (!method_exists($class, 'vote')) {
52-
// in case the vote method is completely missing, to prevent exceptions when voting
53-
throw new LogicException(sprintf('%s should implement the %s interface when used as voter.', $class, VoterInterface::class));
48+
throw new LogicException(sprintf('%s must implement the %s when used as a voter.', $class, VoterInterface::class));
5449
}
5550
}
5651

src/Symfony/Bundle/SecurityBundle/Tests/DependencyInjection/Compiler/AddSecurityVotersPassTest.php

Lines changed: 4 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -14,16 +14,15 @@
1414
use PHPUnit\Framework\TestCase;
1515
use Symfony\Bundle\SecurityBundle\DependencyInjection\Compiler\AddSecurityVotersPass;
1616
use Symfony\Component\DependencyInjection\ContainerBuilder;
17-
use Symfony\Component\DependencyInjection\Exception\LogicException;
1817
use Symfony\Component\DependencyInjection\Reference;
1918
use Symfony\Component\Security\Core\Authorization\AccessDecisionManager;
2019
use Symfony\Component\Security\Core\Authorization\Voter\Voter;
21-
use Symfony\Component\Security\Core\Tests\Authorization\Stub\VoterWithoutInterface;
2220

2321
class AddSecurityVotersPassTest extends TestCase
2422
{
2523
/**
2624
* @expectedException \Symfony\Component\DependencyInjection\Exception\LogicException
25+
* @expectedExceptionMessage No security voters found. You need to tag at least one with "security.voter".
2726
*/
2827
public function testNoVoters()
2928
{
@@ -71,8 +70,8 @@ public function testThatSecurityVotersAreProcessedInPriorityOrder()
7170
}
7271

7372
/**
74-
* @group legacy
75-
* @expectedDeprecation Using a security.voter tag on a class without implementing the Symfony\Component\Security\Core\Authorization\Voter\VoterInterface is deprecated as of 3.4 and will be removed in 4.0. Implement the Symfony\Component\Security\Core\Authorization\Voter\VoterInterface instead.
73+
* @expectedException \Symfony\Component\DependencyInjection\Exception\LogicException
74+
* @expectedExceptionMessage stdClass must implement the Symfony\Component\Security\Core\Authorization\Voter\VoterInterface when used as a voter.
7675
*/
7776
public function testVoterMissingInterface()
7877
{
@@ -82,40 +81,7 @@ public function testVoterMissingInterface()
8281
->addArgument(array())
8382
;
8483
$container
85-
->register('without_interface', VoterWithoutInterface::class)
86-
->addTag('security.voter')
87-
;
88-
$compilerPass = new AddSecurityVotersPass();
89-
$compilerPass->process($container);
90-
91-
$argument = $container->getDefinition('security.access.decision_manager')->getArgument(0);
92-
$refs = $argument->getValues();
93-
$this->assertEquals(new Reference('without_interface'), $refs[0]);
94-
$this->assertCount(1, $refs);
95-
}
96-
97-
/**
98-
* @group legacy
99-
*/
100-
public function testVoterMissingInterfaceAndMethod()
101-
{
102-
$exception = LogicException::class;
103-
$message = 'stdClass should implement the Symfony\Component\Security\Core\Authorization\Voter\VoterInterface interface when used as voter.';
104-
105-
if (method_exists($this, 'expectException')) {
106-
$this->expectException($exception);
107-
$this->expectExceptionMessage($message);
108-
} else {
109-
$this->setExpectedException($exception, $message);
110-
}
111-
112-
$container = new ContainerBuilder();
113-
$container
114-
->register('security.access.decision_manager', AccessDecisionManager::class)
115-
->addArgument(array())
116-
;
117-
$container
118-
->register('without_method', 'stdClass')
84+
->register('without_interface', 'stdClass')
11985
->addTag('security.voter')
12086
;
12187
$compilerPass = new AddSecurityVotersPass();

src/Symfony/Component/Security/CHANGELOG.md

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,8 @@ CHANGELOG
88
You should implement this method yourself in your concrete authenticator.
99
* removed the `AccessDecisionManager::setVoters()` method
1010
* removed the `RoleInterface`
11-
* added a sixth `string $context` argument to`LogoutUrlGenerator::registerListener()`
11+
* removed support for voters that don't implement the `VoterInterface`
12+
* added a sixth `string $context` argument to `LogoutUrlGenerator::registerListener()`
1213

1314
3.4.0
1415
-----

src/Symfony/Component/Security/Core/Authorization/AccessDecisionManager.php

Lines changed: 4 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,6 @@
1313

1414
use Symfony\Component\Security\Core\Authorization\Voter\VoterInterface;
1515
use Symfony\Component\Security\Core\Authentication\Token\TokenInterface;
16-
use Symfony\Component\Security\Core\Exception\LogicException;
1716

1817
/**
1918
* AccessDecisionManager is the base class for all access decision managers
@@ -33,7 +32,7 @@ class AccessDecisionManager implements AccessDecisionManagerInterface
3332
private $allowIfEqualGrantedDeniedDecisions;
3433

3534
/**
36-
* @param iterable|VoterInterface[] $voters An iterator of VoterInterface instances
35+
* @param iterable|VoterInterface[] $voters An array or an iterator of VoterInterface instances
3736
* @param string $strategy The vote strategy
3837
* @param bool $allowIfAllAbstainDecisions Whether to grant access if all voters abstained or not
3938
* @param bool $allowIfEqualGrantedDeniedDecisions Whether to grant access if result are equals
@@ -71,7 +70,7 @@ private function decideAffirmative(TokenInterface $token, array $attributes, $ob
7170
{
7271
$deny = 0;
7372
foreach ($this->voters as $voter) {
74-
$result = $this->vote($voter, $token, $object, $attributes);
73+
$result = $voter->vote($token, $object, $attributes);
7574
switch ($result) {
7675
case VoterInterface::ACCESS_GRANTED:
7776
return true;
@@ -112,7 +111,7 @@ private function decideConsensus(TokenInterface $token, array $attributes, $obje
112111
$grant = 0;
113112
$deny = 0;
114113
foreach ($this->voters as $voter) {
115-
$result = $this->vote($voter, $token, $object, $attributes);
114+
$result = $voter->vote($token, $object, $attributes);
116115

117116
switch ($result) {
118117
case VoterInterface::ACCESS_GRANTED:
@@ -153,7 +152,7 @@ private function decideUnanimous(TokenInterface $token, array $attributes, $obje
153152
$grant = 0;
154153
foreach ($this->voters as $voter) {
155154
foreach ($attributes as $attribute) {
156-
$result = $this->vote($voter, $token, $object, array($attribute));
155+
$result = $voter->vote($token, $object, array($attribute));
157156

158157
switch ($result) {
159158
case VoterInterface::ACCESS_GRANTED:
@@ -177,27 +176,4 @@ private function decideUnanimous(TokenInterface $token, array $attributes, $obje
177176

178177
return $this->allowIfAllAbstainDecisions;
179178
}
180-
181-
/**
182-
* TokenInterface vote proxy method.
183-
*
184-
* Acts as a BC layer when the VoterInterface is not implemented on the voter.
185-
*
186-
* @deprecated as of 3.4 and will be removed in 4.0. Call the voter directly as the instance will always be a VoterInterface
187-
*/
188-
private function vote($voter, TokenInterface $token, $subject, $attributes)
189-
{
190-
if ($voter instanceof VoterInterface) {
191-
return $voter->vote($token, $subject, $attributes);
192-
}
193-
194-
if (method_exists($voter, 'vote')) {
195-
@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);
196-
197-
// making the assumption that the signature matches
198-
return $voter->vote($token, $subject, $attributes);
199-
}
200-
201-
throw new LogicException(sprintf('%s should implement the %s interface when used as voter.', get_class($voter), VoterInterface::class));
202-
}
203179
}

src/Symfony/Component/Security/Core/Tests/Authorization/AccessDecisionManagerTest.php

Lines changed: 0 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -12,11 +12,8 @@
1212
namespace Symfony\Component\Security\Core\Tests\Authorization;
1313

1414
use PHPUnit\Framework\TestCase;
15-
use Symfony\Component\Security\Core\Authentication\Token\TokenInterface;
1615
use Symfony\Component\Security\Core\Authorization\AccessDecisionManager;
1716
use Symfony\Component\Security\Core\Authorization\Voter\VoterInterface;
18-
use Symfony\Component\Security\Core\Exception\LogicException;
19-
use Symfony\Component\Security\Core\Tests\Authorization\Stub\VoterWithoutInterface;
2017

2118
class AccessDecisionManagerTest extends TestCase
2219
{
@@ -141,34 +138,4 @@ protected function getVoter($vote)
141138

142139
return $voter;
143140
}
144-
145-
public function testVotingWrongTypeNoVoteMethod()
146-
{
147-
$exception = LogicException::class;
148-
$message = sprintf('stdClass should implement the %s interface when used as voter.', VoterInterface::class);
149-
150-
if (method_exists($this, 'expectException')) {
151-
$this->expectException($exception);
152-
$this->expectExceptionMessage($message);
153-
} else {
154-
$this->setExpectedException($exception, $message);
155-
}
156-
157-
$adm = new AccessDecisionManager(array(new \stdClass()));
158-
$token = $this->getMockBuilder(TokenInterface::class)->getMock();
159-
160-
$adm->decide($token, array('TEST'));
161-
}
162-
163-
/**
164-
* @group legacy
165-
* @expectedDeprecation Calling vote() on an voter without Symfony\Component\Security\Core\Authorization\Voter\VoterInterface is deprecated as of 3.4 and will be removed in 4.0. Implement the Symfony\Component\Security\Core\Authorization\Voter\VoterInterface on your voter.
166-
*/
167-
public function testVotingWrongTypeWithVote()
168-
{
169-
$adm = new AccessDecisionManager(array(new VoterWithoutInterface()));
170-
$token = $this->getMockBuilder(TokenInterface::class)->getMock();
171-
172-
$adm->decide($token, array('TEST'));
173-
}
174141
}

src/Symfony/Component/Security/Core/Tests/Authorization/Stub/VoterWithoutInterface.php

Lines changed: 0 additions & 22 deletions
This file was deleted.

0 commit comments

Comments
 (0)