Created
November 29, 2010 16:20
-
-
Save stephaneerard/720143 to your computer and use it in GitHub Desktop.
A sf Task for diem to manage module/action security
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| <?php | |
| class dmSecureModuleActionTask extends dmContextTask | |
| { | |
| protected $module, $modulePath, $permissionName, $_options, $_arguments, $dbConn; | |
| protected function configure() | |
| { | |
| parent::configure(); | |
| $this->addArguments(array( | |
| new sfCommandArgument('module', sfCommandArgument::REQUIRED, 'The module name'), | |
| new sfCommandArgument('action', sfCommandArgument::OPTIONAL, 'The action to secure', 'all'), | |
| )); | |
| $this->addOptions(array( | |
| new sfCommandOption('unsecure', null, sfCommandOption::PARAMETER_NONE, 'Append to file or not'), | |
| new sfCommandOption('append', null, sfCommandOption::PARAMETER_NONE, 'Append to file or not'), | |
| )); | |
| $this->namespace = 'dm'; | |
| $this->name = 'secure-module'; | |
| $this->briefDescription = 'Secures a module'; | |
| $this->detailedDescription = <<<EOF | |
| Secures a module/action by creating a security.yml file | |
| within its config directory. | |
| The generated security.yml file contains an entry for given action, | |
| and creates a dmPermission with pattern %MODULE%/%ACTION% | |
| Using --append you'll not erase file content. | |
| Using --unsecure you'll erase action securisation | |
| [php symfony dmSecureAdminModule|INFO] | |
| EOF; | |
| } | |
| protected function execute($arguments = array(), $options = array()) | |
| { | |
| $this->setUp($arguments, $options); | |
| $this->getModule(); | |
| $this->setPermissionName(); | |
| $this->writeSecurityFile(); | |
| $this->createDmPermission(); | |
| $this->rememberClearCache(); | |
| } | |
| protected function setUp($arguments, $options){ | |
| $this->dbConn = $this->withDatabase(); | |
| $this->_arguments = $arguments; | |
| $this->_options = $options; | |
| } | |
| protected function getModule(){ | |
| $modules = $this->get('module_manager')->getModules(); | |
| if(!in_array($this->_arguments['module'], $modules)){ | |
| throw new Exception('The given module doesnt exist'); | |
| } | |
| $this->module = $modules[$this->_arguments['module']]; | |
| $this->modulePath = $this->getModulePath($this->module, $this->_options['application']); | |
| $this->securityFile = dmOs::join($this->modulePath, 'config', 'security.yml'); | |
| $this->logSection('diem', sprintf('security file at %s', $this->securityFile)); | |
| } | |
| /** | |
| * @todo put this method within dmModule ->getPath() | |
| * Enter description here ... | |
| * @param dmModule $module | |
| */ | |
| protected function getModulePath(dmModule $module, $app="") | |
| { | |
| $path = ''; | |
| if($module->isPlugin()){ | |
| $path = dmOs::join(sfConfig::get('sf_plugins_dir'), $module->getPluginName(), 'modules', $module->getSfName()); | |
| }else{ | |
| $path = dmOs::join(sfConfig::get('sf_apps_dir'), $app, 'modules', $module->getSfName()); | |
| } | |
| return $path; | |
| } | |
| protected function setPermissionName(){ | |
| switch($this->_arguments['action']){ | |
| case 'all': | |
| $this->permissionName = $this->module->getSfName().'/all'; | |
| break; | |
| default: | |
| $this->permissionName = $this->module->getSfName().'/'.$this->_arguments['action']; | |
| } | |
| } | |
| protected function getSecurityTemplate(){ | |
| $action = $this->_arguments['action']; | |
| $module = $this->module->getSfName(); | |
| $securityTemplate = ''; | |
| switch($action){ | |
| case 'all': | |
| $securityTemplate = <<<EOF | |
| all: | |
| is_secure: true | |
| credentials: {$this->permissionName} | |
| EOF; | |
| break; | |
| default: | |
| $securityTemplate = <<<EOF | |
| {$action}: | |
| is_secure: true | |
| credentials: {$this->permissionName} | |
| EOF; | |
| } | |
| return $securityTemplate; | |
| } | |
| protected function writeSecurityFile(){ | |
| $yaml = sfYaml::load($this->securityFile); | |
| if($this->_options['unsecure']){ | |
| if(isset($yaml[$this->_arguments['action']])){ | |
| unset($yaml[$this->_arguments['action']]); | |
| $dumper = new sfYamlDumper(); | |
| $securityTemplate = $dumper->dump($yaml, 3); | |
| file_put_contents($this->securityFile, $securityTemplate); | |
| $this->logSection('diem', 'action removed from security file'); | |
| }else{ | |
| $this->logSection('diem', 'action has not been found in security file'); | |
| } | |
| }else{ | |
| if(isset($yaml[$this->_arguments['action']])){ | |
| //the action is already secured | |
| $this->logSection('diem', 'the action is already secured in security file'); | |
| if($yaml[$this->_arguments['action']]['credentials'] !== $this->permissionName){ | |
| $this->logSection('diem', 'the credential differs, changing'); | |
| $yaml[$this->_arguments['action']]['credentials'] = $this->permissionName; | |
| $dumper = new sfYamlDumper(); | |
| $securityTemplate = $dumper->dump($yaml, 3); | |
| file_put_contents($this->securityFile, $securityTemplate); | |
| } | |
| $this->logSection('diem', 'checking if permission exists in db, create otherwise'); | |
| if(!Doctrine::getTable('DmPermission')->findOneBy('name', $this->permissionName)){ | |
| $this->createDmPermission(); | |
| }else{ | |
| $this->logSection('diem', 'permission already exists in db'); | |
| } | |
| exit(0); | |
| }else{ | |
| $securityTemplate = $this->getSecurityTemplate(); | |
| if($this->_options['append']) | |
| { | |
| file_put_contents($this->securityFile, $securityTemplate, FILE_APPEND); | |
| } | |
| else{ | |
| file_put_contents($this->securityFile, $securityTemplate); | |
| } | |
| } | |
| } | |
| } | |
| protected function createDmPermission(){ | |
| if($this->_options['unsecure']) | |
| { | |
| $permission = Doctrine::getTable('DmPermission')->findOneBy('name', $this->permissionName); | |
| if($permission){ | |
| $permission->delete(); | |
| $this->logSection('diem', 'permission deleted from db'); | |
| }else{ | |
| $this->logSection('diem', 'permission has not been found in db'); | |
| } | |
| }else{ | |
| $action = $this->_arguments['action']; | |
| $module = $this->_arguments['module']; | |
| $this->logSection('diem', sprintf('creating permission named %s', $this->permissionName)); | |
| $permission = new DmPermission(); | |
| $permission->set('name', $this->permissionName); | |
| $permission->set('description', sprintf('Grant user access to module %s action %s', $module, $action)); | |
| try{ | |
| $permission->trySave($this->dbConn); | |
| }catch(Doctrine_Connection_Exception $e){ | |
| switch($e->getCode()){ | |
| case 23000: | |
| $this->logSection('diem', 'looks like the permission already exists', null, 'WARNING'); | |
| break; | |
| default: | |
| throw $e; | |
| } | |
| } | |
| } | |
| } | |
| protected function rememberClearCache(){ | |
| $this->logSection('diem', 'Don\'t forget to clear the cache and disconnect-reconnect users for credentials to be reloaded !'); | |
| } | |
| } |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment