On this page
Reference
Ownership Assertions
Available since version 2.7.0
When setting up permissions for an application, site owners common will want to allow roles to manipulate resources owned by the user with that role. For example, a blog author should have permission to write new posts, and also to modify his or her own posts, but not posts of other authors.
To accomodate this use case, we provide two interfaces:
-
Laminas\Acl\ProprietaryInterface
is applicable to resources and roles. It provides information about the owner of an object. Objects implementing this interface are used in conjunction with theOwnershipAssertion
. -
Laminas\Acl\Assertion\OwnershipAssertion
ensures that a resource is owned by a specific role by comparing it to owners provided byProprietaryInterface
implementations.
Example
Consider the following entities:
namespace MyApp\Entity;
use Laminas\Permissions\Acl\ProprietaryInterface;
use Laminas\Permissions\Acl\Resource\ResourceInterface;
use Laminas\Permissions\Acl\Role\RoleInterface;
class User implements RoleInterface, ProprietaryInterface
{
protected $id;
protected $role = 'guest';
public function __construct($id, $role)
{
$this->id = $id;
$this->role = $role;
}
public function getRoleId()
{
return $this->role;
}
public function getOwnerId()
{
return $this->id;
}
}
class BlogPost implements ResourceInterface, ProprietaryInterface
{
public $author = null;
public function getResourceId()
{
return 'blogPost';
}
public function getOwnerId()
{
if ($this->author === null) {
return null;
}
return $this->author->getOwnerId();
}
}
The User
marks itself as an owner by implementing ProprietaryInterface
;
its getOwnerId()
method will return the user identifier provided during
instantiation.
A BlogPost
marks itself as a resource and an owner by also implementing
ProprietaryInterface
; in its case, it returns the author identifier, if
present, but null
otherwise.
Now let's wire these up into an ACL:
namespace MyApp;
use MyApp\Entity;
use Laminas\Permissions\Acl\Acl;
use Laminas\Permissions\Acl\Assertion\OwnershipAssertion;
$acl = new Acl();
$acl->addRole('guest');
$acl->addRole('member', 'guest');
$acl->addRole('author', 'member');
$acl->addRole('admin');
$acl->addResource('blogPost');
$acl->addResource('comment');
$acl->allow('guest', 'blogPost', 'view');
$acl->allow('guest', 'comment', array('view', 'submit'));
$acl->allow('author', 'blogPost', 'write');
$acl->allow('author', 'blogPost', 'edit', new OwnershipAssertion());
$acl->allow('admin');
$author1 = new User(1, 'author');
$author2 = new User(2, 'author');
$blogPost = new BlogPost();
$blogPost->author = $author1;
The takeaways from the above should be:
- An
author
can write blog posts, and edit posts it owns. $author1
and$author2
are both authors.$author1
is the author of$blogPost
.
Knowing these facts, we can expect the following assertion results:
$acl->isAllowed($author1, 'blogPost', 'write'); // true
$acl->isAllowed($author1, $blogPost, 'edit'); // true
$acl->isAllowed($author2, 'blogPost', 'write'); // true
$acl->isAllowed($author2, $blogPost, 'edit'); // false