A free and open-source book on ZF3 for beginners


17.4. Introduction to Dynamic Assertions

You might notice that for the Blog example we had two "special" permissions named post.own.edit and post.own.publish. Those permissions are special, because they allow the author to edit only the posts he is the creator of.

To "check" such permission against the real user, we need to additionally determine if the post really belongs to that user. This is called a dynamic assertion.

In the Role Demo website, we also will have a special permission called profile.own.view. What makes it special is that it allows the user to view a profile the user is the owner of.

To implement dynamic assertions in the Role Demo sample, we will use a special service called the assertion manager. This assertion manager will be implemented as the RbacAssertionManager class, which lives in the Application\Service namespace and looks like the following:

<?php
namespace Application\Service;

use Zend\Permissions\Rbac\Rbac;
use User\Entity\User;

/**
 * This service is used for invoking user-defined RBAC dynamic assertions.
 */
class RbacAssertionManager
{
    /**
     * Entity manager.
     * @var Doctrine\ORM\EntityManager 
     */
    private $entityManager;
    
    /**
     * Auth service.
     * @var Zend\Authentication\AuthenticationService 
     */
    private $authService;
    
    /**
     * Constructs the service.
     */
    public function __construct($entityManager, $authService) 
    {
        $this->entityManager = $entityManager;
        $this->authService = $authService;
    }
    
    /**
     * This method is used for dynamic assertions. 
     */
    public function assert(Rbac $rbac, $permission, $params)
    {
        $currentUser = $this->entityManager->getRepository(User::class)
                ->findOneByEmail($this->authService->getIdentity());
        
        if ($permission=='profile.own.view' && $params['user']->getId()==$currentUser->getId())
            return true;
        
        return false;
    }
}

As you can see from the code above, the class has the assert() method which accepts three arguments:

Inside the assert() method, we can get the currently logged in user and compare it with the user passed, this way we can return true if the user is trying to open its own profile; otherwise false.

In theory, you can have many assertion managers in your website (for example, if your Blog module has some dynamic assertions, you can create and register an assertion manager for that module).


Top