Alex Tech Adventures The webs best tutorials!

Welcome, Guest
Please Login or Register.    Lost Password?

Handling categories
(1 viewing) (1) Guest
Go to bottomPage: 1
TOPIC: Handling categories
#642
Handling categories 1 Year, 9 Months ago Karma: 0
Hi,

Like many others I enjoy the tutorials on this site, but once in a while I run into problems.

One of the problems I have now is having multiple categories for my guestbook. What it actually means is that I have multiple guestbooks and depending on what variable I find in the uri I will fetch the right messages. This works fine as long as I don't use any access control on it.

As you might have guessed: I would like to use access controls.

Now I wonder what would be the best way to do this.
I figured that I want to have the categories as resources so that I can link them in the DB to priveleges and roles.

But how to handle this the best way?
- Would I use assertions since it is controller specific
- Do I use acl helpers and see them as a layer beneath the controller (module:controller:category) which isn't valid for all controllers?

I've already got quite a bit of controlling to do in my action methods and would like to reduce this as much as possible (for example see my post at: alex-tech-adventures.com/forum/13-zend-f...?limit=6&start=6)

How would you approach this problem?

(thinking of it something like an acl helper would actually not be such a bad idea...)
Yorian
Junior Boarder
Posts: 29
graphgraph
User Offline Click here to see the profile of this user
The administrator has disabled public write access.
 
#643
Re:Handling categories 1 Year, 9 Months ago Karma: 0
I fixxed this using helpers, which are in fact some sort of controller specific extension of the Acl.
Yorian
Junior Boarder
Posts: 29
graphgraph
User Offline Click here to see the profile of this user
The administrator has disabled public write access.
 
#688
Re:Handling categories 1 Year, 7 Months ago Karma: 16
Never heard of ACL helper. Could you please give an example of what that involves?
alexanderrv
Administrator
Posts: 279
graph
User Offline Click here to see the profile of this user
Gender: Male tmthv2 alexchatonly@hotmail.com Location: Freeport, Bahamas Birthdate: 1989-04-14
The administrator has disabled public write access.
 
#690
Re:Handling categories 1 Year, 7 Months ago Karma: 0
It is not something ZF implements automatically, I build it myself. There are actually a couple of things I do to keep controllers as simple as possible, meaning: doing as little "non-controller" stuff in the controller itself. Therefor I moved controller specific things such as categories etc. to acl helpers instead of the controller.

My code:
bootstrap
Code:

protected function _initAccessCheck()
{
$this->_auth = Zend_Auth::getInstance();

if($this->_auth->hasIdentity()){
$usermapper = Model_Datamapper_User::getInstance();
$user = $usermapper->findById($this->_auth->getStorage()->read()->id);
$roles = $user->getRoles();
} else {
$role = new Model_Domain_Role();
$role->setId(1);
$role->setParentId(null);
$role->setRole('guest');
$roles = array(1 => $role);
}
Zend_Registry::set('userRoles', $roles);

$this->_acl = new Model_Acl();

$this->_frontController = Zend_Controller_Front::getInstance();
$this->_frontController->registerPlugin(new Plugin_uriAccessCheck($this->_acl));

Zend_Registry::set('acl', $this->_acl);
}



Plugin_uriAccessCheck
Code:

public function preDispatch(Zend_Controller_Request_Abstract $request){
$module = $request->getModuleName();
        $controller = $request->getControllerName();
        $resource = 'uri:' . $module . ':' . $controller; // constructed as follows: type:module:controller
        $action = $request->getActionName();
        
        $resource_registry = Model_ResourceRegistry::getInstance();
        $resource_registry->append($module . ':' . $controller, 'uri');
        
        $allowed = FALSE;
        $roles = Zend_Registry::get('userRoles');
        foreach($roles as $id => $role_data){
         if($this->_acl->isAllowed($role_data->getRole(), $resource, $action)){
         $allowed = TRUE;
         }
        }
        
        // alle helpers in de default module
        $helper_path = APPLICATION_PATH . DS . 'modules' . DS . 'default' . DS . 'models' . DS . 'Acl' . DS . 'Helper' . DS . 'Uri' . DS . ucfirst($module) . DS . ucfirst($controller) . '.php';
        $helper_class = 'Model_Acl_Helper_Uri_' . ucfirst($module) . '_' . ucfirst($controller);
        
        // let helper do extra checks (and is able to overwrite)
        if(file_exists($helper_path)){
         $helper = new $helper_class;
         $helper->setRequest($request);
         $helper->setAcl($this->_acl);
         $helper->setRoles($roles);
         $helper->appendResource(); // append resource if any so the list of resources is always clear
         $allowed = $helper->isAllowed();
        }
        
if(!$allowed){
Zend_Registry::set('Acl_Role_Allowed', FALSE);
}else{
Zend_Registry::set('Acl_Role_Allowed', TRUE);
}

$this->_acl->setDynamicPermissions($request);
}



Abstract helper
Code:



abstract class Model_Acl_Helper_Abstract {
protected $_acl = null;
protected $_request = null;
protected $_roles = null;

public function setAcl(Model_Acl $acl){
$this->_acl = $acl;
}

public function setRequest(Zend_Controller_Request_Abstract $request){
$this->_request = $request;
}

public function setRoles(array $roles){
$this->_roles = $roles;
}

abstract public function isAllowed();
abstract public function appendResource();
}



Guestbook helper
Code:



class Model_Acl_Helper_Uri_Default_guestbook extends Model_Acl_Helper_Abstract {

private $_category = null;

public function isAllowed(){
$allowed = FALSE;
$resource = 'guestbook:' . $this->_category;
        $action = $this->_request->getActionName();

foreach($this->_roles as $id => $role_data){
         if($this->_acl->isAllowed($role_data->getRole(), $resource, $action)){
         $allowed = TRUE;
         }
        }
        
        return $allowed;
}

public function appendResource(){
$category = $this->_request->getParam('category');
$this->_category = (empty($category) || !is_string($category) || strlen($category) < 1 || strlen($category) > 80) ? 'default' : $category;

$resource_registry = Model_ResourceRegistry::getInstance();
$resource_registry->append($this->_category, 'guestbook');
}
}



And finally, Set dynamic permissions in model Acl
Code:

public function setDynamicPermissions(Zend_Controller_Request_Abstract $request){
// OPMERKING:
// Dit werkt alleen voor het geval dat een gebruiker op zijn eigen resource een actie wilt uitvoeren (editten, deleten enzo)
// Dat voldoet in principe prima, maar de assertion wordt dus met de rol 'user' aangeroepen

// from request
$module = $request->getModuleName();
        $controller = $request->getControllerName();
        $request_resource = $module . ':' . $controller;
        $action = $request->getActionName();
        
        $assertion = FALSE;

$privelegemapper = Model_Datamapper_Privelege::getInstance();
$privelege = $privelegemapper->getPrivelegesByRequest($request_resource, $action);

// from DB
if(!empty($privelege) && is_a($privelege, 'Model_Domain_Privelege')){
$resource = $privelege->getResource();

if(file_exists(APPLICATION_PATH . DS . 'modules' . DS . $module . DS . 'models' . DS . 'Acl' . DS . 'Assertion' . DS . ucfirst($controller) . DS . ucfirst($action) . '.php')){
$prefix = ($module == 'default') ? '' : ucfirst($module) . '_';
$class_name = $prefix . 'Model_Acl_Assertion_' . ucfirst($controller) . '_' . ucfirst($action);
$this->allow('user', $resource->getType() . ':' . $resource->getResource(), $privelege->getPrivelege(), new $class_name);
$assertion = TRUE;
}
// Voorbeeld: $this->allow('user', 'administration:album', 'edit', new Administration_Model_Acl_Assertion_Album_Edit());
// Zou eventueel kunnen met null i.p.v. user?
}

if(!$assertion){
// make sure you don't always have to call Acl_Role_Allowed if there is no assertion
if(!Zend_Registry::get('Acl_Role_Allowed')){
     $redirector = Zend_Controller_Action_HelperBroker::getStaticHelper('redirector');
     if(Zend_Auth::getInstance()->hasIdentity()){
     $redirector->gotoUrl('/'); // unauthorized page
     }else{
     $_SESSION['redirect_location'] = $request->getRequestUri();
     $redirector->goToSimple('login', 'authentication', 'default');
     }
     }
}
}



As you can see, I removed all the not so very specific ACL rules. In case there still is a very specific case (such as editting a message by the user itself) I still do this in the action of the controller, but only need a few lines of code.
Yorian
Junior Boarder
Posts: 29
graphgraph
User Offline Click here to see the profile of this user
Last Edit: 2010/06/16 13:05 By alexanderrv.Reason: removed opening php so my stupid template can show the code properly
The administrator has disabled public write access.
 
#691
Re:Handling categories 1 Year, 7 Months ago Karma: 16
Clever!
I also like the idea of ResourceRegistry.
alexanderrv
Administrator
Posts: 279
graph
User Offline Click here to see the profile of this user
Gender: Male tmthv2 alexchatonly@hotmail.com Location: Freeport, Bahamas Birthdate: 1989-04-14
The administrator has disabled public write access.
 
Go to topPage: 1
Moderators: alexanderrv
You are here: Home Forum

Statistics

Members : 1388
Content : 42
Web Links : 1
Content View Hits : 190525

Poll

Interested in TinyBrowser and TinyMce plugin for ZF?
 

Who's Online

We have 41 guests online