To query RbacManager
inside of controllers and view templates, we need to create a
special controller plugin (which we will name Access
) and a special view helper (which we will name
Access
too).
Sometimes it is required to check some permission inside the controller. For example, this is needed
for the profile.own.view
permission, which uses the dynamic assertion. For this purpose, we will
create the Access
controller plugin.
The plugin code will be located inside the AccessPlugin.php
file inside the Controller/Plugin directory
of the User module's source directory:
<?php
namespace User\Controller\Plugin;
use Zend\Mvc\Controller\Plugin\AbstractPlugin;
/**
* This controller plugin is used for role-based access control (RBAC).
*/
class AccessPlugin extends AbstractPlugin
{
private $rbacManager;
public function __construct($rbacManager)
{
$this->rbacManager = $rbacManager;
}
/**
* Checks whether the currently logged in user has the given permission.
* @param string $permission Permission name.
* @param array $params Optional params (used only if an assertion is associated with permission).
*/
public function __invoke($permission, $params = [])
{
return $this->rbacManager->isGranted(null, $permission, $params);
}
}
The Access
plugin's factory looks like the following:
<?php
namespace User\Controller\Plugin\Factory;
use Interop\Container\ContainerInterface;
use Zend\ServiceManager\Factory\FactoryInterface;
use User\Service\RbacManager;
use User\Controller\Plugin\AccessPlugin;
/**
* This is the factory for AccessPlugin. Its purpose is to instantiate the plugin
* and inject dependencies into its constructor.
*/
class AccessPluginFactory implements FactoryInterface
{
public function __invoke(ContainerInterface $container, $requestedName, array $options = null)
{
$rbacManager = $container->get(RbacManager::class);
return new AccessPlugin($rbacManager);
}
}
The plugin is registered inside the module.config.php file as follows:
// We register module-provided controller plugins under this key.
'controller_plugins' => [
'factories' => [
Controller\Plugin\AccessPlugin::class => Controller\Plugin\Factory\AccessPluginFactory::class,
],
'aliases' => [
'access' => Controller\Plugin\AccessPlugin::class,
],
],
So, in your controller's action, you can easily call this plugin like the following:
if (!$this->access('profile.own.view', ['user'=>$user])) {
return $this->redirect()->toRoute('not-authorized');
}
Sometimes, it may be required to query the RbacManager
inside a view template. For example,
you may need to hide or show some HTML block based on current user's permissions. To do that,
we will implement the Access
view helper.
The view helper's code will be located inside the Access.php
file inside the View/Helper directory
of the User module's source directory:
<?php
namespace User\View\Helper;
use Zend\View\Helper\AbstractHelper;
/**
* This view helper is used to check user permissions.
*/
class Access extends AbstractHelper
{
private $rbacManager = null;
public function __construct($rbacManager)
{
$this->rbacManager = $rbacManager;
}
public function __invoke($permission, $params = [])
{
return $this->rbacManager->isGranted(null, $permission, $params);
}
}
The Access
view helper's factory looks like the following:
<?php
namespace User\View\Helper\Factory;
use Interop\Container\ContainerInterface;
use Zend\ServiceManager\Factory\FactoryInterface;
use User\Service\RbacManager;
use User\View\Helper\Access;
/**
* This is the factory for Access view helper. Its purpose is to instantiate the helper
* and inject dependencies into its constructor.
*/
class AccessFactory implements FactoryInterface
{
public function __invoke(ContainerInterface $container, $requestedName, array $options = null)
{
$rbacManager = $container->get(RbacManager::class);
return new Access($rbacManager);
}
}
The view helper is registered inside the module.config.php config file as follows:
// We register module-provided view helpers under this key.
'view_helpers' => [
'factories' => [
View\Helper\Access::class => View\Helper\Factory\AccessFactory::class,
],
'aliases' => [
'access' => View\Helper\Access::class,
],
],
So, you can easily call the view helper from any of your view templates as follows:
if ($this->access('profile.own.view, ['user'=>$user]))) {
// do something...
}