access level management for module in zend framework - zend-framework

Isn't there acl order deny method for module. do i always have to add controller and index? i have an admin module and default module witch dozen controller in them and three dozen actions for them and it's really being wearisome
My code goes like this
class Management_Access extends Zend_Controller_Plugin_Abstract{
public function preDispatch(Zend_Controller_Request_Abstract $request)
{
// set up acl
$acl = new Zend_Acl();
// add the roles
$acl->addRole(new Zend_Acl_Role('guest'));
$acl->addRole(new Zend_Acl_Role('administrator'), 'guest');
// add the resources
$acl->add(new Zend_Acl_Resource('index'));
$acl->add(new Zend_Acl_Resource('error'));
$acl->add(new Zend_Acl_Resource('login'));
//admin resources
$acl->add(new Zend_Acl_Resource('destination'));
$acl->add(new Zend_Acl_Resource('home'));
$acl->add(new Zend_Acl_Resource('page'));
$acl->add(new Zend_Acl_Resource('tour'));
$acl->add(new Zend_Acl_Resource('hotel'));
isn't there a way to check if resource is registered in acl?
UPDATE::
i have eight controllers in my default module and nine controllers in 'admin' module.
i have index controller in admin module as well as in default module. if i add allow guest index, the guest is also able to access the index page in admin module. admin module is only set for administrator

Two possible solutions:
check current module in controller plugin ($request->getModuleName())
implement the logic in module bootstrap (only for module you need).
Edit after update:
You just need to treat modules+controllers as resources, and actions as privileges:
$acl->deny('guest', 'adminmodulename:controllername', array('tour', 'hotel'));
or for all:
$acl->deny('guest', 'adminmodulename:controllername');
isn't there a way to check if resource is registered in acl?
$acl->has($resource)

That's not a very specific question :)
Anyways... You will probably have to implement a user management yourself for ZF. But don't be afraid, there are tons of tutorials online! (e.g. here)
What do you mean by "do i always have to add controller and index?"?

I understand your question. I suggest you make your application modular. For the ACL just move it up as well (aka make your modules the resources)!
e.g.
// ROLES
$this->addRole(new Zend_Acl_Role('guest')); // default
$this->addRole(new Zend_Acl_Role('Marketing'), 'guest'); // 15
// RESOURCES (MY MODULES)
$this->add(new Zend_Acl_Resource('auth'));
$this->add(new Zend_Acl_Resource('takeon'));
// PRIVILEGES
//
// default
$this->deny();
//
// guest
$this->allow('guest', 'auth');
// 15 Marketing
$this->allow('Marketing', 'default');
$this->allow('Marketing', 'takeon', array('index', 'ben10cards'));
Then in your plugin use:
// OBTAIN CONTROL LIST
$acl = new Auth_Model_Acl();
// OBTAIN RESOURCE
$module = $request->getModuleName();
$controller = $request->getControllerName();
// VALIDATE
if ($acl->isAllowed($role, $module, $controller)) {
$allowed = true;
You might then not have resources available for actions, but works better for me :)

Related

Dealing with Zend Auth Data when using zend modules

I am working on zend module based structure for my project. As Zend_Auth class' default session storage is Zend_Auth. I changed according to module being called. Say for admin I use auth namespace Admin_Auth and for default module i use namespace name Default_Auth.
$auth = Zend_Auth::getInstance();
$auth->setStorage(new Zend_Auth_Storage_Session('Admin_Auth'));
I am doing this because, if I do Zend_Session::destroy() it will destroy complete session even for Default Module. and so using namespace and so at logout Zend_Session::namespaceUnset('Admin_Auth');
each time in different controller I have to use
$auth = Zend_Auth::getInstance();
$auth->setStorage(new Zend_Auth_Storage_Session('Admin_Auth'));
just to point corresponding session data.
I am considering to move it in module's Bootstrap.php like
protected function _initAuth(){
$auth = Zend_Auth::getInstance();
$auth->setStorage(new Zend_Auth_Storage_Session('Admin_Auth'));
return $auth;
}
First, is that proper way?
Second, If it is then how can I access the return value $auth of _initAuth() in each controller? Please

Zend ACL allow certain actions

How do I use the Zend ACL to allow access to certain users to some of the actions within a controller? Right now, I only know how to allow a user to access the whole controller, but I want to limit the actions within the controller!
To allow/deny access to certain actions, specify them in the allow/deny methods of Zend_Acl.
The third argument in the Zend_Acl::allow() method will only allow you to set access controls to certain actions on a given controller/resource. For example:
<?php
$acl = new Zend_Acl();
// Roles
$guest = new Zend_Acl_Role('guest');
$user = new Zend_Acl_Role('user');
// Register the roles with the Zend_Acl
$acl->addRole($guest);
$acl->addRole($user, 'guest');
// Resources/Controllers
$indexController = new Zend_Acl_Resource('index');
$profileController = new Zend_Acl_Resource('profile');
// Add resources/controllers to the Zend_Acl
$acl->add($indexController);
$acl->add($profileController);
// Now set limits of access to the resources.
// Guests get access to all the actions in the index controller,
// but to only the login and logout actions in the profile controller.
$acl->allow('guest', 'index');
$acl->allow('guest', 'profile', array('login', 'logout'));
// Users get full access to the profile controller
$acl->allow('user', 'profile');

Zend_Acl, Zend_Auth and Modules

I am trying to get around Zend_Acl but had no success so far. I need help as I am really stuck. My situation is this:
I have two modules
members
administrators
and two roles
member
admin
I set up an Zend_Auth with a login that gets to the members module both the member and admin role. Both can do some stuff here but the admin role can also have access to the 'administrators' module where can do more administrator stuff.
I set up an Acl as follow:
$acl = new Zend_Acl();
$acl->addRole(new Zend_Acl_Role('member'));
$acl->addRole(new Zend_Acl_Role('admin'), 'member');
$acl->add(new Zend_Acl_Resource('members'));
$acl->add(new Zend_Acl_Resource('administrators'), 'members');
$acl->allow('member', 'members');
$acl->allow('admin', 'administrators');
$registry = Zend_Registry::getInstance();
$registry->set('acl', $acl);
I have saved this file and I am calling it in the index.php page.
Assuming the what I have done so far is correct, my problem is what to do next? It is the first time I deal with Acl and honestly I am a bit confused about the all think works. Could you please help? Thank very much in advance.
You have constructed the ACL object. You need to use it now, every time you need to check whether the current user has access to one of the resources.
To do so, you need to retrieve your ACL object from the registry:
$acl = Zend_Registry::get('acl');
And then query it:
if ($acl->isAllowed($yourUser, 'members')) {
// Do the job
} else {
// some message or redirection
}
You can see more details in the Zend_Acl documentation.
Hope that helps,

How to Pass data/variables/objects to Zend_Controller_Plugin

I am converting an old ZF app (its using an early ZF version where we used to do manual app loading/config in the index.php) to latest version, and in one of the plugin we are sending data directly to the plugin constructor
$front->registerPlugin(new My_Plugin_ABC($obj1, $obj2))
Now in the current version we can register a plugin by directly providing the details in the application.ini and I want to stay with this approach(registering using config file). So while testing, I noticed the the plugin constructor is called fairly early in the bootstrapping, so the only option I am left with is using Zend_Registry to store the data, and retrieve it in the hooks. So is it the right way? or are there any other better ways
EDIT
The plugin was actually managing ACL and Auth, and its receiving custom ACL and AUTH objects. Its using the preDispatch hook.
Okay so you could consider you ACL and Auth handlers as a some application resources, and be able to add configuration options for them in you application.ini
//Create a Zend Application resource plugin for each of them
class My_Application_Resource_Acl extends Zend_Application_Resource_Abstract {
//notice the fact that a resource last's classname part is uppercase ONLY on the first letter (nobody nor ZF is perfect)
public function init(){
// initialize your ACL here
// you can get configs set in application.ini with $this->getOptions()
// make sure to return the resource, even if you store it in Zend_registry for a more convenient access
return $acl;
}
}
class My_Application_Resource_Auth extends Zend_Application_Resource_Abstract {
public function init(){
// same rules as for acl resource
return $auth;
}
}
// in your application.ini, register you custom resources path
pluginpaths.My_Application_Resource = "/path/to/My/Application/Resource/"
//and initialize them
resources.acl = //this is without options, but still needed to initialze
;resources.acl.myoption = myvalue // this is how you define resource options
resources.auth = // same as before
// remove you plugin's constructor and get the objects in it's logic instead
class My_Plugin_ABC extends Zend_Controller_Plugin_Abstract {
public function preDispatch (Zend_Controller_Request_Abstract $request){
//get the objects
$bootstrap = Zend_Controller_Front::getInstance()->getParam("bootstrap");
$acl = $bootstrap->getResource('acl');
$auth = $bootstrap->getResource('auth');
// or get them in Zend_Registry if you registered them in it
// do your stuff with these objects
}
}
Acl is needed so many other places hence storing it in Zend_Registry is cool thing to do and since Zend_Auth is singleton so you can access it $auth = Zend_Auth::getInstance() ; anywhere you like so no need for auth to be stored in registry .
Lastly if you have extended Zend_Acl class for your custom acl its better to make it also singleton . Then you can access acl My_Acl::getInstance(); where My_Acl is subclass of Zend_Acl .

setting different access for different module

I want set different access for different modules.
I tried out
$this->allow($role, $module, $controller, $action);
or
$this->allow($role, $module . ':' . $controller, $action);
But this does not seem to work.
Any ideas??
To setup acl correctly you need to define roles, resources and permissions.
E.g.
$this->addRole(new Zend_Acl_Role('guests'));
$this->add(new Zend_Acl_Resource('default'))
->add(new Zend_Acl_REsource('default:index'), 'default');
$this->allow('guests', 'default:index', array('index', 'error'));
This is a module based structure. So first you define a role. Then you define the module resource which is default. Index is the IndexController. And finally you set the actions that user of type guest should be able to access as array.
The second line of code in your question seems to be ok so there might be a problem anywhere else. Check out some resources:
Documentation: Zend_Acl
How To: Zend Framework 1.8 tutorial 5 zend_acl with zend_auth and controller plugin