This is what I came up with. Basically overrode the parent vote() method, adding the check for roles within it. The role check concerns me a bit since it isn't using any of the built in method, but I'm not sure they're accessible and that it won't create a loop (since role checking uses a voter as well). I've tagged the parts that are custom.
Let me know if anything is a big no no.
<?php
// src/AppBundle/Security/Authorization/Voter/PostVoter.php
namespace AppBundle\Security\Authorization\Voter;
use Symfony\Component\Security\Core\Authorization\Voter\AbstractVoter;
use Symfony\Component\Security\Core\User\UserInterface;
use Symfony\Component\Security\Core\Authentication\Token\TokenInterface;
class PostVoter extends AbstractVoter
{
const VIEW = 'view';
const EDIT = 'edit';
/**
* {@inheritDoc}
*/
public function vote(TokenInterface $token, $object, array $attributes)
{
if (!$object || !$this->supportsClass(get_class($object))) {
return self::ACCESS_ABSTAIN;
}
// ----------------------------------
// -- start – custom
$user = $token->getUser();
if ($user instanceof UserInterface) {
if (in_array('ROLE_SUPER_ADMIN', $user->getRoles())) {
return self::ACCESS_GRANTED;
}
}
// -- end – custom
// ----------------------------------
// abstain vote by default in case none of the attributes are supported
$vote = self::ACCESS_ABSTAIN;
foreach ($attributes as $attribute) {
if (!$this->supportsAttribute($attribute)) {
continue;
}
// as soon as at least one attribute is supported, default is to deny access
$vote = self::ACCESS_DENIED;
if ($this->isGranted($attribute, $object, $token->getUser())) {
// grant access as soon as at least one voter returns a positive response
return self::ACCESS_GRANTED;
}
}
return $vote;
}
// ----------------------------------
// -- start – custom
protected function isGranted($attribute, $post, $user = null)
{
switch($attribute) {
case self::VIEW:
if ($post->getIsActive()) {
return true;
}
break;
// must be owned by the current user or the user must be a super admin
case self::EDIT:
// make sure there is a user object (i.e. that the user is logged in)
if (!$user instanceof UserInterface) {
return false;
}
if ($user->getId() === $post->getOwner()->getId()) {
return true;
}
break;
}
return false;
}
// -- end – custom
// ----------------------------------
protected function getSupportedAttributes()
{
return array(self::VIEW, self::EDIT);
}
protected function getSupportedClasses()
{
return array('AppBundle\Entity\Post');
}
}