AclGenerateShell

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;
   }


}
Share Button

Leave a Reply

Your email address will not be published. Required fields are marked *