Skip to content
This repository was archived by the owner on May 31, 2024. It is now read-only.

Commit 3bc433a

Browse files
lyrixxnicolas-grekas
authored andcommitted
[Security] Deprecate "AbstractVoter" in favor of "Voter"
1 parent 59f1711 commit 3bc433a

File tree

2 files changed

+155
-0
lines changed

2 files changed

+155
-0
lines changed

Core/Authorization/Voter/Voter.php

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 <fabien@symfony.com>
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 <inoryy@gmail.com>
20+
* @author Grégoire Pineau <lyrixx@lyrixx.info>
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+
}
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 <fabien@symfony.com>
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 VoterTest_Voter();
54+
55+
$this->assertEquals($expectedVote, $voter->vote($this->token, $object, $attributes), $message);
56+
}
57+
}
58+
59+
class VoterTest_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)