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

Skip to content

Commit 2fb4f3d

Browse files
committed
[Security] Add an abstract voter
1 parent a22a436 commit 2fb4f3d

File tree

5 files changed

+166
-4
lines changed

5 files changed

+166
-4
lines changed

UPGRADE-2.8.md

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -442,7 +442,7 @@ FrameworkBundle
442442
Security
443443
--------
444444
445-
* The AbstractToken::isGranted() method was deprecated. Instead,
445+
* The `AbstractVoter::isGranted()` method was deprecated. Instead,
446446
override the voteOnAttribute() method. This method has one small
447447
difference: it's passed the TokenInterface instead of the user:
448448

@@ -475,6 +475,8 @@ Security
475475
}
476476
```
477477

478+
* The `AbstractVoter` is deprecated. Use `Voter` instead.
479+
478480
Config
479481
------
480482

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

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,13 +11,18 @@
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+
16+
1417
use Symfony\Component\Security\Core\User\UserInterface;
1518
use Symfony\Component\Security\Core\Authentication\Token\TokenInterface;
1619

1720
/**
1821
* Abstract Voter implementation that reduces boilerplate code required to create a custom Voter.
1922
*
2023
* @author Roman Marintšenko <[email protected]>
24+
*
25+
* @deprecated since version 2.8, to be removed in 3.0. Upgrade to Symfony\Component\Security\Core\Authorization\Voter\Voter instead
2126
*/
2227
abstract class AbstractVoter implements VoterInterface
2328
{
@@ -92,7 +97,7 @@ public function vote(TokenInterface $token, $object, array $attributes)
9297
* This method will become abstract in 3.0.
9398
*
9499
* @param string $attribute An attribute
95-
* @param string $object The object to secure
100+
* @param object $object The object to secure
96101
*
97102
* @return bool True if the attribute and object is supported, false otherwise
98103
*/
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 Grégoire Pineau <[email protected]>
20+
*/
21+
abstract class Voter implements VoterInterface
22+
{
23+
/**
24+
* {@inheritdoc}
25+
*/
26+
public function supportsAttribute($attribute)
27+
{
28+
}
29+
30+
/**
31+
* {@inheritdoc}
32+
*/
33+
public function supportsClass($class)
34+
{
35+
}
36+
37+
/**
38+
* {@inheritdoc}
39+
*/
40+
public function vote(TokenInterface $token, $subject, array $attributes)
41+
{
42+
// abstain vote by default in case none of the attributes are supported
43+
$vote = self::ACCESS_ABSTAIN;
44+
45+
foreach ($attributes as $attribute) {
46+
if (!$this->supports($attribute, $subject)) {
47+
continue;
48+
}
49+
50+
// as soon as at least one attribute is supported, default is to
51+
// deny access
52+
$vote = self::ACCESS_DENIED;
53+
54+
if ($this->voteOnAttribute($attribute, $subject, $token)) {
55+
// grant access as soon as at least one voter returns a positive
56+
// response
57+
return self::ACCESS_GRANTED;
58+
}
59+
}
60+
61+
return $vote;
62+
}
63+
64+
/**
65+
* Determines if the attribute and subject are supported by this voter.
66+
*
67+
* @param string $attribute An attribute
68+
* @param string $subject The subject to secure
69+
*
70+
* @return bool True if the attribute and subject is supported, false otherwise
71+
*/
72+
abstract protected function supports($attribute, $subject);
73+
74+
/**
75+
* Perform a single access check operation on a given attribute, subject and
76+
* 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/Authorization/Voter/VoterInterface.php

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -53,10 +53,10 @@ public function supportsClass($class);
5353
* ACCESS_GRANTED, ACCESS_DENIED, or ACCESS_ABSTAIN.
5454
*
5555
* @param TokenInterface $token A TokenInterface instance
56-
* @param object|null $object The object to secure
56+
* @param mixed $subject The subject to secure
5757
* @param array $attributes An array of attributes associated with the method being invoked
5858
*
5959
* @return int either ACCESS_GRANTED, ACCESS_ABSTAIN, or ACCESS_DENIED
6060
*/
61-
public function vote(TokenInterface $token, $object, array $attributes);
61+
public function vote(TokenInterface $token, $subject, array $attributes);
6262
}
Lines changed: 70 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,70 @@
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\Tests\Authorization\Voter;
13+
14+
use Symfony\Component\Security\Core\Authentication\Token\TokenInterface;
15+
use Symfony\Component\Security\Core\Authorization\Voter\Voter;
16+
use Symfony\Component\Security\Core\Authorization\Voter\VoterInterface;
17+
18+
class VoterTest extends \PHPUnit_Framework_TestCase
19+
{
20+
protected $token;
21+
22+
protected function setUp()
23+
{
24+
$this->token = $this->getMock('Symfony\Component\Security\Core\Authentication\Token\TokenInterface');
25+
}
26+
27+
public function getTests()
28+
{
29+
return array(
30+
array(array('EDIT'), VoterInterface::ACCESS_GRANTED, new \stdClass(), 'ACCESS_GRANTED if attribute and class are supported and attribute grants access'),
31+
array(array('CREATE'), VoterInterface::ACCESS_DENIED, new \stdClass(), 'ACCESS_DENIED if attribute and class are supported and attribute does not grant access'),
32+
33+
array(array('DELETE', 'EDIT'), VoterInterface::ACCESS_GRANTED, new \stdClass(), 'ACCESS_GRANTED if one attribute is supported and grants access'),
34+
array(array('DELETE', 'CREATE'), VoterInterface::ACCESS_DENIED, new \stdClass(), 'ACCESS_DENIED if one attribute is supported and denies access'),
35+
36+
array(array('CREATE', 'EDIT'), VoterInterface::ACCESS_GRANTED, new \stdClass(), 'ACCESS_GRANTED if one attribute grants access'),
37+
38+
array(array('DELETE'), VoterInterface::ACCESS_ABSTAIN, new \stdClass(), 'ACCESS_ABSTAIN if no attribute is supported'),
39+
40+
array(array('EDIT'), VoterInterface::ACCESS_ABSTAIN, $this, 'ACCESS_ABSTAIN if class is not supported'),
41+
42+
array(array('EDIT'), VoterInterface::ACCESS_ABSTAIN, null, 'ACCESS_ABSTAIN if object is null'),
43+
44+
array(array(), VoterInterface::ACCESS_ABSTAIN, new \stdClass(), 'ACCESS_ABSTAIN if no attributes were provided'),
45+
);
46+
}
47+
48+
/**
49+
* @dataProvider getTests
50+
*/
51+
public function testVote(array $attributes, $expectedVote, $object, $message)
52+
{
53+
$voter = new AbstractVoterTest_Voter();
54+
55+
$this->assertEquals($expectedVote, $voter->vote($this->token, $object, $attributes), $message);
56+
}
57+
}
58+
59+
class AbstractVoterTest_Voter extends Voter
60+
{
61+
protected function voteOnAttribute($attribute, $object, TokenInterface $token)
62+
{
63+
return 'EDIT' === $attribute;
64+
}
65+
66+
protected function supports($attribute, $object)
67+
{
68+
return $object instanceof \stdClass && in_array($attribute, array('EDIT', 'CREATE'));
69+
}
70+
}

0 commit comments

Comments
 (0)