Magento ACL Permissions are used with the admin area and check to see whether a user has permission to access a particular area.
Within the preDispatch()
method of the Mage_Adminhtml_Controller_Action
class, a call to the _isAllowed()
method is made.
if ($this->getRequest()->isDispatched() && $this->getRequest()->getActionName() !== 'denied' && !$this->_isAllowed()) { $this->_forward('denied'); $this->setFlag('', self::FLAG_NO_DISPATCH, true); return $this; }
protected function _isAllowed() { return Mage::getSingleton('admin/session')->isAllowed('admin'); }
The isAllowed()
method is usually overridden in module’s individual controller file, such as the ProductController.php
file.
protected function _isAllowed() { return Mage::getSingleton('admin/session')->isAllowed('catalog/products'); }
The catalog/products
is a parameter that gets passed in as the $resource
within the isAllowed()
method of the Mage_Admin_Model_Session
class.
public function isAllowed($resource, $privilege = null) { $user = $this->getUser(); $acl = $this->getAcl(); if ($user && $acl) { if (!preg_match('/^admin/', $resource)) { $resource = 'admin/' . $resource; } try { return $acl->isAllowed($user->getAclRole(), $resource, $privilege); } catch (Exception $e) { try { if (!$acl->has($resource)) { return $acl->isAllowed($user->getAclRole(), null, $privilege); } } catch (Exception $e) { } } } return false; }
We then load the user and ACL configuration.
A check if made to see if the $resource
variable contains the admin
string and if it doesn’t, we add it at the front of our resource. For example, the catalog product resource, catalog/products
, becomes admin/catalog/products
.
We then delegate to the isAllowed()
method, passing in the user’s ACL role, the resource and any privileges that have been set. Firstly, we need to get the user’s ACL role.
public function getAclRole() { return 'U' . $this->getUserId(); }
We can then proceed to the isAllowed()
method in the Zend_Acl
class. We won’t go into this library class in detail, but Magento makes use of this class to help validate users permissions within the admin area.
So how do we set up ACL permissions? For this, we’ll need to create a custom module. To start with, set up the module declaration file:
<?xml version="1.0"?> <config> <modules> <Custom_Acl> <codePool>local</codePool> <active>true</active> </Custom_Acl> </modules> </config>
Our config.xml
should look like the below example to start with. The ACL permissions will be added shortly.
<?xml version="1.0"?> <config> <global> <helpers> <acl> <class>Custom_Acl_Helper</class> </acl> </helpers> </global> <admin> <routers> <adminhtml> <args> <modules> <Custom_Acl after="Mage_Adminhtml">Custom_Acl</Custom_Acl> </modules> </args> </adminhtml> </routers> </admin> </config>
We then should add a helper file.
<?php class Custom_Acl_Helper_Data extends Mage_Core_Helper_Abstract { }
Our adminhtml.xml
file consists of our new menu item that we will add to test our ACL permissions.
<?xml version="1.0"?> <config> <menu> <acl module="acl" translate="label"> <title>ACL</title> <sort_order>1000</sort_order> <children> <manageacl module="acl" translate="label"> <title>Manage ACL</title> <sort_order>10</sort_order> <action>adminhtml/acl/index</action> </manageacl> </children> </acl> </menu> </config>
And finally, our controller file that contains an indexAction()
method. The method will not be used for anything in particular. It will just print some text that will let us know if we can view the page.
<?php class Custom_Acl_AclController extends Mage_Adminhtml_Controller_Action { public function indexAction() { echo "We are allowed here"; exit(); } }
So we should get a new menu item appearing in the admin, and if we click on the sub menu item of this, we should be presented with the following:
So we see the contents of this page because we haven’t added the relevant ACL permissions yet. To do this, we need to add some ACL configuration within the adminhtml.xml
file.
<?xml version="1.0"?> <config> <menu> .... </menu> <acl> <resources> <all> <title>Allow Everything</title> </all> <admin> <children> <aclmenu translate="title" module="acl"> <title>ACL</title> <sort_order>1000</sort_order> <children> <manageacl translate="title" module="acl"> <title>ACL Test</title> </manageacl> </children> </aclmenu> </children> </admin> </resources> </acl> </config>
All ACL configuration is configured within a pair of acl
and resources
nodes.
Our new custom menu item should be added as a child within the children
nodes within the admin
nodes.
The name of your nodes should match the name given to them under the pair of menu
nodes defined within the same adminhtml.xml
file.
The sort_order
nodes can be used to position the checkboxes within System -> Permissions -> Roles
.
This works well, however we need to test another scenario. If a custom role is set up to view the custom menu item, along with a new user assigned to the custom role, when the user logs in and tries to view the page, we are presented with the following.
Remember the _isAllowed()
method from earlier? Currently we do not have this in our AclController.php
file, and so the method from the parent Mage_Adminhtml_Controller_Action
class is used. So we need to add in this method into our controller file and change the following line.
protected function _isAllowed() { return Mage::getSingleton('admin/session')->isAllowed('admin'); }
To this:
protected function _isAllowed() { return Mage::getSingleton('admin/session')->isAllowed('aclmenu/manageacl'); }
We can now see that our custom menu item is viewable to this user. Note that the aclmenu
and manageacl
words match the names of our nodes in our ACL configuration.
Magento also gives us the ability to add ACL permissions for sections within System -> Configuration
. We can test this out by adding a system.xml
file and adding a section within a tab.
<?xml version="1.0"?> <config> <tabs> <acltab translate="label" module="acl"> <label>ACL Tab</label> <sort_order>101</sort_order> </acltab> </tabs> <sections> <aclsection translate="label" module="acl"> <label>ACL Section</label> <tab>acltab</tab> <frontend_type>text</frontend_type> <sort_order>1000</sort_order> <show_in_default>1</show_in_default> <show_in_website>1</show_in_website> <show_in_store>1</show_in_store> </aclsection> </sections> </config>
This adds a new tab and section within System -> Configuration
.
However, when clicking on the section, we’re presented with a 404 error.
We should set up ACL Permissions for this section.
<?xml version="1.0"?> <config> .... <acl> <resources> .... <admin> <children> .... <system> <children> <config> <children> <aclsection> <title>ACL Section</title> </aclsection> </children> </config> </children> </system> </children> </admin> </resources> </acl> </config>
Magento caches certain roles in the session, so a logout and login of the admin area should be enough for the permissions to take effect and allow you to view the section.
Note: This article is based on Magento Community/Open Source version 1.9.