Skip to content

Commit

Permalink
Merge branch '5.0' into 5.1
Browse files Browse the repository at this point in the history
* 5.0:
  Fix test that fails on old distros
  Fix: compatibility with phpunit 9.3
  [DoctrineBridge] work around Connection::ping() deprecation
  [MimeType] Duplicated MimeType due to PHP Bug
  [DI] fix parsing of argument type=binary in xml
  fix guessing form types for DateTime types
  fix handling typed properties as constraint options
  Fix the 'supports' method argument type of the security voter
  Use the driverConnection executeUpdate method
  • Loading branch information
nicolas-grekas committed Jun 28, 2020
2 parents 7414e45 + 4e4c76f commit 18551ee
Show file tree
Hide file tree
Showing 2 changed files with 76 additions and 14 deletions.
17 changes: 15 additions & 2 deletions Authorization/Voter/Voter.php
Original file line number Diff line number Diff line change
Expand Up @@ -30,8 +30,21 @@ public function vote(TokenInterface $token, $subject, array $attributes)
$vote = self::ACCESS_ABSTAIN;

foreach ($attributes as $attribute) {
if (!$this->supports($attribute, $subject)) {
continue;
try {
if (!$this->supports($attribute, $subject)) {
continue;
}
} catch (\TypeError $e) {
if (\PHP_VERSION_ID < 80000) {
if (0 === strpos($e->getMessage(), 'Argument 1 passed to')
&& false !== strpos($e->getMessage(), '::supports() must be of the type string')) {
continue;
}
} elseif (false !== strpos($e->getMessage(), 'supports(): Argument #1')) {
continue;
}

throw $e;
}

// as soon as at least one attribute is supported, default is to deny access
Expand Down
73 changes: 61 additions & 12 deletions Tests/Authorization/Voter/VoterTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -27,34 +27,49 @@ protected function setUp(): void

public function getTests()
{
$voter = new VoterTest_Voter();
$integerVoter = new IntegerVoterTest_Voter();

return [
[['EDIT'], VoterInterface::ACCESS_GRANTED, new \stdClass(), 'ACCESS_GRANTED if attribute and class are supported and attribute grants access'],
[['CREATE'], VoterInterface::ACCESS_DENIED, new \stdClass(), 'ACCESS_DENIED if attribute and class are supported and attribute does not grant access'],
[$voter, ['EDIT'], VoterInterface::ACCESS_GRANTED, new \stdClass(), 'ACCESS_GRANTED if attribute and class are supported and attribute grants access'],
[$voter, ['CREATE'], VoterInterface::ACCESS_DENIED, new \stdClass(), 'ACCESS_DENIED if attribute and class are supported and attribute does not grant access'],

[$voter, ['DELETE', 'EDIT'], VoterInterface::ACCESS_GRANTED, new \stdClass(), 'ACCESS_GRANTED if one attribute is supported and grants access'],
[$voter, ['DELETE', 'CREATE'], VoterInterface::ACCESS_DENIED, new \stdClass(), 'ACCESS_DENIED if one attribute is supported and denies access'],

[$voter, ['CREATE', 'EDIT'], VoterInterface::ACCESS_GRANTED, new \stdClass(), 'ACCESS_GRANTED if one attribute grants access'],

[['DELETE', 'EDIT'], VoterInterface::ACCESS_GRANTED, new \stdClass(), 'ACCESS_GRANTED if one attribute is supported and grants access'],
[['DELETE', 'CREATE'], VoterInterface::ACCESS_DENIED, new \stdClass(), 'ACCESS_DENIED if one attribute is supported and denies access'],
[$voter, ['DELETE'], VoterInterface::ACCESS_ABSTAIN, new \stdClass(), 'ACCESS_ABSTAIN if no attribute is supported'],

[['CREATE', 'EDIT'], VoterInterface::ACCESS_GRANTED, new \stdClass(), 'ACCESS_GRANTED if one attribute grants access'],
[$voter, ['EDIT'], VoterInterface::ACCESS_ABSTAIN, $this, 'ACCESS_ABSTAIN if class is not supported'],

[['DELETE'], VoterInterface::ACCESS_ABSTAIN, new \stdClass(), 'ACCESS_ABSTAIN if no attribute is supported'],
[$voter, ['EDIT'], VoterInterface::ACCESS_ABSTAIN, null, 'ACCESS_ABSTAIN if object is null'],

[['EDIT'], VoterInterface::ACCESS_ABSTAIN, $this, 'ACCESS_ABSTAIN if class is not supported'],
[$voter, [], VoterInterface::ACCESS_ABSTAIN, new \stdClass(), 'ACCESS_ABSTAIN if no attributes were provided'],

[['EDIT'], VoterInterface::ACCESS_ABSTAIN, null, 'ACCESS_ABSTAIN if object is null'],
[$voter, [new StringableAttribute()], VoterInterface::ACCESS_GRANTED, new \stdClass(), 'ACCESS_GRANTED if attribute and class are supported and attribute grants access'],

[[], VoterInterface::ACCESS_ABSTAIN, new \stdClass(), 'ACCESS_ABSTAIN if no attributes were provided'],
[$voter, [new \stdClass()], VoterInterface::ACCESS_ABSTAIN, new \stdClass(), 'ACCESS_ABSTAIN if attributes were not strings'],

[$integerVoter, [42], VoterInterface::ACCESS_GRANTED, new \stdClass(), 'ACCESS_GRANTED if attribute is an integer'],
];
}

/**
* @dataProvider getTests
*/
public function testVote(array $attributes, $expectedVote, $object, $message)
public function testVote(VoterInterface $voter, array $attributes, $expectedVote, $object, $message)
{
$voter = new VoterTest_Voter();

$this->assertEquals($expectedVote, $voter->vote($this->token, $object, $attributes), $message);
}

public function testVoteWithTypeError()
{
$this->expectException('TypeError');
$this->expectExceptionMessage('Should error');
$voter = new TypeErrorVoterTest_Voter();
$voter->vote($this->token, new \stdClass(), ['EDIT']);
}
}

class VoterTest_Voter extends Voter
Expand All @@ -69,3 +84,37 @@ protected function supports(string $attribute, $object): bool
return $object instanceof \stdClass && \in_array($attribute, ['EDIT', 'CREATE']);
}
}

class IntegerVoterTest_Voter extends Voter
{
protected function voteOnAttribute($attribute, $object, TokenInterface $token): bool
{
return 42 === $attribute;
}

protected function supports($attribute, $object): bool
{
return $object instanceof \stdClass && \is_int($attribute);
}
}

class TypeErrorVoterTest_Voter extends Voter
{
protected function voteOnAttribute($attribute, $object, TokenInterface $token): bool
{
return false;
}

protected function supports($attribute, $object): bool
{
throw new \TypeError('Should error');
}
}

class StringableAttribute
{
public function __toString(): string
{
return 'EDIT';
}
}

0 comments on commit 18551ee

Please sign in to comment.