Skip to content

Commit 186adc6

Browse files
committed
Updating AbstractVoter so that the method receives the TokenInterface
This fixes issues where people need this token.
1 parent 4d275b4 commit 186adc6

File tree

3 files changed

+106
-4
lines changed

3 files changed

+106
-4
lines changed

UPGRADE-2.8.md

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -406,3 +406,39 @@ FrameworkBundle
406406
session:
407407
cookie_httponly: false
408408
```
409+
410+
Security
411+
--------
412+
413+
* The AbstractToken::isGranted() method was deprecated. Instead,
414+
override the voteOnAttribute() method. This method has one small
415+
difference: it's passed the TokenInterface instead of the user:
416+
417+
Before:
418+
419+
```php
420+
class MyCustomVoter extends AbstractVoter
421+
{
422+
// ...
423+
424+
protected function isGranted($attribute, $object, $user = null)
425+
{
426+
// ...
427+
}
428+
}
429+
```
430+
431+
After:
432+
433+
```php
434+
class MyCustomVoter extends AbstractVoter
435+
{
436+
// ...
437+
438+
protected function voteOnAttribute($attribute, $object, TokenInterface $token)
439+
{
440+
$user = $token->getUser();
441+
// ...
442+
}
443+
}
444+
```

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

Lines changed: 39 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -65,6 +65,12 @@ public function vote(TokenInterface $token, $object, array $attributes)
6565
// abstain vote by default in case none of the attributes are supported
6666
$vote = self::ACCESS_ABSTAIN;
6767

68+
$reflector = new \ReflectionMethod($this, 'voteOnAttribute');
69+
$isNewOverwritten = $reflector->getDeclaringClass()->getName() !== 'Symfony\Component\Security\Core\Authorization\Voter\AbstractVoter';
70+
if (!$isNewOverwritten) {
71+
@trigger_error(sprintf("The AbstractVoter::isGranted method is deprecated since 2.8 and won't be called anymore in 3.0. Override voteOnAttribute() instead.", $reflector->class), E_USER_DEPRECATED);
72+
}
73+
6874
foreach ($attributes as $attribute) {
6975
if (!$this->supportsAttribute($attribute)) {
7076
continue;
@@ -73,9 +79,16 @@ public function vote(TokenInterface $token, $object, array $attributes)
7379
// as soon as at least one attribute is supported, default is to deny access
7480
$vote = self::ACCESS_DENIED;
7581

76-
if ($this->isGranted($attribute, $object, $token->getUser())) {
77-
// grant access as soon as at least one voter returns a positive response
78-
return self::ACCESS_GRANTED;
82+
if ($isNewOverwritten) {
83+
if ($this->voteOnAttribute($attribute, $object, $token)) {
84+
// grant access as soon as at least one voter returns a positive response
85+
return self::ACCESS_GRANTED;
86+
}
87+
} else {
88+
if ($this->isGranted($attribute, $object, $token->getUser())) {
89+
// grant access as soon as at least one voter returns a positive response
90+
return self::ACCESS_GRANTED;
91+
}
7992
}
8093
}
8194

@@ -107,7 +120,29 @@ abstract protected function getSupportedAttributes();
107120
* @param object $object
108121
* @param UserInterface|string $user
109122
*
123+
* @deprecated Override voteOnAttribute instead
110124
* @return bool
111125
*/
112-
abstract protected function isGranted($attribute, $object, $user = null);
126+
protected function isGranted($attribute, $object, $user = null)
127+
{
128+
return false;
129+
}
130+
131+
/**
132+
* Perform a single access check operation on a given attribute, object and (optionally) user
133+
* It is safe to assume that $attribute and $object's class pass supportsAttribute/supportsClass
134+
* $user can be one of the following:
135+
* a UserInterface object (fully authenticated user)
136+
* a string (anonymously authenticated user).
137+
*
138+
* @param string $attribute
139+
* @param object $object
140+
* @param TokenInterface $token
141+
*
142+
* @return bool
143+
*/
144+
protected function voteOnAttribute($attribute, $object, TokenInterface $token)
145+
{
146+
return false;
147+
}
113148
}

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

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111

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

14+
use Symfony\Component\Security\Core\Authentication\Token\TokenInterface;
1415
use Symfony\Component\Security\Core\Authorization\Voter\AbstractVoter;
1516

1617
/**
@@ -46,6 +47,16 @@ public function testVote($expectedVote, $object, $attributes, $message)
4647
$this->assertEquals($expectedVote, $this->voter->vote($this->token, $object, $attributes), $message);
4748
}
4849

50+
/**
51+
* @dataProvider getData
52+
*/
53+
public function testVoteUsingDeprecatedIsGranted($expectedVote, $object, $attributes, $message)
54+
{
55+
$voter = new DeprecatedVoterFixture();
56+
57+
$this->assertEquals($expectedVote, $voter->vote($this->token, $object, $attributes), $message);
58+
}
59+
4960
public function getData()
5061
{
5162
return array(
@@ -75,6 +86,26 @@ protected function getSupportedAttributes()
7586
return array('foo', 'bar', 'baz');
7687
}
7788

89+
protected function voteOnAttribute($attribute, $object, TokenInterface $token)
90+
{
91+
return $attribute === 'foo';
92+
}
93+
}
94+
95+
class DeprecatedVoterFixture extends AbstractVoter
96+
{
97+
protected function getSupportedClasses()
98+
{
99+
return array(
100+
'Symfony\Component\Security\Tests\Core\Authentication\Voter\ObjectFixture',
101+
);
102+
}
103+
104+
protected function getSupportedAttributes()
105+
{
106+
return array('foo', 'bar', 'baz');
107+
}
108+
78109
protected function isGranted($attribute, $object, $user = null)
79110
{
80111
return $attribute === 'foo';

0 commit comments

Comments
 (0)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy