Content Driven Zend_Acl in the Model Layer

2,454 views
2,368 views

Published on

Most people use Zend_Acl to control access to certain controllers/actions. While this is good for most use cases, sometimes you need to go further. For example you can specify that a user has access to article/view, but you might also want to limit access to certain articles for certain roles.

Published in: Technology
0 Comments
7 Likes
Statistics
Notes
  • Be the first to comment

No Downloads
Views
Total views
2,454
On SlideShare
0
From Embeds
0
Number of Embeds
35
Actions
Shares
0
Downloads
82
Comments
0
Likes
7
Embeds 0
No embeds

No notes for slide















  • Content Driven Zend_Acl in the Model Layer

    1. 1. Content Driven ACL in the Model Layer
    2. 2. Jeroen Keppens e-mail jeroen@amazium.com twitter @amazium blog http://blog.amazium.com
    3. 3. Use Case • News site that serves articles, some are free others not. You need to be a subscriber to access them, or buy access to the article. • Users can be either visitors (registered, but no subscription) or subscribers • When an article is opened in the browser, the article needs to be displayed if the user can view it, otherwise show intro and BUY button.
    4. 4. Configuring ACL Defining roles, resources & rules
    5. 5. App_Acl_Acl class App_Acl_Acl extends Zend_Acl {     public function __construct()     {         // Roles         $this->addRole('visitor');         $this->addRole('subscriber', 'visitor');                  // Resourcess         $this->addResource('article');         $this->addResource('free-article', 'article');         $this->addResource('charged-article', 'article');                  // Access rules         $this->allow('subscriber', 'article');         $this->allow('visitor', 'free-article');         $this->allow('visitor', 'charged-article', null,  new App_Acl_Assert_UserOwned());     } }
    6. 6. App_Acl_Assert_UserOwned class App_Acl_Assert_UserOwned implements Zend_Acl_Assert_Interface {     public function assert(Zend_Acl $acl,                             Zend_Acl_Role_Interface $role = null,                             Zend_Acl_Resource_Interface $resource = null,                             $privilege = null)     {            // First we need a good Resource type         if (!$resource instanceof App_Model_UserOwnedInterface) {             throw new Exception('UserOwnedInterface not implemented');         }                  // Secondly, we need a authenticated user         $auth = Zend_Auth::getInstance();         if (!$auth->hasIdentity()) {             return false;         }         $user = new App_Model_User($auth->getIdentity());                  // Then do the check         /** @var App_Model_UserOwnedInterface $resource */         return $resource->isOwnedByUser($user);     } }
    7. 7. Model Layer Domain Logic
    8. 8. User Model • Implements Zend_Acl_Role_Interface • User can have a visitor or subscriber role • User has bought (owns) 0-n articles • 2 important functions: getRoleId() - user's role hasArticle() - did the user buy the article?
    9. 9. App_Model_User class App_Model_User implements Zend_Acl_Role_Interface { /* ... */ // Implementing Zend_Acl_Role_Interface     public function getRoleId()      {         return $this->_roleId;     } // Check if a user has bought an article         public function hasArticle($article)     {         if ($article instanceof App_Model_Article) {             $article = $article->getId();         }         return in_array($article, $this->getUserArticles());     } }
    10. 10. Article Model • Implements Zend_Acl_Resource_Interface • Implements App_Model_UserOwnedInterface • Article can be free-article or charged-article • 2 important functions: getResourceId() - article's resource id isOwnedByUser() - article bought by user?
    11. 11. App_Model_Article interface App_Model_UserOwnedInterface {     public function isOwnedByUser(App_Model_User $user); } class App_Model_Article implements Zend_Acl_Resource_Interface,  App_Model_UserOwnedInterface { /* ... */ // Implementing Zend_Acl_Resource_Interface     public function getResourceId()     {         if ($this->isFree()) {             return 'free-article';         } else {             return 'charged-article';         }     } // Implementing App_Model_UserOwnedInterface     public function isOwnedByUser(App_Model_User $user)     {         return $user->hasArticle($this);     } }
    12. 12. Checking ACL Can the role access the resource?
    13. 13. for ($j = 0; $j < count($users); $j++) {     // Make ZF think he has authenticated a user     Zend_Auth::getInstance()->getStorage()->write($users[$j]->toArray());     // Loop over the articles and check access     for ($i = 0; $i < count($articles); $i++) {         $access[] = array(             'user'    => $users[$j]->getUsername(),             'article' => $articles[$i]->getTitle(),             'allowed' => $acl->isAllowed($users[$j], $articles[$i])          );     } } • Authenticate user • Call isAllowed() for user & article
    14. 14. More info? Read the article below on my blog blog.amazium.com “Content-driven Access Control with Zend ACL” http://www.amazium.com/blog/content-driven-access-control-with-zend-acl
    15. 15. Thanks for listening Please rate the talk at http://joind.in/talk/view/

    ×