I'm trying to create a custom voter to check access on entities for specific actions. So the logic for that is working fine. But then I have some actions that are allowed if the user is either the "owner" of that entity, or they are an admin.
However, I can't just check the ROLE of the user because I'm looking at the role hierarchy. The example in the docs for this just uses in_array
, but that won't work (http://symfony.com/doc/current/best_practices/security.html)
My voter is like this (shortened for clarity). I've tried injecting the security context (or specifically AuthorizationCheckerInterface in 2.6), but that has a circular dependency since this is a voter.
<?php
// ...
class ApplicationVoter extends AbstractVoter
{
const VIEW = 'view';
/**
* @var AuthorizationCheckerInterface
*/
private $security;
/*public function __construct(AuthorizationCheckerInterface $security)
{
$this->security = $security;
}*/
/**
* {@inheritdoc}
*/
protected function getSupportedAttributes()
{
return array(
self::VIEW
);
}
/**
* {@inheritdoc}
*/
protected function getSupportedClasses()
{
return array('Study\MainBundle\Entity\Application');
}
/**
* {@inheritdoc}
*/
protected function isGranted($attribute, $application, $user = null)
{
if (!$user instanceof UserInterface) {
return false;
}
if ($attribute === self::VIEW) {
return $this->canView($application, $user);
}
return false;
}
/**
* Can view own application if not deleted
* Admin can view if submitted
*
* @param \Study\MainBundle\Entity\Application $application
* @param \Study\MainBundle\Entity\User $user
*
* @return boolean
*/
protected function canView(Application $application, User $user)
{
return ($application->isOwner($user) && !$application->isDeleted())
|| (!$application->isHiddenToAdmin() && $this->security->isGranted('ROLE_ADMIN_RO'));
}
}
I'd like to just use the built-in RoleHiearchyVoter here, but it's a non-public service. Is there some solution for this? I'd like to avoid duplicating framework code or making my roles more complicated than just strings if possible.
EDIT: Injecting the whole container works, but isn't my ideal solution. Is that the only way I can access the built-in hierarchy from a voter?