From b50276f976c0c697b60bf153b816db531e9d7f3d Mon Sep 17 00:00:00 2001 From: phpnut Date: Sat, 5 Nov 2005 04:08:14 +0000 Subject: [PATCH] [1328] Author: phpnut Date: 10:02:08 PM, Friday, November 04, 2005 Message: Merging new ACL [1312] Author: phpnut Date: 8:20:15 AM, Wednesday, November 02, 2005 Message: More coding on the Security class. Added cipher method provided by Nate to the class. Added hash method that will be used to generate a authentication key Added method to the CakeSession class to return all session vars if the session components read method is called with empty params. git-svn-id: https://svn.cakephp.org/repo/trunk/cake@1329 3807eeeb-6ff5-0310-8944-8be069107fe0 --- app/config/core.php | 4 +- app/controllers/components/db_acl.sql | 36 ++ cake/libs/controller/components/acl.php | 112 +++++- cake/libs/controller/components/acl_base.php | 15 +- .../controller/components/dbacl/db_acl.php | 300 ++++++++++++++++ .../controller/components/dbacl/db_acl.sql | 29 ++ .../components/dbacl/models/aclnode.php | 194 ++++++++++ .../components/dbacl/models/aco.php | 10 + .../components/dbacl/models/acoaction.php | 10 + .../components/dbacl/models/aro.php | 9 + .../components/dbacl/models/aros_aco.php | 9 + .../controller/components/iniacl/ini_acl.php | 9 +- cake/libs/controller/components/session.php | 3 +- cake/libs/security.php | 56 ++- cake/libs/session.php | 25 +- cake/libs/view/helpers/ajax.php | 2 +- cake/scripts/acl.php | 335 ++++++++++++++++++ 17 files changed, 1134 insertions(+), 24 deletions(-) create mode 100644 app/controllers/components/db_acl.sql create mode 100644 cake/libs/controller/components/dbacl/db_acl.php create mode 100644 cake/libs/controller/components/dbacl/db_acl.sql create mode 100644 cake/libs/controller/components/dbacl/models/aclnode.php create mode 100644 cake/libs/controller/components/dbacl/models/aco.php create mode 100644 cake/libs/controller/components/dbacl/models/acoaction.php create mode 100644 cake/libs/controller/components/dbacl/models/aro.php create mode 100644 cake/libs/controller/components/dbacl/models/aros_aco.php rename app/controllers/components/my_acl.php => cake/libs/controller/components/iniacl/ini_acl.php (95%) create mode 100644 cake/scripts/acl.php diff --git a/app/config/core.php b/app/config/core.php index 47e75acae..d4deeaf7e 100644 --- a/app/config/core.php +++ b/app/config/core.php @@ -118,7 +118,7 @@ define('MAX_MD5SIZE', (5*1024)*1024 ); /** * To use Access Control Lists with Cake... */ -define('ACL_CLASSNAME', 'MyACL'); -define('ACL_FILENAME', 'my_acl.php'); +define('ACL_CLASSNAME', 'DB_ACL'); +define('ACL_FILENAME', 'dbacl'.DS.'db_acl'); ?> \ No newline at end of file diff --git a/app/controllers/components/db_acl.sql b/app/controllers/components/db_acl.sql new file mode 100644 index 000000000..33730959d --- /dev/null +++ b/app/controllers/components/db_acl.sql @@ -0,0 +1,36 @@ +CREATE TABLE `acos` ( + `id` int(11) NOT NULL auto_increment, + `object_id` int(11) default NULL, + `alias` varchar(255) NOT NULL default '', + `lft` int(11) default NULL, + `rght` int(11) default NULL, + PRIMARY KEY (`id`) +); + +CREATE TABLE `aros` ( + `id` int(11) NOT NULL auto_increment, + `user_id` int(11) default NULL, + `alias` varchar(255) NOT NULL default '', + `lft` int(11) default NULL, + `rght` int(11) default NULL, + PRIMARY KEY (`id`) +); + +CREATE TABLE `aros_acos` ( + `id` int(11) NOT NULL auto_increment, + `aro_id` int(11) default NULL, + `aco_id` int(11) default NULL, + `create` tinyint(1) NOT NULL default '0', + `read` tinyint(1) NOT NULL default '0', + `update` tinyint(1) NOT NULL default '0', + `delete` tinyint(1) NOT NULL default '0', + PRIMARY KEY (`id`) +); + +CREATE TABLE `aco_actions` ( + `id` int(11) NOT NULL auto_increment, + `aros_acos_id` int(11) default NULL, + `action` varchar(255) NOT NULL default '', + `value` tinyint(1) NOT NULL default '0', + PRIMARY KEY (`id`) +); diff --git a/cake/libs/controller/components/acl.php b/cake/libs/controller/components/acl.php index 4d47ce519..c9ac4fc24 100644 --- a/cake/libs/controller/components/acl.php +++ b/cake/libs/controller/components/acl.php @@ -42,20 +42,120 @@ * */ class AclComponent -{ - +{ + + var $_instance = null; + var $controller = true; + + function __construct() + { + $this->getACL(); + } + /** * Static function used to gain an instance of the correct ACL class. * * @return MyACL */ - function getACL() + function &getACL() { - require_once(COMPONENTS.ACL_FILENAME); + if($this->_instance == null) + { + uses('controller'.DS.'components'.DS.ACL_FILENAME); + $classname = ACL_CLASSNAME; + $this->_instance = new $classname; + } + return $this->_instance; + } - $myacl = ACL_CLASSNAME; - return new $myacl; + function _initACL() + { + + } + + /** + * Pass-thru function for ACL check instance. + * + * @return boolean + */ + function check($aro, $aco, $action = "*") + { + return $this->_instance->check($aro, $aco, $action); + } + + + /** + * Pass-thru function for ACL allow instance. + * + * @return boolean + */ + function allow($aro, $aco, $action = "*") + { + return $this->_instance->allow($aro, $aco, $action); + } + + /** + * Pass-thru function for ACL deny instance. + * + * @return boolean + */ + function deny($aro, $aco, $action = "*") + { + return $this->_instance->deny($aro, $aco, $action); + } + + /** + * Pass-thru function for ACL inherit instance. + * + * @return boolean + */ + function inherit($aro, $aco, $action = "*") + { + return $this->_instance->inherit($aro, $aco, $action); + } + + /** + * Pass-thru function for ACL grant instance. + * + * @return boolean + */ + function grant($aro, $aco, $action = "*") + { + return $this->_instance->grant($aro, $aco, $action); + } + + /** + * Pass-thru function for ACL grant instance. + * + * @return boolean + */ + function revoke($aro, $aco, $action = "*") + { + return $this->_instance->revoke($aro, $aco, $action); + } + + + /** + * Pass-thru function for ACL getAro instance. + * + * @return Aro + */ + function getAro($id) + { + return $this->_instance->getAro($id); + } + + + /** + * Pass-thru function for ACL getAco instance. + * + * @return Aco + */ + function getAco($id) + { + return $this->_instance->getAco($id); } } + ?> diff --git a/cake/libs/controller/components/acl_base.php b/cake/libs/controller/components/acl_base.php index 2b164d7dc..cce2ccee6 100644 --- a/cake/libs/controller/components/acl_base.php +++ b/cake/libs/controller/components/acl_base.php @@ -43,7 +43,7 @@ uses('error_messages'); */ class AclBase { - + function AclBase() { //No instantiations or constructor calls (even statically) @@ -52,10 +52,11 @@ class AclBase trigger_error(ERROR_ABSTRACT_CONSTRUCTION, E_USER_ERROR); return NULL; } - + } - - function check($aro, $aco) {} - -} -?> \ No newline at end of file + + function check($aro, $aco, $action = "*") {} + +} + +?> diff --git a/cake/libs/controller/components/dbacl/db_acl.php b/cake/libs/controller/components/dbacl/db_acl.php new file mode 100644 index 000000000..673448be0 --- /dev/null +++ b/cake/libs/controller/components/dbacl/db_acl.php @@ -0,0 +1,300 @@ + + * Copyright (c) 2005, CakePHP Authors/Developers + * + * Author(s): Michal Tatarynowicz aka Pies + * Larry E. Masters aka PhpNut + * Kamil Dzielinski aka Brego + * + * Licensed under The MIT License + * Redistributions of files must retain the above copyright notice. + * + * @filesource + * @author CakePHP Authors/Developers + * @copyright Copyright (c) 2005, CakePHP Authors/Developers + * @link https://trac.cakephp.org/wiki/Authors Authors/Developers + * @package cake + * @subpackage cake.cake.app.controllers.componenets + * @since CakePHP v 0.2.9 + * @version $Revision$ + * @modifiedby $LastChangedBy$ + * @lastmodified $Date$ + * @license http://www.opensource.org/licenses/mit-license.php The MIT License + */ + +uses('controller'.DS.'components'.DS.'acl_base'); +uses('controller'.DS.'components'.DS.'dbacl'.DS.'models'.DS.'aclnode'); +uses('controller'.DS.'components'.DS.'dbacl'.DS.'models'.DS.'aco'); +uses('controller'.DS.'components'.DS.'dbacl'.DS.'models'.DS.'acoaction'); +uses('controller'.DS.'components'.DS.'dbacl'.DS.'models'.DS.'aro'); +uses('controller'.DS.'components'.DS.'dbacl'.DS.'models'.DS.'aros_aco'); + +/** + * In this file you can extend the AclBase. + * + * @package cake + * @subpackage cake.cake.app.controllers.components + */ + +class DB_ACL extends AclBase +{ + + function __construct() + { + + } + + function check($aro, $aco, $action = "*") + { + + $Perms = new ArosAco(); + $Aro = new Aro(); + $Aco = new Aco(); + + if($aro == null || $aco == null) + { + return false; + } + + $permKeys = $this->_getAcoKeys($Perms->loadInfo()); + $aroPath = $Aro->getPath($aro); + $tmpAcoPath = $Aco->getPath($aco); + $acoPath = array(); + + if($action != '*' && !in_array($permKeys, '_' . $action)) + { + trigger_error('ACO permissions key "' . $action . '" does not exist in DB_ACL::check()', E_USER_ERROR); + } + + foreach($tmpAcoPath as $a) + { + $acoPath[] = $a['Aco']['id']; + } + $acoPath = implode(", ", $acoPath); + + for($i = count($aroPath) - 1; $i >= 0; $i--) + { + $perms = $Perms->findBySql("select aros_acos.* from aros_acos left join acos on aros_acos.aco_id = acos.id where aros_acos.aro_id = " . $aroPath[$i]['Aro']['id'] . " and aros_acos.aco_id in ({$acoPath}) order by acos.lft asc"); + if($perms == null || count($perms) == 0) + { + continue; + } + else + { + foreach($perms as $perm) + { + if($action == '*') + { + // ARO must be cleared for ALL ACO actions + foreach($permKeys as $key) + { + if($perm['aros_acos'][$key] != 1) + { + return false; + } + } + return true; + } + else + { + switch($perm['aros_acos']['_' . $action]) + { + case -1: + return false; + case 0: + continue; + break; + case 1: + return true; + } + } + } + } + } + + return false; + } + + /** + * Allow + * + * @return boolean + */ + function allow($aro, $aco, $action = "*", $value = 1) + { + $Perms = new ArosAco(); + $perms = $this->getAclLink($aro, $aco); + $permKeys = $this->_getAcoKeys($Perms->loadInfo()); + $save = array(); + + if(isset($perms[0])) + { + $save = $perms[0]['aros_acos']; + } + + if($action == "*") + { + $permKeys = $this->_getAcoKeys($Perms->loadInfo()); + foreach($permKeys as $key) + { + $save[$key] = $value; + } + } + else + { + if(in_array('_' . $action, $permKeys)) + { + $save['_' . $action] = $value; + } + else + { + // Raise an error + } + } + + $save['aro_id'] = $perms['aro']; + $save['aco_id'] = $perms['aco']; + + if($perms['link'] != null && count($perms['link']) > 0) + { + $save['id'] = $perms['link'][0]['aros_acos']['id']; + } + //return $Perms->save(array('ArosAco' => $save)); + + if(isset($save['id'])) + { + $q = 'update aros_acos set '; + $saveKeys = array(); + foreach($save as $key => $val) + { + if($key != 'id') + { + $saveKeys[] = $key . ' = ' . $val; + } + } + $q .= implode(', ', $saveKeys) . ' where id = ' . $save['id']; + } + else + { + $q = 'insert into aros_acos (' . implode(', ', array_keys($save)) . ') values (' . implode(', ', $save) . ')'; + } + + $Perms->db->query($q); + return true; + } + + /** + * Deny + * + * @return boolean + */ + function deny($aro, $aco, $action = "*") + { + return $this->allow($aro, $aco, $action, -1); + } + + /** + * Inherit + * + * @return boolean + */ + function inherit($aro, $aco, $action = "*") + { + return $this->allow($aro, $aco, $action, 0); + } + + /** + * Allow alias + * + * @return boolean + */ + function grant($aro, $aco, $action = "*") + { + return $this->allow($aro, $aco, $action); + } + + /** + * Deny alias + * + * @return boolean + */ + function revoke($aro, $aco, $action = "*") + { + return $this->deny($aro, $aco, $action); + } + + + + function getAro($id = null) + { + if($id == null) + { + // Raise error + } + $aro = new Aro(); + $tmp = $aro->find(is_string($aro) ? "aros.alias = '" . addslashes($aro) . "'" : "aros.user_id = {$aro}"); + $aro->setId($tmp['aro']['id']); + return $aro; + } + + + function getAco($id = null) + { + if($id == null) + { + // Raise error + } + $aco = new Aco(); + $tmp = $aco->find(is_string($aco) ? "acos.alias = '" . addslashes($aco) . "'" : "acos.user_id = {$aco}"); + $aro->setId($tmp['aco']['id']); + return $aco; + } + + + function getAclLink($aro, $aco) + { + $Aro = new Aro(); + $Aco = new Aco(); + + $qAro = (is_string($aro) ? "alias = '" . addslashes($aro) . "'" : "user_id = {$aro}"); + $qAco = (is_string($aco) ? "alias = '" . addslashes($aco) . "'" : "object_id = {$aco}"); + + $obj = array(); + $obj['Aro'] = $Aro->find($qAro); + $obj['Aco'] = $Aco->find($qAco); + $obj['Aro'] = $obj['Aro']['Aro']; + $obj['Aco'] = $obj['Aco']['Aco']; + + return array( + 'aro' => $obj['Aro']['id'], + 'aco' => $obj['Aco']['id'], + 'link' => $Aro->findBySql("select * from aros_acos where aro_id = {$obj['Aro']['id']} and aco_id = {$obj['Aco']['id']}") + ); + } + + function _getAcoKeys($keys) + { + $newKeys = array(); + $keys = $keys->value; + foreach($keys as $key) + { + if($key['name'] != 'id' && $key['name'] != 'aro_id' && $key['name'] != 'aco_id') + { + $newKeys[] = $key['name']; + } + } + return $newKeys; + } + +} + +?> \ No newline at end of file diff --git a/cake/libs/controller/components/dbacl/db_acl.sql b/cake/libs/controller/components/dbacl/db_acl.sql new file mode 100644 index 000000000..2b218248e --- /dev/null +++ b/cake/libs/controller/components/dbacl/db_acl.sql @@ -0,0 +1,29 @@ + +CREATE TABLE `acos` ( + `id` int(11) NOT NULL auto_increment, + `object_id` int(11) default NULL, + `alias` varchar(255) NOT NULL default '', + `lft` int(11) default NULL, + `rght` int(11) default NULL, + PRIMARY KEY (`id`) +); + +CREATE TABLE `aros` ( + `id` int(11) NOT NULL auto_increment, + `user_id` int(11) default NULL, + `alias` varchar(255) NOT NULL default '', + `lft` int(11) default NULL, + `rght` int(11) default NULL, + PRIMARY KEY (`id`) +); + +CREATE TABLE `aros_acos` ( + `id` int(11) NOT NULL auto_increment, + `aro_id` int(11) default NULL, + `aco_id` int(11) default NULL, + `_create` int(1) NOT NULL default '0', + `_read` int(1) NOT NULL default '0', + `_update` int(1) NOT NULL default '0', + `_delete` int(11) NOT NULL default '0', + PRIMARY KEY (`id`) +); diff --git a/cake/libs/controller/components/dbacl/models/aclnode.php b/cake/libs/controller/components/dbacl/models/aclnode.php new file mode 100644 index 000000000..5e265b617 --- /dev/null +++ b/cake/libs/controller/components/dbacl/models/aclnode.php @@ -0,0 +1,194 @@ +__setTable(); + } + + function create($link_id = 0, $parent_id = null, $alias = '') + { + parent::create(); + + if (strtolower(get_class($this)) == "aclnode") + { + trigger_error(ERROR_ABSTRACT_CONSTRUCTION, E_USER_ERROR); + return NULL; + } + extract($this->__dataVars()); + + if($parent_id == null || $parent_id === 0) + { + $parent = $this->find(null, "MAX(rght)"); + $parent['lft'] = $parent[0]['MAX(rght)']; + + if($parent[0]['MAX(rght)'] == null) + { + // The tree is empty + $parent['lft'] = 0; + } + } + else + { + $parent = $this->find($this->_resolveID($parent_id, $secondary_id)); + if($parent == null || count($parent) == 0) + { + trigger_error("Null parent in {$class}::create()", E_USER_ERROR); + } + + $parent = $parent[$class]; + $this->_syncTable($table_name, 1, $parent['lft'], $parent['lft']); + } + + $return = $this->save(array($class => array( + $secondary_id => $link_id, + 'alias' => $alias, + 'lft' => $parent['lft'] + 1, + 'rght' => $parent['lft'] + 2 + ))); + + $this->setId($this->getLastInsertID()); + return $return; + } + + + function setParent($parent_id = null, $id = null) + { + if (strtolower(get_class($this)) == "aclnode") + { + trigger_error(ERROR_ABSTRACT_CONSTRUCTION, E_USER_ERROR); + return null; + } + extract($this->__dataVars()); + + if($id == null && $this->id == false) + { + return false; + } + else if($id == null) + { + $id = $this->id; + } + + $object = $this->find($this->_resolveID($id, $secondary_id)); + if($object == null || count($object) == 0) + { + // Couldn't find object + return false; + } + $parent = $this->getParent(intval($object[$class][$secondary_id])); + + // Node is already at root, or new parent == old parent + if(($parent == null && $parent_id == null) || ($parent_id == $parent[$class][$secondary_id]) || ($parent_id == $parent[$class]['alias'])) + { + return false; + } + + if($parent_id != null && $parent[$class]['lft'] <= $object[$class]['lft'] && $parent[$class]['rght'] >= $object[$class]['rght']) + { + // Can't move object inside self or own child + return false; + } + $this->_syncTable($table_name, 0, $object[$class]['lft'], $object[$class]['lft']); + + if($parent_id == null) + { + $parent = $this->find(null, "MAX(rght)"); + $parent['lft'] = $parent[0]['MAX(rght)']; + } + else + { + $parent = $this->find($this->_resolveID($parent_id, $secondary_id)); + $parent = $parent[$class]; + $this->_syncTable($table_name, 1, $parent['lft'], $parent['lft']); + } + + $object[$class]['lft'] = $parent['lft'] + 1; + $object[$class]['rght'] = $parent['lft'] + 2; + $this->save($object); + + if($parent['lft'] == 0) + { + $this->_syncTable($table_name, 2, $parent['lft'], $parent['lft']); + } + + } + + + function getParent($id) + { + $path = $this->getPath($id); + if($path == null || count($path) < 2) + { + return null; + } + else + { + return $path[count($path) - 2]; + } + } + + function getPath($id) + { + if (strtolower(get_class($this)) == "aclnode") + { + trigger_error(ERROR_ABSTRACT_CONSTRUCTION, E_USER_ERROR); + return NULL; + } + extract($this->__dataVars()); + + $item = $this->find($this->_resolveID($id, $secondary_id)); + return $this->findAll("lft <= {$item[$class]['lft']} and rght >= {$item[$class]['rght']}"); + } + + function getChildren($id) + { + if (strtolower(get_class($this)) == "aclnode") + { + trigger_error(ERROR_ABSTRACT_CONSTRUCTION, E_USER_ERROR); + return NULL; + } + extract($this->__dataVars()); + + $item = $this->find($this->_resolveID($id, $secondary_id)); + return $this->findAll("lft > {$item[$class]['lft']} and rght < {$item[$class]['rght']}"); + } + + function _resolveID($id, $fKey) + { + $key = (is_string($id) ? 'alias' : $fKey); + $val = (is_string($id) ? '"' . addslashes($id) . '"' : $id); + return "{$key} = {$val}"; + } + + function _syncTable($table, $dir, $lft, $rght) + { + $shift = ($dir == 2 ? 1 : 2); + $this->db->query("UPDATE $table SET rght = rght " . ($dir > 0 ? "+" : "-") . " {$shift} WHERE rght > " . $rght); + $this->db->query("UPDATE $table SET lft = lft " . ($dir > 0 ? "+" : "-") . " {$shift} WHERE lft > " . $lft); + } + + function __dataVars() + { + $vars = array(); + $class = strtolower(get_class($this)); + $vars['secondary_id'] = ($class == 'aro' ? 'user_id' : 'object_id'); + $vars['data_name'] = $class; + $vars['table_name'] = $class . 's'; + $vars['class'] = ucwords($class); + return $vars; + } + + function __setTable() + { + $this->table = strtolower(get_class($this)) . "s"; + } +} + +?> \ No newline at end of file diff --git a/cake/libs/controller/components/dbacl/models/aco.php b/cake/libs/controller/components/dbacl/models/aco.php new file mode 100644 index 000000000..9eda95f84 --- /dev/null +++ b/cake/libs/controller/components/dbacl/models/aco.php @@ -0,0 +1,10 @@ + \ No newline at end of file diff --git a/cake/libs/controller/components/dbacl/models/acoaction.php b/cake/libs/controller/components/dbacl/models/acoaction.php new file mode 100644 index 000000000..0e2c65492 --- /dev/null +++ b/cake/libs/controller/components/dbacl/models/acoaction.php @@ -0,0 +1,10 @@ + \ No newline at end of file diff --git a/cake/libs/controller/components/dbacl/models/aro.php b/cake/libs/controller/components/dbacl/models/aro.php new file mode 100644 index 000000000..b43b4f884 --- /dev/null +++ b/cake/libs/controller/components/dbacl/models/aro.php @@ -0,0 +1,9 @@ + \ No newline at end of file diff --git a/cake/libs/controller/components/dbacl/models/aros_aco.php b/cake/libs/controller/components/dbacl/models/aros_aco.php new file mode 100644 index 000000000..88c1978b2 --- /dev/null +++ b/cake/libs/controller/components/dbacl/models/aros_aco.php @@ -0,0 +1,9 @@ + \ No newline at end of file diff --git a/app/controllers/components/my_acl.php b/cake/libs/controller/components/iniacl/ini_acl.php similarity index 95% rename from app/controllers/components/my_acl.php rename to cake/libs/controller/components/iniacl/ini_acl.php index bda46bc57..26fc4bfd1 100644 --- a/app/controllers/components/my_acl.php +++ b/cake/libs/controller/components/iniacl/ini_acl.php @@ -11,7 +11,8 @@ * CakePHP : Rapid Development Framework * Copyright (c) 2005, CakePHP Authors/Developers * - * Author(s): Larry E. Masters aka PhpNut + * Author(s): Michal Tatarynowicz aka Pies + * Larry E. Masters aka PhpNut * Kamil Dzielinski aka Brego * * Licensed under The MIT License @@ -30,7 +31,7 @@ * @license http://www.opensource.org/licenses/mit-license.php The MIT License */ -uses(DS.'controller'.DS.'components'.DS.'acl_base'); +uses('controller/components/acl_base'); /** * In this file you can extend the AclBase. @@ -39,7 +40,7 @@ uses(DS.'controller'.DS.'components'.DS.'acl_base'); * @subpackage cake.cake.app.controllers.componenets */ -class MyACL extends AclBase +class INI_ACL extends AclBase { /** * The constructor must be overridden, as AclBase is abstract. @@ -58,7 +59,7 @@ class MyACL extends AclBase * @param string $aco * @return boolean */ - function check($aro, $aco) + function check($aro, $aco, $aco_action = null) { $aclConfig = $this->readConfigFile(CONFIGS . 'acl.ini.php'); diff --git a/cake/libs/controller/components/session.php b/cake/libs/controller/components/session.php index c881cfb29..4d2eaa7c7 100644 --- a/cake/libs/controller/components/session.php +++ b/cake/libs/controller/components/session.php @@ -70,11 +70,12 @@ class SessionComponent extends Object * Enter description here... * * Use like this. $this->Session->read('Controller.sessKey'); + * Calling the method without a param will return all session vars * * @param unknown_type $name * @return unknown */ - function read($name) + function read($name = null) { return $this->CakeSession->readSessionVar($name); } diff --git a/cake/libs/security.php b/cake/libs/security.php index 136e85b34..359511609 100644 --- a/cake/libs/security.php +++ b/cake/libs/security.php @@ -80,6 +80,60 @@ class Security extends Object { return true; } -} + + function hash($string, $type='sha1') + { + $type = strtolower($type); + if ($type == 'sha1') + { + if (function_exists('sha1')) + { + return sha1($string); + } + else + { + $type = 'sha256'; + } + } + if ($type == 'sha256') + { + if (function_exists('mhash')) + { + return bin2hex(mhash(MHASH_SHA256, $string)); + } + else + { + $type = 'md5'; + } + } + if ($type == 'md5') + { + return md5($string); + } + } + + function cipher($text, $key) + { + if (!defined('CIPHER_SEED')) + { + //This is temporary will change later + define('CIPHER_SEED', 'mKEZGy8AB8FErX4t'); + } + srand(CIPHER_SEED); + + $out = ''; + for($i = 0; $i < strlen($text); $i++) + { + for($j = 0; $j < ord(substr($key, $i % strlen($key), 1)); $j++) + { + $toss = rand(0, 255); + } + + $mask = rand(0, 255); + $out .= chr(ord(substr($text, $i, 1)) ^ $mask); + } + return $out; + } +} ?> \ No newline at end of file diff --git a/cake/libs/session.php b/cake/libs/session.php index 85b9fb545..0dc98990e 100644 --- a/cake/libs/session.php +++ b/cake/libs/session.php @@ -156,7 +156,6 @@ class CakeSession extends Object */ function getError($errorNumber) { - if(!is_array($this->error) || !array_key_exists($errorNumber, $this->error)) { return false; @@ -202,8 +201,12 @@ class CakeSession extends Object * @param unknown_type $name * @return unknown */ - function readSessionVar($name) + function readSessionVar($name = null) { + if(is_null($name)) + { + return $this->returnSessionVars(); + } if($this->checkSessionVar($name)) { @@ -214,6 +217,24 @@ class CakeSession extends Object return false; } +/** + * Enter description here... + * + * @param unknown_type $name + * @return unknown + */ + function returnSessionVars() + { + + if(!empty($_SESSION)) + { + $result = eval("return ".$_SESSION.";"); + return $result; + } + $this->_setError(2, "No Session vars set"); + return false; + } + /** * Enter description here... * diff --git a/cake/libs/view/helpers/ajax.php b/cake/libs/view/helpers/ajax.php index eb3d6c949..6bc33641a 100644 --- a/cake/libs/view/helpers/ajax.php +++ b/cake/libs/view/helpers/ajax.php @@ -159,7 +159,7 @@ class AjaxHelper extends Helper } else { - $html_options['onclick'] = $this->remoteFunction($options) . " return false;"; + $html_options['onclick'] = $this->remoteFunction($options) . "; return false;"; return $this->Html->link($title, $href, $html_options); } } diff --git a/cake/scripts/acl.php b/cake/scripts/acl.php new file mode 100644 index 000000000..0e0003358 --- /dev/null +++ b/cake/scripts/acl.php @@ -0,0 +1,335 @@ +#!/usr/bin/php -q +__construct($command, $args); + } + + function __construct ($command, $args) + { + $acl = new AclComponent(); + $this->acl = $acl->getACL(); + + $this->args = $args; + + $this->controller =& new Controller(); + $this->controller->constructClasses(); + + $this->stdin = fopen('php://stdin', 'r'); + $this->stdout = fopen('php://stdout', 'w'); + $this->stderr = fopen('php://stderr', 'w'); + + //Check to see if DB ACL is enabled + if (ACL_CLASSNAME != 'DB_ACL') + { + $out = "--------------------------------------------------\n"; + $out .= "Error: Your current Cake configuration is set to \n"; + $out .= "an ACL implementation other than DB. Please change \n"; + $out .= "your core config to reflect your decision to use \n"; + $out .= "DB_ACL before attempting to use this script.\n"; + $out .= "--------------------------------------------------\n"; + $out .= "Current ACL Classname: " . ACL_CLASSNAME . "\n"; + $out .= "--------------------------------------------------\n"; + + fwrite($this->stderr, $out); + exit(); + } + + switch ($command) + { + case 'create': + $this->create(); + break; + case 'delete': + $this->delete(); + break; + case 'setParent': + $this->setParent(); + break; + case 'getPath': + $this->getPath(); + break; + case 'grant': + $this->grant(); + break; + case 'deny': + $this->deny(); + break; + case 'inherit': + $this->inherit(); + break; + case 'view': + $this->view(); + break; + case 'help': + $this->help(); + break; + default: + fwrite($this->stderr, "Unknown ACL command '$command'.\nFor usage, try 'php acl.php help'.\n\n"); + } + + } + + function create() + { + $this->checkArgNumber(4, 'create'); + $this->checkNodeType(); + extract($this->__dataVars()); + $node = &new $class; + $parent = $this->nodeExists($this->args[0], $this->args[2]); + + if (!$parent) + { + fwrite($this->stdout, "Warning: Parent not found. Creating this object with the root node as parent.\n"); + $parent = $node->find(null, "MAX(rght)"); + } + + $node->create($this->args[1], $parent[$data_name]['id'], $this->args[3]); + + fwrite($this->stdout, "New $class '".$this->args[3]."' created.\n\n"); + } + + function delete() + { + $this->checkArgNumber(2, 'delete'); + $this->checkNodeType(); + extract($this->__dataVars()); + $node = &new $class; + + //What about children? + //$node->del($this->args[1]); + //fwrite($this->stdout, "$class deleted.\n\n"); + } + + function setParent() + { + $this->checkArgNumber(3, 'setParent'); + $this->checkNodeType(); + extract($this->__dataVars()); + $node = &new $class; + $parent = $this->nodeExists($this->args[0], $this->args[2]); + + if (!$parent) + { + fwrite($this->stdout, "Warning: Parent not found. Setting this object with the root node as parent.\n"); + $parent = $node->find(null, "MAX(rght)"); + } + + $node = &new $class; + + $node->setParent($parent[$data_name]['id'], $this->args[1]); + fwrite($this->stdout, "Node parent set to ".$this->args[2]."\n\n"); + } + + function getPath() + { + $this->checkArgNumber(2, 'getPath'); + $this->checkNodeType(); + extract($this->__dataVars()); + + $suppliedNode = $this->nodeExists($this->args[0], $this->args[1]); + + if (!$suppliedNode) + { + $this->displayError("Supplied Node '".$args[1]."' not found. No tree returned."); + } + + $node = &new $class; + + fwrite($this->stdout, print_r($node->getPath($this->args[1]))); + } + + function grant() + { + $this->checkArgNumber(3, 'grant'); + //add existence checks for nodes involved + + + $this->acl->allow($this->args[0], $this->args[1], $this->args[2]); + fwrite($this->stdout, "Permission granted..."); + } + + function deny() + { + $this->checkArgNumber(3, 'deny'); + //add existence checks for nodes involved + + $this->acl->deny($this->args[0], $this->args[1], $this->args[2]); + fwrite($this->stdout, "Permission denied..."); + } + + function inherit() {} + + function view() {} + + function help() + { + $out = "Usage: php acl.php ...\n"; + $out .= "-----------------------------------------------\n"; + $out .= "Commands:\n"; + $out .= "\n"; + + $out .= "\tcreate aro|aco \n"; + $out .= "\t\tCreates a new ACL object under the parent specified by parent_id (see\n"; + $out .= "\t\t'view'). The link_id allows you to link a current user object to Cake's\n"; + $out .= "\t\tACL structures. The alias parameter allows you address your object\n"; + $out .= "\t\tusing a non-integer ID. Example: \"\$php acl.php create aro 0 jda57 John\"\n"; + $out .= "\t\twould create a new ARO object at the root of the tree, linked to jda57\n"; + $out .= "\t\tin your users table, with an internal alias 'John'."; + $out .= "\n"; + $out .= "\n"; + + $out .= "\tdelete aro|aco \n"; + $out .= "\t\tDeletes the ACL object with the specified ID (see 'view').\n"; + $out .= "\n"; + $out .= "\n"; + + $out .= "\tsetParent aro|aco \n"; + $out .= "\t\tUsed to set the parent of the ACL object specified by to the ID\n"; + $out .= "\t\tspecified by .\n"; + $out .= "\n"; + $out .= "\n"; + + $out .= "\tgetPath aro|aco \n"; + $out .= "\t\tReturns the path to the ACL object specified by . This command is\n"; + $out .= "\t\tis useful in determining the inhertiance of permissions for a certain\n"; + $out .= "\t\tobject in the tree.\n"; + $out .= "\n"; + $out .= "\n"; + + $out .= "\tgrant \n"; + $out .= "\t\tUse this command to grant ACL permissions. Once executed, the ARO\n"; + $out .= "\t\tspecified (and its children, if any) will have ALLOW access to the\n"; + $out .= "\t\tspecified ACO action (and the ACO's children, if any).\n"; + $out .= "\n"; + $out .= "\n"; + + $out .= "\tdeny \n"; + $out .= "\t\tUse this command to deny ACL permissions. Once executed, the ARO\n"; + $out .= "\t\tspecified (and its children, if any) will have DENY access to the\n"; + $out .= "\t\tspecified ACO action (and the ACO's children, if any).\n"; + $out .= "\n"; + $out .= "\n"; + + $out .= "\tinherit \n"; + $out .= "\t\tUse this command to force a child ARO object to inherit its\n"; + $out .= "\t\tpermissions settings from its parent.\n"; + $out .= "\n"; + $out .= "\n"; + + $out .= "\tview aro|aco [id]\n"; + $out .= "\t\tThe view command will return the ARO or ACO tree. The optional\n"; + $out .= "\t\tid/alias parameter allows you to return only a portion of the requested\n"; + $out .= "\t\ttree.\n"; + $out .= "\n"; + $out .= "\n"; + + $out .= "\thelp\n"; + $out .= "\t\tDisplays this help message.\n"; + $out .= "\n"; + $out .= "\n"; + + fwrite($this->stdout, $out); + } + + function displayError($title, $msg) + { + $out = "\n"; + $out .= "Error: $title\n"; + $out .= "$msg\n"; + $out .= "\n"; + fwrite($this->stdout, $out); + exit(); + } + + function checkArgNumber($expectedNum, $command) + { + if (count($this->args) != $expectedNum) + { + $this->displayError('Wrong number of parameters: '.count($this->args), 'Please type \'php acl.php help\' for help on usage of the '.$command.' command.'); + } + } + + function checkNodeType() + { + if ($this->args[0] != 'aco' && $this->args[0] != 'aro') + { + $this->displayError("Missing/Unknown node type: '".$this->args[0]."'", 'Please specify which ACL object type you wish to create.'); + } + } + + function nodeExists($type, $id) + { + fwrite($this->stdout, "Check to see if $type with ID = $id exists...\n"); + extract($this->__dataVars($type)); + $node = &new $class; + + $possibility = $node->find('id = ' . $id); + + if (empty($possibility[$data_name]['id'])) + { + return false; + } + else + { + return $possibility; + } + } + + function __dataVars($type = null) + { + if ($type == null) + { + $type = $this->args[0]; + } + + $vars = array(); + $class = ucwords($type); + $vars['secondary_id'] = ($class == 'aro' ? 'user_id' : 'object_id'); + $vars['data_name'] = $type; + $vars['table_name'] = $class . 's'; + $vars['class'] = $class; + return $vars; + } +} +?>