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

Skip to content

Commit a58df11

Browse files
feature #16601 [Security] Deprecate "AbstractVoter" in favor of "Voter" (nicolas-grekas, lyrixx)
This PR was merged into the 2.8 branch. Discussion ---------- [Security] Deprecate "AbstractVoter" in favor of "Voter" | Q | A | ------------- | --- | Bug fix? | yes | New feature? | yes | BC breaks? | no | Deprecations? | yes | Tests pass? | yes | Fixed tickets | #16556, #16558, #16554 | License | MIT | Doc PR | - Commits ------- fd8b87c [Security] Deprecate "AbstractVoter" in favor of "Voter" d3c6d93 [Security] Revert changes made between 2.7 and 2.8-beta
2 parents da43309 + fd8b87c commit a58df11

File tree

6 files changed

+201
-180
lines changed

6 files changed

+201
-180
lines changed

UPGRADE-2.8.md

Lines changed: 5 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -442,38 +442,12 @@ FrameworkBundle
442442
Security
443443
--------
444444
445-
* The AbstractToken::isGranted() method was deprecated. Instead,
446-
override the voteOnAttribute() method. This method has one small
447-
difference: it's passed the TokenInterface instead of the user:
445+
* The `AbstractVoter` class was deprecated. Instead, extend the `Voter` class and
446+
move your voting logic in the `supports($attribute, $subject)` and
447+
`voteOnAttribute($attribute, $object, TokenInterface $token)` methods.
448448

449-
Before:
450-
451-
```php
452-
class MyCustomVoter extends AbstractVoter
453-
{
454-
// ...
455-
456-
protected function isGranted($attribute, $object, $user = null)
457-
{
458-
// ...
459-
}
460-
}
461-
```
462-
463-
After:
464-
465-
```php
466-
class MyCustomVoter extends AbstractVoter
467-
{
468-
// ...
469-
470-
protected function voteOnAttribute($attribute, $object, TokenInterface $token)
471-
{
472-
$user = $token->getUser();
473-
// ...
474-
}
475-
}
476-
```
449+
* The `VoterInterface::supportsClass` and `supportsAttribute` methods were
450+
deprecated and will be removed from the interface in 3.0.
477451

478452
Config
479453
------

src/Symfony/Component/Security/Core/Authorization/Voter/AbstractVoter.php

Lines changed: 10 additions & 79 deletions
Original file line numberDiff line numberDiff line change
@@ -11,13 +11,17 @@
1111

1212
namespace Symfony\Component\Security\Core\Authorization\Voter;
1313

14+
@trigger_error('The '.__NAMESPACE__.'\AbstractVoter class is deprecated since version 2.8, to be removed in 3.0. Upgrade to Symfony\Component\Security\Core\Authorization\Voter\Voter instead.', E_USER_DEPRECATED);
15+
1416
use Symfony\Component\Security\Core\User\UserInterface;
1517
use Symfony\Component\Security\Core\Authentication\Token\TokenInterface;
1618

1719
/**
1820
* Abstract Voter implementation that reduces boilerplate code required to create a custom Voter.
1921
*
2022
* @author Roman Marintšenko <[email protected]>
23+
*
24+
* @deprecated since version 2.8, to be removed in 3.0. Upgrade to Symfony\Component\Security\Core\Authorization\Voter\Voter instead.
2125
*/
2226
abstract class AbstractVoter implements VoterInterface
2327
{
@@ -26,8 +30,6 @@ abstract class AbstractVoter implements VoterInterface
2630
*/
2731
public function supportsAttribute($attribute)
2832
{
29-
@trigger_error('The '.__METHOD__.' is deprecated since version 2.8 and will be removed in version 3.0.', E_USER_DEPRECATED);
30-
3133
return in_array($attribute, $this->getSupportedAttributes());
3234
}
3335

@@ -36,8 +38,6 @@ public function supportsAttribute($attribute)
3638
*/
3739
public function supportsClass($class)
3840
{
39-
@trigger_error('The '.__METHOD__.' is deprecated since version 2.8 and will be removed in version 3.0.', E_USER_DEPRECATED);
40-
4141
foreach ($this->getSupportedClasses() as $supportedClass) {
4242
if ($supportedClass === $class || is_subclass_of($class, $supportedClass)) {
4343
return true;
@@ -62,22 +62,22 @@ public function supportsClass($class)
6262
*/
6363
public function vote(TokenInterface $token, $object, array $attributes)
6464
{
65-
if (!$object) {
65+
if (!$object || !$this->supportsClass(get_class($object))) {
6666
return self::ACCESS_ABSTAIN;
6767
}
6868

6969
// abstain vote by default in case none of the attributes are supported
7070
$vote = self::ACCESS_ABSTAIN;
7171

7272
foreach ($attributes as $attribute) {
73-
if (!$this->supports($attribute, $object)) {
73+
if (!$this->supportsAttribute($attribute)) {
7474
continue;
7575
}
7676

7777
// as soon as at least one attribute is supported, default is to deny access
7878
$vote = self::ACCESS_DENIED;
7979

80-
if ($this->voteOnAttribute($attribute, $object, $token)) {
80+
if ($this->isGranted($attribute, $object, $token->getUser())) {
8181
// grant access as soon as at least one voter returns a positive response
8282
return self::ACCESS_GRANTED;
8383
}
@@ -86,62 +86,19 @@ public function vote(TokenInterface $token, $object, array $attributes)
8686
return $vote;
8787
}
8888

89-
/**
90-
* Determines if the attribute and object are supported by this voter.
91-
*
92-
* This method will become abstract in 3.0.
93-
*
94-
* @param string $attribute An attribute
95-
* @param string $object The object to secure
96-
*
97-
* @return bool True if the attribute and object is supported, false otherwise
98-
*/
99-
protected function supports($attribute, $object)
100-
{
101-
@trigger_error('The getSupportedClasses and getSupportedAttributes methods are deprecated since version 2.8 and will be removed in version 3.0. Overwrite supports instead.', E_USER_DEPRECATED);
102-
103-
$classIsSupported = false;
104-
foreach ($this->getSupportedClasses() as $supportedClass) {
105-
if ($object instanceof $supportedClass) {
106-
$classIsSupported = true;
107-
break;
108-
}
109-
}
110-
111-
if (!$classIsSupported) {
112-
return false;
113-
}
114-
115-
if (!in_array($attribute, $this->getSupportedAttributes())) {
116-
return false;
117-
}
118-
119-
return true;
120-
}
121-
12289
/**
12390
* Return an array of supported classes. This will be called by supportsClass.
12491
*
12592
* @return array an array of supported classes, i.e. array('Acme\DemoBundle\Model\Product')
126-
*
127-
* @deprecated since version 2.8, to be removed in 3.0. Use supports() instead.
12893
*/
129-
protected function getSupportedClasses()
130-
{
131-
@trigger_error('The '.__METHOD__.' is deprecated since version 2.8 and will be removed in version 3.0.', E_USER_DEPRECATED);
132-
}
94+
abstract protected function getSupportedClasses();
13395

13496
/**
13597
* Return an array of supported attributes. This will be called by supportsAttribute.
13698
*
13799
* @return array an array of supported attributes, i.e. array('CREATE', 'READ')
138-
*
139-
* @deprecated since version 2.8, to be removed in 3.0. Use supports() instead.
140100
*/
141-
protected function getSupportedAttributes()
142-
{
143-
@trigger_error('The '.__METHOD__.' is deprecated since version 2.8 and will be removed in version 3.0.', E_USER_DEPRECATED);
144-
}
101+
abstract protected function getSupportedAttributes();
145102

146103
/**
147104
* Perform a single access check operation on a given attribute, object and (optionally) user
@@ -154,33 +111,7 @@ protected function getSupportedAttributes()
154111
* @param object $object
155112
* @param UserInterface|string $user
156113
*
157-
* @deprecated This method will be removed in 3.0 - override voteOnAttribute instead.
158-
*
159-
* @return bool
160-
*/
161-
protected function isGranted($attribute, $object, $user = null)
162-
{
163-
// forces isGranted() or voteOnAttribute() to be overridden
164-
throw new \BadMethodCallException(sprintf('You must override the voteOnAttribute() method in "%s".', get_class($this)));
165-
}
166-
167-
/**
168-
* Perform a single access check operation on a given attribute, object and token.
169-
* It is safe to assume that $attribute and $object's class pass supports method call.
170-
*
171-
* This method will become abstract in 3.0.
172-
*
173-
* @param string $attribute
174-
* @param object $object
175-
* @param TokenInterface $token
176-
*
177114
* @return bool
178115
*/
179-
protected function voteOnAttribute($attribute, $object, TokenInterface $token)
180-
{
181-
// the user should override this method, and not rely on the deprecated isGranted()
182-
@trigger_error(sprintf("The AbstractVoter::isGranted() method is deprecated since 2.8 and won't be called anymore in 3.0. Override voteOnAttribute() in %s instead.", get_class($this)), E_USER_DEPRECATED);
183-
184-
return $this->isGranted($attribute, $object, $token->getUser());
185-
}
116+
abstract protected function isGranted($attribute, $object, $user = null);
186117
}
Lines changed: 85 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,85 @@
1+
<?php
2+
3+
/*
4+
* This file is part of the Symfony package.
5+
*
6+
* (c) Fabien Potencier <[email protected]>
7+
*
8+
* For the full copyright and license information, please view the LICENSE
9+
* file that was distributed with this source code.
10+
*/
11+
12+
namespace Symfony\Component\Security\Core\Authorization\Voter;
13+
14+
use Symfony\Component\Security\Core\Authentication\Token\TokenInterface;
15+
16+
/**
17+
* Voter is an abstract default implementation of a voter.
18+
*
19+
* @author Roman Marintšenko <[email protected]>
20+
* @author Grégoire Pineau <[email protected]>
21+
*/
22+
abstract class Voter implements VoterInterface
23+
{
24+
/**
25+
* {@inheritdoc}
26+
*/
27+
public function supportsAttribute($attribute)
28+
{
29+
throw new \BadMethodCallException('supportsAttribute method is deprecated since version 2.8, to be removed in 3.0');
30+
}
31+
32+
/**
33+
* {@inheritdoc}
34+
*/
35+
public function supportsClass($class)
36+
{
37+
throw new \BadMethodCallException('supportsClass method is deprecated since version 2.8, to be removed in 3.0');
38+
}
39+
40+
/**
41+
* {@inheritdoc}
42+
*/
43+
public function vote(TokenInterface $token, $object, array $attributes)
44+
{
45+
// abstain vote by default in case none of the attributes are supported
46+
$vote = self::ACCESS_ABSTAIN;
47+
48+
foreach ($attributes as $attribute) {
49+
if (!$this->supports($attribute, $object)) {
50+
continue;
51+
}
52+
53+
// as soon as at least one attribute is supported, default is to deny access
54+
$vote = self::ACCESS_DENIED;
55+
56+
if ($this->voteOnAttribute($attribute, $object, $token)) {
57+
// grant access as soon as at least one attribute returns a positive response
58+
return self::ACCESS_GRANTED;
59+
}
60+
}
61+
62+
return $vote;
63+
}
64+
65+
/**
66+
* Determines if the attribute and subject are supported by this voter.
67+
*
68+
* @param string $attribute An attribute
69+
* @param mixed $subject The subject to secure, e.g. an object the user wants to access or any other PHP type
70+
*
71+
* @return bool True if the attribute and subject are supported, false otherwise
72+
*/
73+
abstract protected function supports($attribute, $subject);
74+
75+
/**
76+
* Perform a single access check operation on a given attribute, subject and token.
77+
*
78+
* @param string $attribute
79+
* @param mixed $subject
80+
* @param TokenInterface $token
81+
*
82+
* @return bool
83+
*/
84+
abstract protected function voteOnAttribute($attribute, $subject, TokenInterface $token);
85+
}

src/Symfony/Component/Security/Core/Tests/Authorization/Voter/AbstractVoterTest.php

Lines changed: 4 additions & 70 deletions
Original file line numberDiff line numberDiff line change
@@ -11,10 +11,11 @@
1111

1212
namespace Symfony\Component\Security\Core\Tests\Authorization\Voter;
1313

14-
use Symfony\Component\Security\Core\Authentication\Token\TokenInterface;
15-
use Symfony\Component\Security\Core\Authorization\Voter\AbstractVoter;
1614
use Symfony\Component\Security\Core\Authorization\Voter\VoterInterface;
1715

16+
/**
17+
* @group legacy
18+
*/
1819
class AbstractVoterTest extends \PHPUnit_Framework_TestCase
1920
{
2021
protected $token;
@@ -50,75 +51,8 @@ public function getTests()
5051
*/
5152
public function testVote(array $attributes, $expectedVote, $object, $message)
5253
{
53-
$voter = new AbstractVoterTest_Voter();
54+
$voter = new Fixtures\MyVoter();
5455

5556
$this->assertEquals($expectedVote, $voter->vote($this->token, $object, $attributes), $message);
5657
}
57-
58-
/**
59-
* @dataProvider getTests
60-
* @group legacy
61-
*/
62-
public function testVoteLegacy(array $attributes, $expectedVote, $object, $message)
63-
{
64-
$voter = new AbstractVoterTest_LegacyVoter();
65-
66-
$this->assertEquals($expectedVote, $voter->vote($this->token, $object, $attributes), $message);
67-
}
68-
69-
/**
70-
* @group legacy
71-
* @expectedException \BadMethodCallException
72-
*/
73-
public function testNoOverriddenMethodsThrowsException()
74-
{
75-
$voter = new AbstractVoterTest_NothingImplementedVoter();
76-
$voter->vote($this->token, new \stdClass(), array('EDIT'));
77-
}
78-
}
79-
80-
class AbstractVoterTest_Voter extends AbstractVoter
81-
{
82-
protected function voteOnAttribute($attribute, $object, TokenInterface $token)
83-
{
84-
return 'EDIT' === $attribute;
85-
}
86-
87-
protected function supports($attribute, $object)
88-
{
89-
return $object instanceof \stdClass && in_array($attribute, array('EDIT', 'CREATE'));
90-
}
91-
}
92-
93-
class AbstractVoterTest_LegacyVoter extends AbstractVoter
94-
{
95-
protected function getSupportedClasses()
96-
{
97-
return array('stdClass');
98-
}
99-
100-
protected function getSupportedAttributes()
101-
{
102-
return array('EDIT', 'CREATE');
103-
}
104-
105-
protected function isGranted($attribute, $object, $user = null)
106-
{
107-
return 'EDIT' === $attribute;
108-
}
109-
}
110-
111-
class AbstractVoterTest_NothingImplementedVoter extends AbstractVoter
112-
{
113-
protected function getSupportedClasses()
114-
{
115-
return array('stdClass');
116-
}
117-
118-
protected function getSupportedAttributes()
119-
{
120-
return array('EDIT', 'CREATE');
121-
}
122-
123-
// this is a bad voter that hasn't overridden isGranted or voteOnAttribute
12458
}

0 commit comments

Comments
 (0)