Skip to content

Instantly share code, notes, and snippets.

@henrikbjorn
Created December 23, 2011 07:47
Show Gist options
  • Save henrikbjorn/1513514 to your computer and use it in GitHub Desktop.
Save henrikbjorn/1513514 to your computer and use it in GitHub Desktop.
<?php
namespace FooBar\FooBundle\Security\Authorization\Voter;
use Symfony\Component\Security\Core\Authentication\AuthenticationTrustResolverInterface;
use Symfony\Component\Security\Core\Authentication\Token\TokenInterface;
use Symfony\Component\Security\Core\Authorization\Voter\VoterInterface;
/**
* @author Henrik Bjornskov <henrik@bjrnskov.dk>
*/
class AnonymousVoter implements VoterInterface
{
/**
* The role check agains
*/
const IS_ANONYMOUS = 'IS_ANONYMOUS';
/**
* @var AuthenticationTrustResolverInterface $authenticationTrustResolver
*/
protected $authenticationTrustResolver;
/**
* @param AuthenticationTrustResolverInterface $authenticationTrustResolver
*/
public function __construct(AuthenticationTrustResolverInterface $authenticationTrustResolver)
{
$this->authenticationTrustResolver = $authenticationTrustResolver;
}
/**
* @param string $attribute
* @return Boolean
*/
public function supportsAttribute($attribute)
{
return static::IS_ANONYMOUS === $attribute;
}
/**
* @param string $class
* @return Boolean
*/
public function supportsClass($class)
{
return true;
}
/**
* Only allow access if the TokenInterface isAnonymous. But abstain from voting
* if the attribute IS_ANONYMOUS isnt supported.
*
* @param TokenInterface $token
* @param object $object
* @param array $attributes
* @return integer
*/
public function vote(TokenInterface $token, $object, array $attributes)
{
foreach ($attributes as $attribute) {
if (!$this->supportsAttribute($attribute)) {
continue;
}
// If the user is anonymous then grant access otherwise deny!
if ($this->authenticationTrustResolver->isAnonymous($token)) {
return VoterInterface::ACCESS_GRANTED;
}
return VoterInterface::ACCESS_DENIED;
}
return VoterInterface::ACCESS_ABSTAIN;
}
}
<?php
namespace FooBar\FooBundle\Tests\Security\Authorization\Voter;
use FooBar\FooBundle\Security\Authorization\Voter\AnonymousVoter;
use Symfony\Component\Security\Core\Authorization\Voter\VoterInterface;
/**
* @author Henrik Bjornskov <henrik@bjrnskov.dk>
*/
class AnonymousVoterTest extends \PHPUnit_Framework_TestCase
{
public function testSupportsClass()
{
$voter = new AnonymousVoter($this->createResolverMock());
$this->assertTrue($voter->supportsClass('stdClass'));
$this->assertTrue($voter->supportsClass('Just return true always'));
}
public function testSupportsAttribute()
{
$voter = new AnonymousVoter($this->createResolverMock());
$this->assertTrue($voter->supportsAttribute(AnonymousVoter::IS_ANONYMOUS));
$this->assertFalse($voter->supportsAttribute('ROLE_USER'));
$this->assertFalse($voter->supportsAttribute('IS_AUTHENTICATED_ANONYMOUSLY'));
}
public function testVote()
{
$token = $this->createTokenMock();
// Voter returns VoterInterface::ACCESS_ABSTAIN when its attribute isnt found
$voter = new AnonymousVoter($this->createResolverMock());
$this->assertEquals(VoterInterface::ACCESS_ABSTAIN, $voter->vote($token, new \stdClass, array()));
// Voter returns ACCESS_DENIED if token is not anonymous and our attribute is present
$this->assertEquals(VoterInterface::ACCESS_DENIED, $voter->vote($token, new \stdClass, array(
AnonymousVoter::IS_ANONYMOUS,
)));
// Voter returns ACCESS_GRANTED if the token is anonymous and our attribute is present
$voter = new AnonymousVoter($this->createResolverMock(true));
$this->assertEquals(VoterInterface::ACCESS_GRANTED, $voter->vote($token, new \stdClass, array(
AnonymousVoter::IS_ANONYMOUS,
)));
}
protected function createResolverMock($isAnonymous = false)
{
$resolver = $this->getMock('Symfony\Component\Security\Core\Authentication\AuthenticationTrustResolverInterface');
$resolver
->expects($this->any())
->method('isAnonymous')
->will($this->returnValue($isAnonymous))
;
return $resolver;
}
protected function createTokenMock()
{
return $this->getMock('Symfony\Component\Security\Core\Authentication\Token\TokenInterface');
}
}
<?xml version="1.0" ?>
<container xmlns="http://symfony.com/schema/dic/services"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://symfony.com/schema/dic/services http://symfony.com/schema/dic/services/services-1.0.xsd">
<parameters>
<parameter key="foobar.security.authorization.voter.anonymous.class">FooBar\FooBundle\Security\Authorization\Voter\AnonymousVoter</parameter>
</parameters>
<services>
<service id="security.access.anonymous.voter" class="%foobar.security.authorization.voter.anonymous.class%" public="false">
<tag name="security.voter" />
<argument type="service" id="security.authentication.trust_resolver" />
</service>
</services>
</container>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment