Skip to content
This repository was archived by the owner on Jan 30, 2020. It is now read-only.

Conversation

@nikolaposa
Copy link
Contributor

Intent

When setting up permissions for some application, there is a common use case of allowing some role to manipulate with resources owned by the user which has that certain role. For example, blog author should have permission to write new posts, but he/she should also have permission to modify his/her own posts, and not posts of other authors.

Solution

  • ProprietaryInterface - applicable to Resources and Roles. Provides information about the owner of some object. Used in conjunction with the OwnershipAssertion.
  • OwnershipAssertion - makes sure that some resource is owned by certain role, by comparing owners provided by the ProprietaryInterface implementations.

Use-case

Entities:

namespace MyApp\Entity;

use Zend\Permissions\Acl;

class User implements Acl\Role\RoleInterface, Acl\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 Acl\Resource\ResourceInterface, Acl\ProprietaryInterface
{
    public $author = null;

    public function getResourceId()
    {
        return 'blogPost';
    }

    public function getOwnerId()
    {
        if ($this->author === null) {
            return null;
        }

        return $this->author->getOwnerId();
    }
}

Usage example:

namespace MyApp;

use MyApp\Entity;
use Zend\Permissions\Acl;

$acl = new Acl\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 Acl\Assertion\OwnershipAssertion());
$acl->allow('admin');

$author1 = new User(1, 'author');
$author2 = new User(2, 'author');

$blogPost = new BlogPost();
$blogPost->author = $author1;

$acl->isAllowed($author1, 'blogPost', 'write'); //true
$acl->isAllowed($author1, $blogPost, 'edit'); //true
$acl->isAllowed($author2, 'blogPost', 'write'); //true
$acl->isAllowed($author2, $blogPost, 'edit'); //FALSE

@nikolaposa
Copy link
Contributor Author

Is there anything else I should do in order for this PR to be accepted? Any other comments?

@weierophinney weierophinney added this to the 2.7.0 milestone May 1, 2018
weierophinney added a commit that referenced this pull request May 1, 2018
Based on the wonderful issue description!
weierophinney added a commit that referenced this pull request May 1, 2018
weierophinney added a commit that referenced this pull request May 1, 2018
@weierophinney
Copy link
Member

Thanks, @nikolaposa! I have created documentation for the feature during merge, and this will release with 2.7.0.

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants