Skip to content

Instantly share code, notes, and snippets.

@mpchadwick
Created July 11, 2015 03:42
Show Gist options
  • Save mpchadwick/6de214d2b231ccfb3ec6 to your computer and use it in GitHub Desktop.
Save mpchadwick/6de214d2b231ccfb3ec6 to your computer and use it in GitHub Desktop.
Mpchadwick_Missing_Acl_Checker.php
<?php
require_once 'abstract.php';
/**
* Generate a CSV of modules with admin routes that haven't implemented _isAllowed()
*/
class Mpchadwick_Missing_Acl_Checker extends Mage_Shell_Abstract
{
const MODULES_PATH = 'modules';
const ADMIN_ROUTERS_PATH = 'admin/routers';
const CSV_FILE_NAME = 'missingAcl.csv';
/**
* Config instance
*
* @var Mage_Core_Model_Config
*/
protected $_config;
/**
* Csv Handle
*
* @var File handle
*/
protected $_csvHandle;
/**
* Retrieve config instance
*
* @return Mage_Core_Model_Config
*/
protected function _getConfig()
{
if (is_null($this->_config)) {
$this->_config = Mage::getConfig();
}
return $this->_config;
}
/**
* Checks whether an _isAllowed method exists in the module directory
* This check does not guarantee that *all* controllers have implemented _isAllowed()
* but identifies the modules where *no* controllers have done so
*
* @param string $moduleName
* @param array $moduleData
* @return boolean
*/
protected function _checkForIsAllowed($moduleName, $moduleData)
{
$pos = strpos($moduleName, '_');
$vendor = substr($moduleName, 0, $pos);
$module = substr($moduleName, $pos + 1);
$codePool = (string)$moduleData['codePool'];
$path = 'app/code/' . $codePool . '/' . $vendor . '/' . $module . '/';
return (shell_exec("grep -R '_isAllowed' $path"));
}
/**
* Write data about a module that has been confirmed missing _isAllowed to a CSV
*
* @param string $moduleName
* @param array $moduleData
*/
protected function _addModuleToCsv($moduleName, $moduleData)
{
$row = [];
$row[] = $moduleData['codePool'];
$row[] = $moduleName;
$row[] = $moduleData['version'];
fputcsv($this->_csvHandle, $row);
return true;
}
protected function _giveFeedback($message)
{
if (!$this->getArg('silent')) {
echo $message . PHP_EOL;
}
}
/**
* Run script
*
*/
public function run()
{
$this->_showIntroMessage();
$allModules = $this->_getConfig()->getNode(self::MODULES_PATH)->asArray();
$adminRoutersNode = $this->_getConfig()->getNode(self::ADMIN_ROUTERS_PATH);
$this->_csvHandle = fopen(self::CSV_FILE_NAME, 'w');
foreach ($adminRoutersNode->children() as $routerName => $routerData) {
// Check the module associated with this router
$moduleName = (string)$routerData->args->module;
$this->_giveFeedback('Checking ' . $moduleName);
$moduleData = $allModules[$moduleName];
$active = (boolean)$moduleData['active'];
$codePool = (string)$moduleData['codePool'];
if ($active && $codePool !== 'core') {
if (!$this->_checkForIsAllowed($moduleName, $moduleData)) {
$this->_giveFeedback('>>> _isAllowed() is missing. Adding to csv');
$this->_addModuleToCsv($moduleName, $moduleData);
} else {
$this->_giveFeedback('>>> _isAllowed() is implemented at least once in this module');
}
} else {
$this->_giveFeedback('>>> This module either is not active, or is in the core code pool');
}
$this->_giveFeedback('==================================');
// Check any child modules
if ($childModules = $routerData->args->modules) {
foreach ($childModules->children() as $childModuleNodeName => $childModuleNodeBody) {
$pos1 = strpos($childModuleNodeBody, '_');
$pos2 = strpos($childModuleNodeBody, '_', $pos1 + 1);
$moduleName = ($pos2) ? substr($childModuleNodeBody, 0, $pos2) : $childModuleNodeBody;
$moduleName = (string)$moduleName;
$this->_giveFeedback('Checking ' . $moduleName);
$moduleData = $allModules[$moduleName];
$active = (boolean)$moduleData['active'];
$codePool = (string)$moduleData['codePool'];
if ($active && $codePool !== 'core') {
if (!$this->_checkForIsAllowed($moduleName, $moduleData)) {
$this->_giveFeedback('>>> _isAllowed() is missing. Adding to csv');
$this->_addModuleToCsv($moduleName, $moduleData);
} else {
$this->_giveFeedback('>>> _isAllowed() is implemented at least once in this module');
}
} else {
$this->_giveFeedback('>>> This module either is not active, or is in the core code pool');
}
$this->_giveFeedback('==================================');
}
}
}
fclose($this->_csvHandle);
$this->_showExitMessage();
}
/**
* Show the intro message when running the script
*/
protected function _showIntroMessage()
{
$this->_giveFeedback('==================================');
$this->_giveFeedback('==================================');
$this->_giveFeedback('Mpchadwick_Missing_Acl_Checker');
$this->_giveFeedback('==================================');
$this->_giveFeedback('==================================');
$this->_giveFeedback('Generates a CSV of modules with admin routes that haven\'t implemented _isAllowed()');
$this->_giveFeedback('');
$this->_giveFeedback('This script greps the directory of each enabled community and local module that implements');
$this->_giveFeedback('an admin router for _isAllowed()');
$this->_giveFeedback('');
$this->_giveFeedback('shell_exec is required to execute this script successfully');
$this->_giveFeedback('');
$this->_giveFeedback('Just because _isAllowed() exists in the module doesn\'t necessarily mean that is has been');
$this->_giveFeedback('implemented correctly in all controllers');
$this->_giveFeedback('');
$this->_giveFeedback('User discretion is advised');
$this->_giveFeedback('==================================');
$this->_giveFeedback('==================================');
$this->_giveFeedback('');
}
protected function _showExitMessage()
{
$this->_giveFeedback('');
$this->_giveFeedback('');
$this->_giveFeedback('Finished! CSV generated with the following file name ' . self::CSV_FILE_NAME);
}
}
$checker = new Mpchadwick_Missing_Acl_Checker();
$checker->run();
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment