{"id":5498,"date":"2016-07-01T12:51:58","date_gmt":"2016-07-01T12:51:58","guid":{"rendered":"https:\/\/blog.mageworx.com\/?p=5498"},"modified":"2023-01-20T14:40:25","modified_gmt":"2023-01-20T14:40:25","slug":"adding-more-flexibility-to-magento-access-control-lists","status":"publish","type":"post","link":"https:\/\/www.mageworx.com\/blog\/adding-flexibility-to-magento-access-control-lists","title":{"rendered":"Adding More Flexibility to Magento Access Control Lists"},"content":{"rendered":"\n<!-- SEO Ultimate (http:\/\/www.seodesignsolutions.com\/wordpress-seo\/) - Code Inserter module -->\n<!-- Google Tag Manager (noscript) -->\r\n<noscript><iframe src=\"https:\/\/www.googletagmanager.com\/ns.html?id=GTM-5DTCW7B8\"\r\nheight=\"0\" width=\"0\" style=\"display:none;visibility:hidden\"><\/iframe><\/noscript>\r\n<!-- End Google Tag Manager (noscript) -->\n<!-- \/SEO Ultimate -->\n\n<span class=\"span-reading-time rt-reading-time\" style=\"display: block;\"><span class=\"rt-label rt-prefix\">Reading Time: <\/span> <span class=\"rt-time\"> 2<\/span> <span class=\"rt-label rt-postfix\">minutes<\/span><\/span><p>Sometimes you may need to let customers manage products section in your store BUT limit their ability to delete them. However, by default, Magento allows you to change only one permission that called &#8216;Manage product&#8217;. That&#8217;s quite a limitation and doesn&#8217;t allow us to solve this problem.<\/p>\n<p>Read on to learn how to create additional permission, like &#8216;Add&#8217;, &#8220;Edit&#8217;, or &#8216;Delete&#8217;, etc.<br \/>\n<!--more--><br \/>\nWe&#8217;ve created a little module with an observer and a new ACL rule that will let you extend the default Magento functionality.<\/p>\n<p>Here is the adminhtml.xml file:<\/p>\n<pre class=\"theme:github font:courier-new font-size:16 line-height:18 lang:default decode:true \">&lt;?xml version=\"1.0\"?&gt;\n&lt;config&gt;\n    &lt;acl&gt;\n        &lt;resources&gt;\n            &lt;admin&gt;\n                &lt;children&gt;\n                    &lt;catalog&gt;\n                        &lt;children&gt;\n                            &lt;products&gt;\n                                &lt;children&gt;\n                                    &lt;delete translate=\"title\"&gt;\n                                        &lt;title&gt;Delete Products&lt;\/title&gt;\n                                    &lt;\/delete&gt;\n                                &lt;\/children&gt;\n                            &lt;\/products&gt;\n                        &lt;\/children&gt;\n                    &lt;\/catalog&gt;\n                &lt;\/children&gt;\n            &lt;\/admin&gt;\n        &lt;\/resources&gt;\n    &lt;\/acl&gt;\n&lt;\/config&gt;<\/pre>\n<p>Also, we added a new ACL \u2018Manage Products\u2019 section with the \u2019Delete Products\u2019 section inside.<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" class=\"alignleft size-full wp-image-5501\" src=\"https:\/\/www.mageworx.com\/blog\/wp-content\/uploads\/2016\/07\/original.png\" alt=\"original\" width=\"278\" height=\"229\" srcset=\"https:\/\/www.mageworx.com\/blog\/wp-content\/uploads\/2016\/07\/original.png 278w, https:\/\/www.mageworx.com\/blog\/wp-content\/uploads\/2016\/07\/original-150x124.png 150w\" sizes=\"auto, (max-width: 278px) 100vw, 278px\" \/><\/p>\n<p>You can repeat this for other actions that you may want to limit for customers.<\/p>\n<p>Then, we need the observer where to check if the action is permitted or redirect the Admin back if not. As in the previous case, you can extend this functionality.<\/p>\n<p>Declare the observer in the modules&#8217; config.xml file in the adminhtml section:<\/p>\n<pre class=\"theme:github font:courier-new font-size:16 line-height:18 lang:default decode:true \">&lt;adminhtml&gt;\n    &lt;events&gt;\n        &lt;controller_action_predispatch_adminhtml_catalog_product_delete&gt;\n            &lt;observers&gt;\n                &lt;delete_product_acl&gt;\n                    &lt;type&gt;singleton&lt;\/type&gt;\n                    &lt;class&gt;test\/observer&lt;\/class&gt;\n                    &lt;method&gt;isDeletionAllowed&lt;\/method&gt;\n                &lt;\/delete_product_acl&gt;\n            &lt;\/observers&gt;\n        &lt;\/controller_action_predispatch_adminhtml_catalog_product_delete&gt;\n        &lt;controller_action_predispatch_adminhtml_catalog_product_massDelete&gt;\n            &lt;observers&gt;\n                &lt;massdelete_product_acl&gt;\n                    &lt;type&gt;singleton&lt;\/type&gt;\n                    &lt;class&gt;test\/observer&lt;\/class&gt;\n                    &lt;method&gt;isDeletionAllowed&lt;\/method&gt;\n                &lt;\/massdelete_product_acl&gt;\n            &lt;\/observers&gt;\n        &lt;\/controller_action_predispatch_adminhtml_catalog_product_massDelete&gt;\n    &lt;\/events&gt;\n&lt;\/adminhtml&gt;\n<\/pre>\n<p>We&#8217;ve used two known actions to delete products: <em>simple delete<\/em> and <em>delete with mass clearance. <\/em>Both are available in the products grid.<\/p>\n<p>The same observer and its method is used because there are no differences between the checks and result. When expanding this functionality, keep in mind that the observer&#8217;s name should be unique (<em>delete_product_acl<\/em> and <em>massdelete_product_acl<\/em> in our case).<\/p>\n<p>Now, we need to complete the method in the observer.<\/p>\n<p>Here is the Observer.php file:<\/p>\n<pre class=\"theme:github font:courier-new font-size:16 line-height:18 lang:default decode:true \">&lt;?php\n\nclass Test_Module_Model_Observer\n{\n\n    public function isDeletionAllowed($observer)\n    {\n        $isAllowed = Mage::getSingleton('admin\/session')-&gt;isAllowed('catalog\/products\/delete');\n        if (!$isAllowed) {\n            \/** @var $controller Mage_Core_Controller_Varien_Action *\/\n            $controller = $observer-&gt;getData('controller_action');\n            $controller-&gt;setFlag(\n                $controller-&gt;getRequest()-&gt;getActionName(),\n                Mage_Core_Controller_Varien_Action::FLAG_NO_DISPATCH,\n                true\n            );\n            Mage::getSingleton('adminhtml\/session')-&gt;addError(Mage::helper('test')-&gt;__('Delete action is not allowed'));\n            Mage::app()-&gt;getResponse()-&gt;setRedirect($controller-&gt;getUrl('*\/*\/'));\n            Mage::app()-&gt;getResponse()-&gt;sendResponse();\n        }\n    }\n}\n?&gt;\n<\/pre>\n<p>Let&#8217;s look through this method line by line:<\/p>\n<pre class=\"theme:github font:courier-new font-size:16 line-height:18 lang:default decode:true \">&lt;?php\n$isAllowed = Mage::getSingleton('admin\/session')-&gt;isAllowed('catalog\/products\/delete');\n?&gt;\n<\/pre>\n<p>We got the validation result for the current Admin using our ALC for &#8216;Delete&#8217;.<\/p>\n<p>In case you are logged in under Superadmin, the check will be ignored and always return &#8216;true&#8217;. That&#8217;s why it is required to create a new Admin (but not <em>Superadmin!<\/em>) to run the check.<\/p>\n<p>Next goes the <em>if<\/em> (<em>!$isAllowed<\/em>) check.<\/p>\n<p>If it is successfully passed and the rule is not available to the current Admin,\u00a0 reset the following execution of the current action for the current Controller. Also, give the redirect back in response to the index action of the current Controller with the \u2018<em>Delete action is not allowed<\/em>\u2019 error display.<\/p>\n<p>You can change the redirect page by replacing the path <em>$controller-&gt;getUrl(&#8216;*\/*\/&#8217;)<\/em> to any other, where the first * is route, and the second * is controller. The third and missed * is the controller&#8217;s action, when we miss value like in the example it is <em>indexAction<\/em>.<\/p>\n<p>You can change the result and show <em>404 page<\/em>, for example, or send an email to the Superadmin about the actions of the current Admin.<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" class=\"alignleft wp-image-5499 size-full\" src=\"https:\/\/www.mageworx.com\/blog\/wp-content\/uploads\/2016\/07\/original-1.png\" alt=\"original (1)\" width=\"1329\" height=\"711\" srcset=\"https:\/\/www.mageworx.com\/blog\/wp-content\/uploads\/2016\/07\/original-1.png 1329w, https:\/\/www.mageworx.com\/blog\/wp-content\/uploads\/2016\/07\/original-1-150x80.png 150w, https:\/\/www.mageworx.com\/blog\/wp-content\/uploads\/2016\/07\/original-1-300x160.png 300w, https:\/\/www.mageworx.com\/blog\/wp-content\/uploads\/2016\/07\/original-1-768x411.png 768w, https:\/\/www.mageworx.com\/blog\/wp-content\/uploads\/2016\/07\/original-1-1024x548.png 1024w\" sizes=\"auto, (max-width: 1329px) 100vw, 1329px\" \/> <img loading=\"lazy\" decoding=\"async\" class=\"alignleft wp-image-5500 size-full\" src=\"https:\/\/www.mageworx.com\/blog\/wp-content\/uploads\/2016\/07\/original-2.png\" alt=\"original (2)\" width=\"1896\" height=\"545\" srcset=\"https:\/\/www.mageworx.com\/blog\/wp-content\/uploads\/2016\/07\/original-2.png 1896w, https:\/\/www.mageworx.com\/blog\/wp-content\/uploads\/2016\/07\/original-2-150x43.png 150w, https:\/\/www.mageworx.com\/blog\/wp-content\/uploads\/2016\/07\/original-2-300x86.png 300w, https:\/\/www.mageworx.com\/blog\/wp-content\/uploads\/2016\/07\/original-2-768x221.png 768w, https:\/\/www.mageworx.com\/blog\/wp-content\/uploads\/2016\/07\/original-2-1024x294.png 1024w\" sizes=\"auto, (max-width: 1896px) 100vw, 1896px\" \/>Additionally, you can add the same check for the default blocks drawing in the Admin panel AND hide its buttons. If you are interested to learn how to do that, please let me know (in the comments section below) and we will write about that in a separate blog post.<\/p>\n<p>Hence, the basics of such a module are quite obvious and the following development is limited only to one&#8217;s development resources.<\/p>\n","protected":false},"excerpt":{"rendered":"<p><span class=\"span-reading-time rt-reading-time\" style=\"display: block;\"><span class=\"rt-label rt-prefix\">Reading Time: <\/span> <span class=\"rt-time\"> 2<\/span> <span class=\"rt-label rt-postfix\">minutes<\/span><\/span>Sometimes you may need to let customers manage products section in your store BUT limit their ability to delete them. However, by default, Magento allows you to change only one permission that called &#8216;Manage product&#8217;. That&#8217;s quite a limitation and doesn&#8217;t allow us to solve this problem. Read on to learn how to create additional [&hellip;]<\/p>\n","protected":false},"author":13,"featured_media":6047,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[289,425],"tags":[436],"class_list":{"0":"post-5498","1":"post","2":"type-post","3":"status-publish","4":"format-standard","5":"has-post-thumbnail","7":"category-magento","8":"category-magento-how-tos","9":"tag-developer-diaries"},"_links":{"self":[{"href":"https:\/\/www.mageworx.com\/blog\/wp-json\/wp\/v2\/posts\/5498","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.mageworx.com\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.mageworx.com\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.mageworx.com\/blog\/wp-json\/wp\/v2\/users\/13"}],"replies":[{"embeddable":true,"href":"https:\/\/www.mageworx.com\/blog\/wp-json\/wp\/v2\/comments?post=5498"}],"version-history":[{"count":10,"href":"https:\/\/www.mageworx.com\/blog\/wp-json\/wp\/v2\/posts\/5498\/revisions"}],"predecessor-version":[{"id":15587,"href":"https:\/\/www.mageworx.com\/blog\/wp-json\/wp\/v2\/posts\/5498\/revisions\/15587"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/www.mageworx.com\/blog\/wp-json\/wp\/v2\/media\/6047"}],"wp:attachment":[{"href":"https:\/\/www.mageworx.com\/blog\/wp-json\/wp\/v2\/media?parent=5498"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.mageworx.com\/blog\/wp-json\/wp\/v2\/categories?post=5498"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.mageworx.com\/blog\/wp-json\/wp\/v2\/tags?post=5498"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}