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

Skip to content

[Security] allow arbitrary types in VoterInterface::vote() #16754

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Nov 30, 2015
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions UPGRADE-3.0.md
Original file line number Diff line number Diff line change
Expand Up @@ -615,6 +615,10 @@ UPGRADE FROM 2.x to 3.0

### Security

* The `vote()` method from the `VoterInterface` was changed to now accept arbitrary
types and not only objects. You can rely on the new abstract `Voter` class introduced
in 2.8 to ease integrating your own voters.

* The `Resources/` directory was moved to `Core/Resources/`

* The `key` settings of `anonymous`, `remember_me` and `http_digest` are
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ public function __construct(AuthenticationTrustResolverInterface $authentication
/**
* {@inheritdoc}
*/
public function vote(TokenInterface $token, $object, array $attributes)
public function vote(TokenInterface $token, $subject, array $attributes)
{
$result = VoterInterface::ACCESS_ABSTAIN;
foreach ($attributes as $attribute) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@ public function addExpressionLanguageProvider(ExpressionFunctionProviderInterfac
/**
* {@inheritdoc}
*/
public function vote(TokenInterface $token, $object, array $attributes)
public function vote(TokenInterface $token, $subject, array $attributes)
{
$result = VoterInterface::ACCESS_ABSTAIN;
$variables = null;
Expand All @@ -62,7 +62,7 @@ public function vote(TokenInterface $token, $object, array $attributes)
}

if (null === $variables) {
$variables = $this->getVariables($token, $object);
$variables = $this->getVariables($token, $subject);
}

$result = VoterInterface::ACCESS_DENIED;
Expand All @@ -74,7 +74,7 @@ public function vote(TokenInterface $token, $object, array $attributes)
return $result;
}

private function getVariables(TokenInterface $token, $object)
private function getVariables(TokenInterface $token, $subject)
{
if (null !== $this->roleHierarchy) {
$roles = $this->roleHierarchy->getReachableRoles($token->getRoles());
Expand All @@ -85,16 +85,16 @@ private function getVariables(TokenInterface $token, $object)
$variables = array(
'token' => $token,
'user' => $token->getUser(),
'object' => $object,
'object' => $subject,
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The object variable should probably be renamed to subject too. But that should be done in 2.8 and we should throw a deprecation when accessing object. Would that actually be possible?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Adding subject along side object in 2.8 is a good idea. Throwing a deprecation notice is possible, but not trivial.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Okay, renamed object to subject here and introduced a new subject variable in #16755.

'roles' => array_map(function ($role) { return $role->getRole(); }, $roles),
'trust_resolver' => $this->trustResolver,
);

// this is mainly to propose a better experience when the expression is used
// in an access control rule, as the developer does not know that it's going
// to be handled by this voter
if ($object instanceof Request) {
$variables['request'] = $object;
if ($subject instanceof Request) {
$variables['request'] = $subject;
}

return $variables;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ public function __construct($prefix = 'ROLE_')
/**
* {@inheritdoc}
*/
public function vote(TokenInterface $token, $object, array $attributes)
public function vote(TokenInterface $token, $subject, array $attributes)
{
$result = VoterInterface::ACCESS_ABSTAIN;
$roles = $this->extractRoles($token);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,20 +24,20 @@ abstract class Voter implements VoterInterface
/**
* {@inheritdoc}
*/
public function vote(TokenInterface $token, $object, array $attributes)
public function vote(TokenInterface $token, $subject, array $attributes)
{
// abstain vote by default in case none of the attributes are supported
$vote = self::ACCESS_ABSTAIN;

foreach ($attributes as $attribute) {
if (!$this->supports($attribute, $object)) {
if (!$this->supports($attribute, $subject)) {
continue;
}

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

if ($this->voteOnAttribute($attribute, $object, $token)) {
if ($this->voteOnAttribute($attribute, $subject, $token)) {
// grant access as soon as at least one attribute returns a positive response
return self::ACCESS_GRANTED;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,10 +31,10 @@ interface VoterInterface
* ACCESS_GRANTED, ACCESS_DENIED, or ACCESS_ABSTAIN.
*
* @param TokenInterface $token A TokenInterface instance
* @param object|null $object The object to secure
* @param mixed $subject The subject to secure
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this is a BC break for existing voters, as they must now be written in a way accepting any kind of value here, not just object|null. So if we do it, we must document it as a BC break.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, that BC break is intended so that the interface actually allows to be used like the new Voter class introduced in 2.8.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

and by the way, it's added to the upgrade file

* @param array $attributes An array of attributes associated with the method being invoked
*
* @return int either ACCESS_GRANTED, ACCESS_ABSTAIN, or ACCESS_DENIED
*/
public function vote(TokenInterface $token, $object, array $attributes);
public function vote(TokenInterface $token, $subject, array $attributes);
}