Skip to content

Instantly share code, notes, and snippets.

@standa
Forked from raybogman/SupportDesk_FixAcl.php
Last active May 18, 2016 23:57
Show Gist options
  • Star 2 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save standa/004937e00dcdb2acfecd to your computer and use it in GitHub Desktop.
Save standa/004937e00dcdb2acfecd to your computer and use it in GitHub Desktop.
SupportDesk_FixAcl
<?php
/**
* Updated behaviour:
*
* - search also /controllers and /Controller folders
* - disregard adminhtml.xml setup, write 'return true' always - or comment it back in if you need it
* - write more verbose logs
* - only update controllers extending Mage_Adminhtml_Controller_Action
*
*
* SupportDesk_FixAcl.php v1.1
* SupportDesk (www.supportdesk.nu)
* 10/7/2015
*
* NOTICE OF LICENSE
*
* This source file is subject to the Open Software License (OSL 3.0)
* It is available through the world-wide-web at this URL:
* http://opensource.org/licenses/osl-3.0.php
*
* @copyright SupportDesk BV (http://www.supportdesk.nu)
* @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
*
* @link https://gist.github.com/raybogman/eec47237b8ef0d4dd0fd
*/
namespace Aardvark\Shell;
date_default_timezone_set('UTC');
function getRecursiveList($data,&$list,$parent = '')
{
foreach($data as $node)
{
if($data->getName() == 'children')
{
$list[] = $parent . $node->getName();
getRecursiveList($node,$list,$parent . $node->getName() . '/');
}else{
getRecursiveList($node,$list,$parent);
}
}
}
function getAclList($adminHtml)
{
$data = file_get_contents($adminHtml);
if($data === false)
{
echo 'Adminhtml unreadable!' . PHP_EOL;
return false;
}
$data = simplexml_load_string($data);
if($data === false)
{
echo 'Could not parse ' . $adminHtml . PHP_EOL;
return false;
}
$list = array();
if(!isset($data->acl))
{
return $list;
}
getRecursiveList($data,$list);
return $list;
}
function getAclString($adminHtml,$file)
{
$controllerName = getControllerName($file);
$vendorName = getVendorName($file);
$moduleName = getModuleName($file);
$list = getAclList($adminHtml);
if(sizeof($list) == 0)
{
echo ' No ACL config found!' . PHP_EOL;
return false;
}
$result = array();
$backup = array();
foreach($list as $item)
{
if(strpos($item,$controllerName) !== false)
{
$result[] = $item;
}
}
if(sizeof($result) == 1)
{
return $result[0];
}else if(sizeof($result) > 1)
{
$list = $result;
$backup = $result;
$result = array();
}
foreach($list as $item)
{
if(strpos($item,$moduleName) !== false)
{
$result[] = $item;
}
}
if(sizeof($result) == 0)
{
$list = $backup;
}else if(sizeof($result) == 1)
{
return $result[0];
}else
{
$list = $result;
$backup = $result;
$result = array();
}
foreach($list as $item)
{
if(strpos($item,$vendorName) !== false)
{
$result[] = $item;
}
}
if(sizeof($result) == 0){
$result = $backup;
foreach($result as $item)
{
if($item == $controllerName)
{
return $item;
}
}
}
if(sizeof($result) == 1){
return $result[0];
}else if(sizeof($result) > 1)
{
usort($result, function ($a, $b) {
return strlen($b) - strlen($a);
});
return $result[0];
}
return false;
}
function getControllerName($file)
{
$needle = 'controllers/Adminhtml';
$marker = strpos($file,$needle);
$name = substr($file,$marker + strlen($needle) + 1);
$needle = 'Controller.php';
$marker = strpos($name,$needle);
$name = substr($name,0,$marker);
return strtolower($name);
}
function getModuleName($file)
{
return strtolower(preg_replace('/app\/code\/.*?\/.*?\/(.*?)\/.*/','$1',$file));
}
function getVendorName($file)
{
return strtolower(preg_replace('/app\/code\/.*?\/(.*?)\/.*/','$1',$file));
}
function getPatchString($file,$adminHtml)
{
$patchString = false;
if($adminHtml !== null)
{
$patchString = getAclString($adminHtml,$file);
}else
{
echo ' adminhtml.xml missing' . PHP_EOL;
}
if($patchString === false)
{
echo ' ' . 'could not determine ACL, using default (aka, allow everyone)' . PHP_EOL;
$patchString = 'return true;';
}else
{
// always return true
$patchString = 'return true;';
// $patchString = "return Mage::getSingleton('admin/session')->isAllowed('".$patchString."');";
}
echo ' Patching with: ' . $patchString . PHP_EOL;
$patchString = PHP_EOL .
' /**'.PHP_EOL.
' * add _isAllowed() method override '.PHP_EOL.
' * @author standa aardvark '.PHP_EOL.
' * @version '.date('Y-m-d').PHP_EOL.
' */'.PHP_EOL.
' protected function _isAllowed()' . PHP_EOL .
' {' . PHP_EOL .
' ' . $patchString . PHP_EOL .
' }';
return $patchString;
}
function patch($file,$adminHtml)
{
echo 'Patching file: ' . $file . '...' . PHP_EOL;
$patchString = getPatchString($file,$adminHtml);
$data = file_get_contents($file);
if($data === false)
{
echo ' Could not open file for writing!' . PHP_EOL;
return;
}
if(file_put_contents($file . '.orig',$data) === false)
{
echo ' Could not create backup file!' . PHP_EOL;
return;
}
$marker = strrpos($data,'}');
$result = substr($data,0,$marker-1) . $patchString . substr($data,$marker-1);
if(file_put_contents($file,$result) === false)
{
echo ' Could not write to file!' . PHP_EOL;
}
echo ' SUCCESS' . PHP_EOL;
}
function hasAllowed($file)
{
if(substr($file,-1) == '~'){return true;}
if(substr($file,-5) == '.orig'){return true;}
$content = file_get_contents($file);
if($content === false) {
echo $file . ' is unreadable!';
return true;
}
if (stripos($content, 'Mage_Adminhtml_Controller_Action') === false) {
echo __METHOD__.'(): File '.$file.' is not a Mage_Adminhtml_Controller_Action controller.'.PHP_EOL;
return true;
}
if(stripos($content,'extension_loaded(\'ionCube Loader') !== false){
echo $file . ' has been encoded by ionCube, skipping..' . PHP_EOL;
return true;
}
if(stripos($content,'function _isAllowed(') === false)
{
return false;
}
return true;
}
function patchController($file,$adminHtml)
{
if(!hasAllowed($file))
{
echo __METHOD__.'(): Patching '.$file.'.'.PHP_EOL;
patch($file,$adminHtml);
} else {
echo __METHOD__.'(): Controller '.$file.' will not be patched.'.PHP_EOL;
}
}
function traverseController($dir,$adminHtml)
{
$folder = opendir($dir);
while($new = readdir($folder))
{
if($new=='.' || $new=='..') {continue;}
$file = $dir . '/' . $new;
if(is_dir($file))
{
traverseController($file,$adminHtml);
}else if(is_file($file)){
patchController($file,$adminHtml);
}
}
}
function scanModule($file)
{
$adminHtml = $file . '/etc/adminhtml.xml';
if(!is_file($adminHtml))
{
$adminHtml = null;
}
if (is_dir($file.'/controllers')) {
traverseController($file.'/controllers', $adminHtml);
}
if (is_dir($file.'/Controller')) {
traverseController($file.'/Controller', $adminHtml);
}
if (is_dir($file.'/controllers/Adminhtml')) {
traverseController($file.'/controllers/Adminhtml', $adminHtml);
}
}
function traverseModule($dir)
{
$module = opendir($dir);
$new = '';
while($new = readdir($module))
{
if($new=='.' || $new=='..') {continue;}
$file = $dir . '/' . $new;
if(is_dir($file))
{
echo __METHOD__.'(): check '.$file.'.'.PHP_EOL;
scanModule($file);
}
}
closedir($module);
}
function traverseVendor($dir)
{
$vendor = opendir($dir);
$new = '';
while($new = readdir($vendor))
{
if($new=='.' || $new=='..') {continue;}
$file = $dir . '/' . $new;
if(is_dir($file))
{
echo __METHOD__.'(): check '.$file.'.'.PHP_EOL;
traverseModule($file);
}
}
closedir($vendor);
}
echo 'This script has been developed by SupportDesk (www.supportdesk.nu)' . PHP_EOL .
' Always make certain this is tested on a development environment first, preferably with GIT available' . PHP_EOL .
' And save the output from this script to a file, for your own administration' . PHP_EOL .
' This script is provided as is, and under no circumstances is there any warranty' . PHP_EOL .
' Usage at own discretion and risk' . PHP_EOL . PHP_EOL;
traverseVendor('app/code/community');
traverseVendor('app/code/local');
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment