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
Related
I've got Backpack for Laravel installed and have been using it for some time as an admin back end on a project. I'm also using the spatie/permission module (might come with Backpack, can't remember) to create users for the front end.
Currently, all users are able to access both front end and back end regardless of the group they belong to. I'd like to change that so that only members in an "admin" group are able to access the back end. I've followed the instructions here for separating front end and back end sessions but that's not really what I want as all users are still able to access both sites of the project.
I'm guessing I need to add a guard to the CRUD routes but I'm finding it to be much harder than it should be. Any pointers on how to do this would be greatly appreciated. TIA.
You can create a new middleware and use it in your routes group for admin routes.
To create a new middleware use the php artisan command like so: (you can name the new middleware what ever you want:
php artisan make:middleware RequireAdminRole
Now, inside your new middleware, on the handle function you can have something like this that returns a 403 Forbidden error message:
public function handle($request, Closure $next)
{
$user = auth()->user();
if (!$user) return $next($request);
if (!$user->hasRole('Admin'))
{
// if your sessions are decoupled from the frontend
// you can even logout the user like so:
// auth()->logout();
abort(403, 'Access denied');
}
return $next($request);
}
Here we are using the hasRole method, but there are more that you can use. See the spatie/laravel-permissions documentation for more info.
Now, let's assign this middleware a 'name' so we can use it in our route groups for the admin. Inside the App\Kernel.php file, in the end, inside the $routeMiddleware array add it and give it a new, for example:
'isadmin' => \App\Http\Middleware\RequireAdminRole::class,
And finally, you can add this middleware to your admin routes group (which should be in custom.php file if you're using latest backpack 3.4 version) :
Route::group([
'prefix' => 'admin',
'middleware' => ['web', 'isadmin', config('backpack.base.middleware_key', 'admin')],
'namespace' => 'App\Http\Controllers\Admin',
], function () {
// your routes are here
});
Now all your requests to the admin routes should be protected by the user role check.
Please let us know how it went for you, and if you encountered any issues.
Best regards,
~Cristian
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
I am trying to create a method inside a doctrine 2 entity in zend framework. It is just to keep the code DRY. I want to retrieve the user object if they are logged in, and FALSE other wise:
public function getCurrentUserId() {
//returns false if not logged in, user object otherwise
$auth = Zend_Auth::getInstance();
$id = $auth->getidentity();
$user = $this->_em->getRepository('Entities\User')
->findOneByid($id);
if (is_null($user))
return false;
else
return $user;
}
}
This works fine within a controller action, but causes the following error here:
PHP Fatal error: Doctrine\Common\ClassLoader::loadClass(): Failed opening required '/var/www/myswap/application/models/Repositories/Zend_Auth.php'
Why, and how can I avoid this?
I'm going to take a guess and assume you're using namespaces since it looks like that.
On the line where you use Zend_Auth, prefix it with a \ - eg. $auth = \Zend_Auth::getInstance();
The reason for this is that namespaces in PHP are relative. Thus, if you try to use just Zend_Auth it assumes you want an object in the current namespace. By prefixing it with a \, you're telling it you want Zend_Auth from root.
I'd suggest familiarizing yourself with the namespaces manual page
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,
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 :)