From ae7ab27d20899d60be268e954d99f57bf6157e7d Mon Sep 17 00:00:00 2001 From: nate Date: Wed, 23 May 2007 18:12:05 +0000 Subject: [PATCH] Refactoring ACL class locations git-svn-id: https://svn.cakephp.org/repo/branches/1.2.x.x@5156 3807eeeb-6ff5-0310-8944-8be069107fe0 --- cake/libs/controller/components/acl.php | 395 +++++++++++++++++++++++- cake/libs/model/db_acl.php | 243 --------------- cake/libs/model/ini_acl.php | 174 ----------- 3 files changed, 391 insertions(+), 421 deletions(-) delete mode 100644 cake/libs/model/ini_acl.php diff --git a/cake/libs/controller/components/acl.php b/cake/libs/controller/components/acl.php index 08bfbb001..64be07675 100644 --- a/cake/libs/controller/components/acl.php +++ b/cake/libs/controller/components/acl.php @@ -26,6 +26,8 @@ * @lastmodified $Date$ * @license http://www.opensource.org/licenses/mit-license.php The MIT License */ +uses('model' . DS . 'db_acl'); + /** * Access Control List factory class. * @@ -35,8 +37,8 @@ * @subpackage cake.cake.libs.controller.components */ class AclComponent extends Object { + var $_instance = null; - var $controller = true; /** * Constructor. Will return an instance of the correct ACL class. * @@ -51,9 +53,6 @@ class AclComponent extends Object { */ function &getACL() { if($this->_instance == null) { - $file = explode(DS, ACL_FILENAME); - $file = array_pop($file); - uses('model' . DS . $file); $classname = ACL_CLASSNAME; $this->_instance = new $classname; $this->_instance->initialize($this); @@ -205,5 +204,393 @@ class AclBase extends Object { function initialize(&$component) { } } +/** + * In this file you can extend the AclBase. + * + * @package cake + * @subpackage cake.cake.libs.model + */ +class DB_ACL extends AclBase { +/** + * Enter description here... + * + */ + function __construct() { + parent::__construct(); + $this->Aro =& new Aro(); + $this->Aco =& new Aco(); + } +/** + * Enter description here... + * + * @param unknown_type $aro + * @param unknown_type $aco + * @param unknown_type $action + * @return unknown + */ + function initialize(&$component) { + $component->Aro =& $this->Aro; + $component->Aco =& $this->Aco; + } +/** + * Enter description here... + * + * @param unknown_type $aro + * @param unknown_type $aco + * @param unknown_type $action + * @return unknown + */ + function check($aro, $aco, $action = "*") { + + if ($aro == null || $aco == null) { + return false; + } + + $permKeys = $this->_getAcoKeys($this->Aro->Permission->loadInfo()); + $aroPath = $this->Aro->node($aro); + $acoPath = new Set($this->Aco->node($aco)); + + if (empty($aroPath) || empty($acoPath)) { + trigger_error("DB_ACL::check() - Failed ARO/ACO node lookup in permissions check. Node references:\nAro: " . print_r($aro, true) . "\nAco: " . print_r($aco, true), E_USER_WARNING); + return false; + } + if ($acoPath->get() == null || $acoPath->get() == array()) { + trigger_error("DB_ACL::check() - Failed ACO node lookup in permissions check. Node references:\nAro: " . print_r($aro, true) . "\nAco: " . print_r($aco, true), E_USER_WARNING); + return false; + } + + $aroNode = $aroPath[0]; + $acoNode = $acoPath->get(); + $acoNode = $acoNode[0]; + + if ($action != '*' && !in_array('_' . $action, $permKeys)) { + trigger_error(sprintf(__("ACO permissions key %s does not exist in DB_ACL::check()", true), $action), E_USER_NOTICE); + return false; + } + + for($i = count($aroPath) - 1; $i >= 0; $i--) { + $perms = $this->Aro->Permission->findAll( + array( + 'Permission.aro_id' => $aroPath[$i]['Aro']['id'], + 'Permission.aco_id' => $acoPath->extract('{n}.Aco.id') + ), + null, array('Aco.lft' => 'desc'), null, null, 0 + ); + + if (empty($perms)) { + continue; + } else { + foreach(Set::extract($perms, '{n}.Permission') as $perm) { + if ($action == '*') { + // ARO must be cleared for ALL ACO actions + foreach($permKeys as $key) { + if (!empty($perm)) { + if ($perm[$key] != 1) { + return false; + } + } + } + return true; + } else { + switch($perm['_' . $action]) { + case -1: + return false; + case 0: + continue; + break; + case 1: + return true; + break; + } + } + } + } + } + return false; + } +/** + * Allow + * + * @return boolean + */ + function allow($aro, $aco, $action = "*", $value = 1) { + $perms = $this->getAclLink($aro, $aco); + $permKeys = $this->_getAcoKeys($this->Aro->Permission->loadInfo()); + $save = array(); + + if ($perms == false) { + trigger_error(__('DB_ACL::allow() - Invalid node', true), E_USER_WARNING); + return false; + } + + if (isset($perms[0])) { + $save = $perms[0]['Permission']; + } + + if ($action == "*") { + $permKeys = $this->_getAcoKeys($this->Aro->Permission->loadInfo()); + + foreach($permKeys as $key) { + $save[$key] = $value; + } + } else { + if (in_array('_' . $action, $permKeys)) { + $save['_' . $action] = $value; + } else { + trigger_error(__('DB_ACL::allow() - Invalid ACO action', true), E_USER_WARNING); + return false; + } + } + + $save['aro_id'] = $perms['aro']; + $save['aco_id'] = $perms['aco']; + + if ($perms['link'] != null && count($perms['link']) > 0) { + $save['id'] = $perms['link'][0]['Permission']['id']; + } + return $this->Aro->Permission->save(array('Permission' => $save)); + } +/** + * 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); + } +/** + * Private method + * + */ + function &__getObject($id = null, $object) { + if ($id == null) { + trigger_error(__('Null id provided in DB_ACL::get', true) . $object, E_USER_WARNING); + return null; + } + + if (is_numeric($id)) { + $conditions = array("{$object}.foreign_key" => $id); + } else { + $conditions = array("{$object}.alias" => $id); + } + + $tmp = $this->{$object}->find($conditions); + $this->{$object}->id = $tmp[$object]['id']; + return $this->{$object}; + } +/** + * Get an array of access-control links between the given Aro and Aco + * + * @param mixed $aro + * @param mixed $aco + * @return array + */ + function getAclLink($aro, $aco) { + $Link = new Permission(); + + $obj = array(); + $obj['Aro'] = $this->Aro->node($aro); + $obj['Aco'] = $this->Aco->node($aco); + + if (empty($obj['Aro']) || empty($obj['Aco'])) { + return false; + } + + return array( + 'aro' => Set::extract($obj, 'Aro.0.Aro.id'), + 'aco' => Set::extract($obj, 'Aco.0.Aco.id'), + 'link' => $this->Aro->Permission->findAll(array( + 'Permission.aro_id' => Set::extract($obj, 'Aro.0.Aro.id'), + 'Permission.aco_id' => Set::extract($obj, 'Aco.0.Aco.id') + )) + ); + } +/** + * Enter description here... + * + * @param unknown_type $keys + * @return unknown + */ + function _getAcoKeys($keys) { + $newKeys = array(); + $keys = $keys->extract('{n}.name'); + + foreach($keys as $key) { + if (!in_array($key, array('id', 'aro_id', 'aco_id'))) { + $newKeys[] = $key; + } + } + return $newKeys; + } +} +/** + * In this file you can extend the AclBase. + * + * @package cake + * @subpackage cake.cake.libs.model.iniacl + */ +class INI_ACL extends AclBase { +/** + * Array with configuration, parsed from ini file + */ + var $config = null; +/** + * The constructor must be overridden, as AclBase is abstract. + * + */ + function __construct() { + } +/** + * Main ACL check function. Checks to see if the ARO (access request object) has access to the ACO (access control object). + * Looks at the acl.ini.php file for permissions (see instructions in/config/acl.ini.php). + * + * @param string $aro + * @param string $aco + * @return boolean + */ + function check($aro, $aco, $aco_action = null) { + if ($this->config == null) { + $this->config = $this->readConfigFile(CONFIGS . 'acl.ini.php'); + } + $aclConfig = $this->config; + + //First, if the user is specifically denied, then DENY + if (isset($aclConfig[$aro]['deny'])) { + $userDenies = $this->arrayTrim(explode(",", $aclConfig[$aro]['deny'])); + + if (array_search($aco, $userDenies)) { + //echo "User Denied!"; + return false; + } + } + + //Second, if the user is specifically allowed, then ALLOW + if (isset($aclConfig[$aro]['allow'])) { + $userAllows = $this->arrayTrim(explode(",", $aclConfig[$aro]['allow'])); + + if (array_search($aco, $userAllows)) { + //echo "User Allowed!"; + return true; + } + } + + //Check group permissions + if (isset($aclConfig[$aro]['groups'])) { + $userGroups = $this->arrayTrim(explode(",", $aclConfig[$aro]['groups'])); + + foreach($userGroups as $group) { + //If such a group exists, + if (array_key_exists($group, $aclConfig)) { + //If the group is specifically denied, then DENY + if (isset($aclConfig[$group]['deny'])) { + $groupDenies=$this->arrayTrim(explode(",", $aclConfig[$group]['deny'])); + + if (array_search($aco, $groupDenies)) { + //echo("Group Denied!"); + return false; + } + } + + //If the group is specifically allowed, then ALLOW + if (isset($aclConfig[$group]['allow'])) { + $groupAllows = $this->arrayTrim(explode(",", $aclConfig[$group]['allow'])); + + if (array_search($aco, $groupAllows)) { + //echo("Group Allowed!"); + return true; + } + } + } + } + } + + //Default, DENY + //echo("DEFAULT: DENY."); + return false; + } +/** + * Parses an INI file and returns an array that reflects the INI file's section structure. Double-quote friendly. + * + * @param string $fileName + * @return array + */ + function readConfigFile($fileName) { + $fileLineArray = file($fileName); + + foreach($fileLineArray as $fileLine) { + $dataLine = trim($fileLine); + $firstChar = substr($dataLine, 0, 1); + + if ($firstChar != ';' && $dataLine != '') { + if ($firstChar == '[' && substr($dataLine, -1, 1) == ']') { + $sectionName = preg_replace('/[\[\]]/', '', $dataLine); + } else { + $delimiter = strpos($dataLine, '='); + + if ($delimiter > 0) { + $key = strtolower(trim(substr($dataLine, 0, $delimiter))); + $value = trim(substr($dataLine, $delimiter + 1)); + + if (substr($value, 0, 1) == '"' && substr($value, -1) == '"') { + $value = substr($value, 1, -1); + } + + $iniSetting[$sectionName][$key]=stripcslashes($value); + } else { + if (!isset($sectionName)) { + $sectionName = ''; + } + + $iniSetting[$sectionName][strtolower(trim($dataLine))]=''; + } + } + } else { + } + } + + return $iniSetting; + } +/** + * Removes trailing spaces on all array elements (to prepare for searching) + * + * @param array $array + * @return array + */ + function arrayTrim($array) { + foreach($array as $element) { + $element = trim($element); + } + + //Adding this element keeps array_search from returning 0: + //0 is the first key, which may be correct, but 0 is interpreted as false. + //Adding this element makes all the keys be positive integers. + array_unshift($array, ""); + return $array; + } +} ?> \ No newline at end of file diff --git a/cake/libs/model/db_acl.php b/cake/libs/model/db_acl.php index 33f7347d7..949e4432f 100644 --- a/cake/libs/model/db_acl.php +++ b/cake/libs/model/db_acl.php @@ -36,249 +36,6 @@ if (!defined('ACL_DATABASE')) { * Load Model and AppModel */ loadModel(); -/** - * In this file you can extend the AclBase. - * - * @package cake - * @subpackage cake.cake.libs.model - */ -class DB_ACL extends AclBase { -/** - * Enter description here... - * - */ - function __construct() { - parent::__construct(); - $this->Aro =& new Aro(); - $this->Aco =& new Aco(); - } -/** - * Enter description here... - * - * @param unknown_type $aro - * @param unknown_type $aco - * @param unknown_type $action - * @return unknown - */ - function initialize(&$component) { - $component->Aro =& $this->Aro; - $component->Aco =& $this->Aco; - } -/** - * Enter description here... - * - * @param unknown_type $aro - * @param unknown_type $aco - * @param unknown_type $action - * @return unknown - */ - function check($aro, $aco, $action = "*") { - - if ($aro == null || $aco == null) { - return false; - } - - $permKeys = $this->_getAcoKeys($this->Aro->Permission->loadInfo()); - $aroPath = $this->Aro->node($aro); - $acoPath = new Set($this->Aco->node($aco)); - - if (empty($aroPath) || empty($acoPath)) { - trigger_error("DB_ACL::check() - Failed ARO/ACO node lookup in permissions check. Node references:\nAro: " . print_r($aro, true) . "\nAco: " . print_r($aco, true), E_USER_WARNING); - return false; - } - if ($acoPath->get() == null || $acoPath->get() == array()) { - trigger_error("DB_ACL::check() - Failed ACO node lookup in permissions check. Node references:\nAro: " . print_r($aro, true) . "\nAco: " . print_r($aco, true), E_USER_WARNING); - return false; - } - - $aroNode = $aroPath[0]; - $acoNode = $acoPath->get(); - $acoNode = $acoNode[0]; - - if ($action != '*' && !in_array('_' . $action, $permKeys)) { - trigger_error(sprintf(__("ACO permissions key %s does not exist in DB_ACL::check()", true), $action), E_USER_NOTICE); - return false; - } - - for($i = count($aroPath) - 1; $i >= 0; $i--) { - $perms = $this->Aro->Permission->findAll( - array( - 'Permission.aro_id' => $aroPath[$i]['Aro']['id'], - 'Permission.aco_id' => $acoPath->extract('{n}.Aco.id') - ), - null, array('Aco.lft' => 'desc'), null, null, 0 - ); - - if (empty($perms)) { - continue; - } else { - foreach(Set::extract($perms, '{n}.Permission') as $perm) { - if ($action == '*') { - // ARO must be cleared for ALL ACO actions - foreach($permKeys as $key) { - if (!empty($perm)) { - if ($perm[$key] != 1) { - return false; - } - } - } - return true; - } else { - switch($perm['_' . $action]) { - case -1: - return false; - case 0: - continue; - break; - case 1: - return true; - break; - } - } - } - } - } - return false; - } -/** - * Allow - * - * @return boolean - */ - function allow($aro, $aco, $action = "*", $value = 1) { - $perms = $this->getAclLink($aro, $aco); - $permKeys = $this->_getAcoKeys($this->Aro->Permission->loadInfo()); - $save = array(); - - if ($perms == false) { - trigger_error(__('DB_ACL::allow() - Invalid node', true), E_USER_WARNING); - return false; - } - - if (isset($perms[0])) { - $save = $perms[0]['Permission']; - } - - if ($action == "*") { - $permKeys = $this->_getAcoKeys($this->Aro->Permission->loadInfo()); - - foreach($permKeys as $key) { - $save[$key] = $value; - } - } else { - if (in_array('_' . $action, $permKeys)) { - $save['_' . $action] = $value; - } else { - trigger_error(__('DB_ACL::allow() - Invalid ACO action', true), E_USER_WARNING); - return false; - } - } - - $save['aro_id'] = $perms['aro']; - $save['aco_id'] = $perms['aco']; - - if ($perms['link'] != null && count($perms['link']) > 0) { - $save['id'] = $perms['link'][0]['Permission']['id']; - } - return $this->Aro->Permission->save(array('Permission' => $save)); - } -/** - * 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); - } -/** - * Private method - * - */ - function &__getObject($id = null, $object) { - if ($id == null) { - trigger_error(__('Null id provided in DB_ACL::get', true) . $object, E_USER_WARNING); - return null; - } - - if (is_numeric($id)) { - $conditions = array("{$object}.foreign_key" => $id); - } else { - $conditions = array("{$object}.alias" => $id); - } - - $tmp = $this->{$object}->find($conditions); - $this->{$object}->id = $tmp[$object]['id']; - return $this->{$object}; - } -/** - * Get an array of access-control links between the given Aro and Aco - * - * @param mixed $aro - * @param mixed $aco - * @return array - */ - function getAclLink($aro, $aco) { - $Link = new Permission(); - - $obj = array(); - $obj['Aro'] = $this->Aro->node($aro); - $obj['Aco'] = $this->Aco->node($aco); - - if (empty($obj['Aro']) || empty($obj['Aco'])) { - return false; - } - - return array( - 'aro' => Set::extract($obj, 'Aro.0.Aro.id'), - 'aco' => Set::extract($obj, 'Aco.0.Aco.id'), - 'link' => $this->Aro->Permission->findAll(array( - 'Permission.aro_id' => Set::extract($obj, 'Aro.0.Aro.id'), - 'Permission.aco_id' => Set::extract($obj, 'Aco.0.Aco.id') - )) - ); - } -/** - * Enter description here... - * - * @param unknown_type $keys - * @return unknown - */ - function _getAcoKeys($keys) { - $newKeys = array(); - $keys = $keys->extract('{n}.name'); - - foreach($keys as $key) { - if (!in_array($key, array('id', 'aro_id', 'aco_id'))) { - $newKeys[] = $key; - } - } - return $newKeys; - } -} /** * Short description for file. * diff --git a/cake/libs/model/ini_acl.php b/cake/libs/model/ini_acl.php deleted file mode 100644 index cc128a122..000000000 --- a/cake/libs/model/ini_acl.php +++ /dev/null @@ -1,174 +0,0 @@ - - * Copyright 2005-2007, Cake Software Foundation, Inc. - * 1785 E. Sahara Avenue, Suite 490-204 - * Las Vegas, Nevada 89104 - * - * Licensed under The MIT License - * Redistributions of files must retain the above copyright notice. - * - * @filesource - * @copyright Copyright 2005-2007, Cake Software Foundation, Inc. - * @link http://www.cakefoundation.org/projects/info/cakephp CakePHP(tm) Project - * @package cake - * @subpackage cake.cake.libs.model.iniacl - * @since CakePHP(tm) v 0.2.9 - * @version $Revision$ - * @modifiedby $LastChangedBy$ - * @lastmodified $Date$ - * @license http://www.opensource.org/licenses/mit-license.php The MIT License - */ -/** - * In this file you can extend the AclBase. - * - * @package cake - * @subpackage cake.cake.libs.model.iniacl - */ -class INI_ACL extends AclBase{ -/** - * Array with configuration, parsed from ini file - */ - var $config = null; -/** - * The constructor must be overridden, as AclBase is abstract. - * - */ - function __construct() { - } -/** - * Main ACL check function. Checks to see if the ARO (access request object) has access to the ACO (access control object). - * Looks at the acl.ini.php file for permissions (see instructions in/config/acl.ini.php). - * - * @param string $aro - * @param string $aco - * @return boolean - */ - function check($aro, $aco, $aco_action = null) { - if ($this->config == null) { - $this->config = $this->readConfigFile(CONFIGS . 'acl.ini.php'); - } - $aclConfig = $this->config; - - //First, if the user is specifically denied, then DENY - if (isset($aclConfig[$aro]['deny'])) { - $userDenies = $this->arrayTrim(explode(",", $aclConfig[$aro]['deny'])); - - if (array_search($aco, $userDenies)) { - //echo "User Denied!"; - return false; - } - } - - //Second, if the user is specifically allowed, then ALLOW - if (isset($aclConfig[$aro]['allow'])) { - $userAllows = $this->arrayTrim(explode(",", $aclConfig[$aro]['allow'])); - - if (array_search($aco, $userAllows)) { - //echo "User Allowed!"; - return true; - } - } - - //Check group permissions - if (isset($aclConfig[$aro]['groups'])) { - $userGroups = $this->arrayTrim(explode(",", $aclConfig[$aro]['groups'])); - - foreach($userGroups as $group) { - //If such a group exists, - if (array_key_exists($group, $aclConfig)) { - //If the group is specifically denied, then DENY - if (isset($aclConfig[$group]['deny'])) { - $groupDenies=$this->arrayTrim(explode(",", $aclConfig[$group]['deny'])); - - if (array_search($aco, $groupDenies)) { - //echo("Group Denied!"); - return false; - } - } - - //If the group is specifically allowed, then ALLOW - if (isset($aclConfig[$group]['allow'])) { - $groupAllows = $this->arrayTrim(explode(",", $aclConfig[$group]['allow'])); - - if (array_search($aco, $groupAllows)) { - //echo("Group Allowed!"); - return true; - } - } - } - } - } - - //Default, DENY - //echo("DEFAULT: DENY."); - return false; - } -/** - * Parses an INI file and returns an array that reflects the INI file's section structure. Double-quote friendly. - * - * @param string $fileName - * @return array - */ - function readConfigFile($fileName) { - $fileLineArray = file($fileName); - - foreach($fileLineArray as $fileLine) { - $dataLine = trim($fileLine); - $firstChar = substr($dataLine, 0, 1); - - if ($firstChar != ';' && $dataLine != '') { - if ($firstChar == '[' && substr($dataLine, -1, 1) == ']') { - $sectionName = preg_replace('/[\[\]]/', '', $dataLine); - } else { - $delimiter = strpos($dataLine, '='); - - if ($delimiter > 0) { - $key = strtolower(trim(substr($dataLine, 0, $delimiter))); - $value = trim(substr($dataLine, $delimiter + 1)); - - if (substr($value, 0, 1) == '"' && substr($value, -1) == '"') { - $value = substr($value, 1, -1); - } - - $iniSetting[$sectionName][$key]=stripcslashes($value); - } else { - if (!isset($sectionName)) { - $sectionName = ''; - } - - $iniSetting[$sectionName][strtolower(trim($dataLine))]=''; - } - } - } else { - } - } - - return $iniSetting; - } -/** - * Removes trailing spaces on all array elements (to prepare for searching) - * - * @param array $array - * @return array - */ - function arrayTrim($array) { - foreach($array as $element) { - $element = trim($element); - } - - //Adding this element keeps array_search from returning 0: - //0 is the first key, which may be correct, but 0 is interpreted as false. - //Adding this element makes all the keys be positive integers. - array_unshift($array, ""); - return $array; - } -} -?> \ No newline at end of file