Skip to content

Instantly share code, notes, and snippets.

@stephaneerard
Created November 29, 2010 16:20
Show Gist options
  • Select an option

  • Save stephaneerard/720143 to your computer and use it in GitHub Desktop.

Select an option

Save stephaneerard/720143 to your computer and use it in GitHub Desktop.
A sf Task for diem to manage module/action security
<?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