Nieco zmodyfikowany skrypt automatycznego tworzenia ACLi. Dodaliśmy tworzenie ARO’s na podstawie tabeli Users oraz automatyczne dodawanie zdefiniowanych grantów (var $permissions):
class AclGenerateShell extends Shell {
var $permissions = array("admin" => array("controllers") ,
"operator" => array(
"controllers/Users/employees",
"controllers/Users/add_employee",
"controllers/Users/delete_employee",
"controllers/Users/edit_employee",
"controllers/Users/send",
"controllers/Users/generatePassword",
"Cars",
"Entries",
"Agreements",
"Appendixes",
"controllers/Packages/details"
),
"pracownik" => array(
"controllers/Cars/lists",
"controllers/Entries/employee_entries",
"Costs",
"Drivers",
"Tracks",
"controllers/Cars/details",
"controllers/Cars/lists_drivers",
"controllers/Cars/bind_car_to_driver",
"Services"
),
);
/**
* @var AclComponent
*/
var $Acl;
/**
* @var AuthComponent
*/
var $Auth;
function help() {
$this->out("ACL Genarate - adds or update ACL objects and permissions");
$this->hr();
$this->out("Usage: cake acl_generate
...");
$this->hr();
$this->out("If called withoud any params, acts like");
$this->out("\t\t\tcake acl_generate -aros -grants");
$this->out("\t\t\twithout time consuming ACO's generation");
$this->out("Params:");
$this->out("\t\t-acos ");
$this->out("\t\t\tGenerate ACO's for every Controller's methods");
$this->out("\t\t-aros ");
$this->out("\t\t\tGenerate ACO's for every User and Group in DB");
$this->out("\t\t-grants ");
$this->out("\t\t\tgrants ARO's access to ACO's based on AclGenerate::permissions array ");
$this->out("\t\t-all ");
$this->out("\t\t\teffect like with cake acl_generate -acos -aros -grants");
$this->out("\t\t-help ");
$this->out("\t\t\tdisplay this help");
}
function main() {
$default = true;
if(isset($this->params['test'])) {
return 1;
}
if(isset($this->params["help"])) {
return $this->help();
}
if(isset($this->params['all'])) {
$this->params['acos'] = $this->params['aros'] = $this->params['grants'] = 1;
}
if(! (isset($this->params['acos']) || isset($this->params['aros']) || isset($this->params['grants'])) ) {
$this->params['aros'] = $this->params['grants'] = 1;
}
if(isset($this->params['acos'])) {
$this->out("================================= Building ACO's...");
$this->buildACOs();
}
if(isset($this->params['aros'])) {
$this->out("================================= Building ARO's...");
$this->buildAROs();
}
if(isset($this->params['grants'])) {
$this->out("================================= Giving grants...");
$this->setGrants();
}
}
function initialize() {
App::import("component", "Auth");
$this->Auth = ClassRegistry::init("AuthComponent", "component");
App::import("component", "Acl");
$this->Acl = ClassRegistry::init("AclComponent", "component");
App::import("Core", "Controller");
$this->_welcome();
$this->out('ACL generate');
$this->hr();
}
function startup() {}
function setGrants() {
App::import("model", "Group");
$Group = ClassRegistry::init("Group", "model");
$Group->Behaviors->attach("Containable");
foreach($this->permissions as $name => $acos) {
$id = $Group->find("first", array( "conditions"=>array( "name"=> $name ), "contain"=> array()));
$Group->id = $id["Group"]["id"];
$this->out("Group $name permissions:");
foreach($acos as $aco) {
$this->out("$aco");
$this->Acl->allow($Group, $aco);
}
}
}
function _setGrants() {
$Group->id = 3;
$this->Acl->grant($Group, "Cars", "lists");
$this->Acl->grant($Group, "Costs", "all");
}
function buildAROs() {
App::import("model", "Group");
$Group = ClassRegistry::init("Group", "model");
$Group->Behaviors->attach("Containable");
$groups = $Group->find("all", array("contain"=> array(), "order"=> "Group.id ASC"));
App::import("model", "User");
$User = ClassRegistry::init("User", "model");
$users = $User->find("all", array("order"=> "User.id ASC"));
$User->Behaviors->disable("Acl");
$Group->Behaviors->disable("Acl");
foreach($users as $user) {
$User->delete($user['User']['id']);
}
foreach($groups as $group) {
$Group->delete($group['Group']['id']);
}
// $Group->validate = array();
$User->Behaviors->enable("Acl");
$Group->Behaviors->enable("Acl");
foreach($groups as $group) {
$this->out("Creating ARO for {$group['Group']['name']} Group");
$Group->save($group['Group']);
}
$User->validate = array();
foreach($users as $user) {
unset($user["Group"]);
$this->out("Creating ARO for {$user['User']['name']} User");
$User->save($user);
}
//
}
function buildACOs() {
if (!Configure::read('debug')) {
return $this->_stop();
}
$log = array();
$aco =& $this->Acl->Aco;
$root = $aco->node('controllers');
if (!$root) {
$aco->create(array('parent_id' => null, 'model' => null, 'alias' => 'controllers'));
$root = $aco->save();
$root['Aco']['id'] = $aco->id;
$log[] = 'Created Aco node for controllers';
} else {
$root = $root[0];
}
App::import('Core', 'File');
$Controllers = Configure::listObjects('controller');
$appIndex = array_search('App', $Controllers);
if ($appIndex !== false ) {
unset($Controllers[$appIndex]);
}
// $baseMethods = get_class_methods('Controller');
$baseMethods[] = 'buildAcl';
$Plugins = $this->_getPluginControllerNames();
$Controllers = array_merge($Controllers, $Plugins);
// look at each controller in app/controllers
foreach ($Controllers as $ctrlName) {
$this->out("Checking $ctrlName methods");
$methods = $this->_getClassMethods($this->_getPluginControllerPath($ctrlName));
// Do all Plugins First
if ($this->_isPlugin($ctrlName)){
$pluginNode = $aco->node('controllers/'.$this->_getPluginName($ctrlName));
$this->out($pluginNode, true);
if (!$pluginNode) {
$aco->create(array('parent_id' => $root['Aco']['id'], 'model' => null, 'alias' => $this->_getPluginName($ctrlName)));
$pluginNode = $aco->save();
$pluginNode['Aco']['id'] = $aco->id;
$this->out( 'Created Aco node for ' . $this->_getPluginName($ctrlName) . ' Plugin');
}
}
// find / make controller node
$controllerNode = $aco->node('controllers/'.$ctrlName);
if (!$controllerNode) {
if ($this->_isPlugin($ctrlName)){
$pluginNode = $aco->node('controllers/' . $this->_getPluginName($ctrlName));
$aco->create(array('parent_id' => $pluginNode['0']['Aco']['id'], 'model' => null, 'alias' => $this->_getPluginControllerName($ctrlName)));
$controllerNode = $aco->save();
$controllerNode['Aco']['id'] = $aco->id;
$this->out( 'Created Aco node for ' . $this->_getPluginControllerName($ctrlName) . ' ' . $this->_getPluginName($ctrlName) . ' Plugin Controller, ');
} else {
$aco->create(array('parent_id' => $root['Aco']['id'], 'model' => null, 'alias' => $ctrlName));
$controllerNode = $aco->save();
$controllerNode['Aco']['id'] = $aco->id;
if(isset($method)){
$this->out("\t$method");
}
}
} else {
$controllerNode = $controllerNode[0];
}
//clean the methods. to remove those in Controller and private actions.
$i = 0;
foreach ($methods as $k => $method) {
// $this->out("$k => $method", true);
$i++;
if (strpos($method, '_', 0) === 0) {
unset($methods[$k]);
continue;
}
if (in_array($method, $baseMethods)) {
unset($methods[$k]);
continue;
}
$methodNode = $aco->node('controllers/'.$ctrlName.'/'.$method);
if (!$methodNode) {
$aco->create(array('parent_id' => $controllerNode['Aco']['id'], 'model' => null, 'alias' => $method));
$methodNode = $aco->save();
$this->out("\t$method");
}
}
// $this->out($i, true);
}
}
function microtime_float()
{
// debug(microtime());
list($usec, $sec) = explode(" ", microtime());
return ($usec);
}
function _getClassMethods($ctrlName = null) {
App::import('Controller', $ctrlName);
if (strlen(strstr($ctrlName, '.')) > 0) {
// plugin's controller
$num = strpos($ctrlName, '.');
$ctrlName = substr($ctrlName, $num+1);
}
$ctrlclass = $ctrlName . 'Controller';
App::import("Controller", "AppController");
App::import("Controller", "Controller");
// nie używamy dziedziczenia akcji kontrolera, więc nie ma potrzeby sprawdzania czy istnieją acl'e dla dziedziczonych akcji z
// appController
// $methods = get_class_methods($ctrlclass);\
// $AppControllerMethods = get_class_methods("AppController");
return array_diff(get_class_methods($ctrlclass),get_class_methods("AppController"), get_class_methods("Controller")) ;
}
function _isPlugin($ctrlName = null) {
$arr = String::tokenize($ctrlName, '/');
if (count($arr) > 1) {
return true;
} else {
return false;
}
}
function _getPluginControllerPath($ctrlName = null) {
$arr = String::tokenize($ctrlName, '/');
if (count($arr) == 2) {
return $arr[0] . '.' . $arr[1];
} else {
return $arr[0];
}
}
function _getPluginName($ctrlName = null) {
$arr = String::tokenize($ctrlName, '/');
if (count($arr) == 2) {
return $arr[0];
} else {
return false;
}
}
function _getPluginControllerName($ctrlName = null) {
$arr = String::tokenize($ctrlName, '/');
if (count($arr) == 2) {
return $arr[1];
} else {
return false;
}
}
/**
* Get the names of the plugin controllers ...
*
* This function will get an array of the plugin controller names, and
* also makes sure the controllers are available for us to get the
* method names by doing an App::import for each plugin controller.
*
* @return array of plugin names.
*
*/
function _getPluginControllerNames() {
App::import('Core', 'File', 'Folder');
$paths = Configure::getInstance();
$folder =& new Folder();
$folder->cd(APP . 'plugins');
// Get the list of plugins
$Plugins = $folder->read();
$Plugins = $Plugins[0];
$arr = array();
// Loop through the plugins
foreach($Plugins as $pluginName) {
// Change directory to the plugin
$didCD = $folder->cd(APP . 'plugins'. DS . $pluginName . DS . 'controllers');
// Get a list of the files that have a file name that ends
// with controller.php
$files = $folder->findRecursive('.*_controller\.php');
// Loop through the controllers we found in the plugins directory
foreach($files as $fileName) {
// Get the base file name
$file = basename($fileName);
// Get the controller name
$file = Inflector::camelize(substr($file, 0, strlen($file)-strlen('_controller.php')));
if (!preg_match('/^'. Inflector::humanize($pluginName). 'App/', $file)) {
if (!App::import('Controller', $pluginName.'.'.$file)) {
debug('Error importing '.$file.' for plugin '.$pluginName);
} else {
/// Now prepend the Plugin name ...
// This is required to allow us to fetch the method names.
$arr[] = Inflector::humanize($pluginName) . "/" . $file;
}
}
}
}
return $arr;
}
}