2005-08-21 06:49:02 +00:00
< ? php
/* SVN FILE: $Id$ */
/**
2005-09-07 01:52:45 +00:00
* Access Control List factory class .
2006-01-12 02:10:47 +00:00
*
2005-09-07 01:52:45 +00:00
* Permissions system .
2005-08-21 06:49:02 +00:00
*
* PHP versions 4 and 5
*
2007-02-02 10:39:45 +00:00
* CakePHP ( tm ) : Rapid Development Framework < http :// www . cakephp . org />
* Copyright 2005 - 2007 , Cake Software Foundation , Inc .
2006-05-26 05:29:17 +00:00
* 1785 E . Sahara Avenue , Suite 490 - 204
* Las Vegas , Nevada 89104
2006-01-12 02:10:47 +00:00
*
2005-12-23 21:57:26 +00:00
* Licensed under The MIT License
* Redistributions of files must retain the above copyright notice .
2005-08-21 06:49:02 +00:00
*
2006-01-12 02:10:47 +00:00
* @ filesource
2007-02-02 10:39:45 +00:00
* @ copyright Copyright 2005 - 2007 , Cake Software Foundation , Inc .
* @ link http :// www . cakefoundation . org / projects / info / cakephp CakePHP ( tm ) Project
2006-05-26 05:29:17 +00:00
* @ package cake
* @ subpackage cake . cake . libs . controller . components
2007-02-02 10:39:45 +00:00
* @ since CakePHP ( tm ) v 0.10 . 0.1076
2006-05-26 05:29:17 +00:00
* @ version $Revision $
* @ modifiedby $LastChangedBy $
* @ lastmodified $Date $
* @ license http :// www . opensource . org / licenses / mit - license . php The MIT License
2005-08-21 06:49:02 +00:00
*/
2007-05-23 18:12:05 +00:00
uses ( 'model' . DS . 'db_acl' );
2005-08-21 06:49:02 +00:00
/**
* Access Control List factory class .
2006-01-12 02:10:47 +00:00
*
2005-08-21 06:49:02 +00:00
* Looks for ACL implementation class in core config , and returns an instance of that class .
*
2006-05-26 05:29:17 +00:00
* @ package cake
* @ subpackage cake . cake . libs . controller . components
2005-08-21 06:49:02 +00:00
*/
2006-06-14 18:02:37 +00:00
class AclComponent extends Object {
2007-05-23 18:12:05 +00:00
2006-06-14 18:02:37 +00:00
var $_instance = null ;
2005-12-22 01:07:28 +00:00
/**
2006-02-07 02:19:53 +00:00
* Constructor . Will return an instance of the correct ACL class .
2005-12-22 01:07:28 +00:00
*
*/
2006-06-14 18:02:37 +00:00
function __construct () {
$this -> getACL ();
}
2005-12-22 01:07:28 +00:00
/**
* Static function used to gain an instance of the correct ACL class .
*
* @ return MyACL
*/
2006-06-14 18:02:37 +00:00
function & getACL () {
2007-06-20 06:15:35 +00:00
if ( $this -> _instance == null ) {
2006-06-14 18:02:37 +00:00
$classname = ACL_CLASSNAME ;
$this -> _instance = new $classname ;
2007-05-15 20:01:44 +00:00
$this -> _instance -> initialize ( $this );
2006-11-24 17:27:11 +00:00
}
2006-06-14 18:02:37 +00:00
return $this -> _instance ;
}
2005-12-22 01:07:28 +00:00
/**
2006-02-07 02:19:53 +00:00
* Empty class defintion , to be overridden in subclasses .
2005-12-22 01:07:28 +00:00
*
*/
2006-06-14 18:02:37 +00:00
function _initACL () {
}
2005-12-22 01:07:28 +00:00
/**
* Pass - thru function for ACL check instance .
*
2006-11-24 17:27:11 +00:00
* @ param string $aro
* @ param string $aco
* @ param string $action : default = *
2005-12-22 01:07:28 +00:00
* @ return boolean
*/
2006-06-14 18:02:37 +00:00
function check ( $aro , $aco , $action = " * " ) {
return $this -> _instance -> check ( $aro , $aco , $action );
}
2005-12-22 01:07:28 +00:00
/**
* Pass - thru function for ACL allow instance .
*
2006-11-24 17:27:11 +00:00
* @ param string $aro
* @ param string $aco
* @ param string $action : default = *
2005-12-22 01:07:28 +00:00
* @ return boolean
*/
2006-06-14 18:02:37 +00:00
function allow ( $aro , $aco , $action = " * " ) {
return $this -> _instance -> allow ( $aro , $aco , $action );
}
2005-12-22 01:07:28 +00:00
/**
* Pass - thru function for ACL deny instance .
*
2006-11-24 17:27:11 +00:00
* @ param string $aro
* @ param string $aco
* @ param string $action : default = *
2005-12-22 01:07:28 +00:00
* @ return boolean
*/
2006-06-14 18:02:37 +00:00
function deny ( $aro , $aco , $action = " * " ) {
return $this -> _instance -> deny ( $aro , $aco , $action );
}
2005-12-22 01:07:28 +00:00
/**
* Pass - thru function for ACL inherit instance .
*
* @ return boolean
*/
2006-06-14 18:02:37 +00:00
function inherit ( $aro , $aco , $action = " * " ) {
return $this -> _instance -> inherit ( $aro , $aco , $action );
}
2005-12-22 01:07:28 +00:00
/**
* Pass - thru function for ACL grant instance .
*
2006-11-24 17:27:11 +00:00
* @ param string $aro
* @ param string $aco
* @ param string $action : default = *
2005-12-22 01:07:28 +00:00
* @ return boolean
*/
2006-06-14 18:02:37 +00:00
function grant ( $aro , $aco , $action = " * " ) {
return $this -> _instance -> grant ( $aro , $aco , $action );
}
2005-12-22 01:07:28 +00:00
/**
* Pass - thru function for ACL grant instance .
*
2006-11-24 17:27:11 +00:00
* @ param string $aro
* @ param string $aco
* @ param string $action : default = *
2005-12-22 01:07:28 +00:00
* @ return boolean
*/
2006-06-14 18:02:37 +00:00
function revoke ( $aro , $aco , $action = " * " ) {
return $this -> _instance -> revoke ( $aro , $aco , $action );
}
2005-12-22 01:07:28 +00:00
/**
2006-11-24 17:27:11 +00:00
* Sets the current ARO instance to object from getAro
*
* @ param string $id
* @ return boolean
*/
function setAro ( $id ) {
return $this -> Aro = $this -> _instance -> getAro ( $id );
}
/**
* Sets the current ACO instance to object from getAco
*
* @ param string $id
* @ return boolean
*/
function setAco ( $id ) {
return $this -> Aco = $this -> _instance -> getAco ( $id );
}
/**
* Pass - thru function for ACL getAro instance
* that gets an ARO object from the given id or alias
2005-12-22 01:07:28 +00:00
*
2006-11-24 17:27:11 +00:00
* @ param string $id
2005-12-22 01:07:28 +00:00
* @ return Aro
*/
2006-06-14 18:02:37 +00:00
function getAro ( $id ) {
return $this -> _instance -> getAro ( $id );
}
2005-12-22 01:07:28 +00:00
/**
* Pass - thru function for ACL getAco instance .
2006-11-24 17:27:11 +00:00
* that gets an ACO object from the given id or alias
2005-12-22 01:07:28 +00:00
*
2006-11-24 17:27:11 +00:00
* @ param string $id
2005-12-22 01:07:28 +00:00
* @ return Aco
*/
2006-06-14 18:02:37 +00:00
function getAco ( $id ) {
return $this -> _instance -> getAco ( $id );
}
2005-08-21 06:49:02 +00:00
}
2007-05-01 01:23:21 +00:00
/**
* Access Control List abstract class . Not to be instantiated .
* Subclasses of this class are used by AclComponent to perform ACL checks in Cake .
*
* @ package cake
* @ subpackage cake . cake . libs . controller . components
2007-05-20 04:44:18 +00:00
* @ abstract
2007-05-01 01:23:21 +00:00
*/
2007-05-20 04:44:18 +00:00
class AclBase extends Object {
2007-05-01 01:23:21 +00:00
/**
* This class should never be instantiated , just subclassed .
*
* @ return AclBase
*/
2007-05-21 04:24:58 +00:00
function __construct () {
2007-05-01 01:23:21 +00:00
if ( strcasecmp ( get_class ( $this ), " AclBase " ) == 0 || ! is_subclass_of ( $this , " AclBase " )) {
trigger_error ( __ ( " [acl_base] The AclBase class constructor has been called, or the class was instantiated. This class must remain abstract. Please refer to the Cake docs for ACL configuration. " , true ), E_USER_ERROR );
return NULL ;
}
}
/**
* Empty method to be overridden in subclasses
*
* @ param unknown_type $aro
* @ param unknown_type $aco
* @ param string $action
*/
function check ( $aro , $aco , $action = " * " ) {
}
2007-05-15 20:01:44 +00:00
/**
* Empty method to be overridden in subclasses
*
* @ param unknown_type $component
*/
function initialize ( & $component ) {
}
2007-05-01 01:23:21 +00:00
}
2007-05-23 18:12:05 +00:00
/**
* 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: \n Aro: " . print_r ( $aro , true ) . " \n Aco: " . 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: \n Aro: " . print_r ( $aro , true ) . " \n Aco: " . 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 ;
}
2007-06-20 06:15:35 +00:00
for ( $i = count ( $aroPath ) - 1 ; $i >= 0 ; $i -- ) {
2007-05-23 18:12:05 +00:00
$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 {
2007-06-20 06:15:35 +00:00
foreach ( Set :: extract ( $perms , '{n}.Permission' ) as $perm ) {
2007-05-23 18:12:05 +00:00
if ( $action == '*' ) {
// ARO must be cleared for ALL ACO actions
2007-06-20 06:15:35 +00:00
foreach ( $permKeys as $key ) {
2007-05-23 18:12:05 +00:00
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
*/
2007-06-10 17:43:37 +00:00
function allow ( $aro , $aco , $actions = " * " , $value = 1 ) {
2007-05-23 18:12:05 +00:00
$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' ];
}
2007-06-10 17:43:37 +00:00
if ( $actions == " * " ) {
2007-05-23 18:12:05 +00:00
$permKeys = $this -> _getAcoKeys ( $this -> Aro -> Permission -> loadInfo ());
2007-06-20 06:15:35 +00:00
foreach ( $permKeys as $key ) {
2007-05-23 18:12:05 +00:00
$save [ $key ] = $value ;
}
} else {
2007-06-20 06:15:35 +00:00
if ( ! is_array ( $actions )) {
2007-06-17 07:58:48 +00:00
$actions = array ( '_' . $actions );
2007-06-10 17:43:37 +00:00
$actions = am ( $permKeys , $actions );
}
2007-06-20 06:15:35 +00:00
if ( is_array ( $actions )) {
foreach ( $actions as $action ) {
2007-06-10 17:43:37 +00:00
if ( $action { 0 } != '_' ) {
$action = '_' . $action ;
}
if ( in_array ( $action , $permKeys )) {
$save [ $action ] = $value ;
}
}
2007-05-23 18:12:05 +00:00
}
}
2007-06-10 17:43:37 +00:00
2007-05-23 18:12:05 +00:00
$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' ];
}
2007-06-10 17:43:37 +00:00
$this -> Aro -> Permission -> create ( $save );
return $this -> Aro -> Permission -> save ();
2007-05-23 18:12:05 +00:00
}
/**
* 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' );
2007-06-20 06:15:35 +00:00
foreach ( $keys as $key ) {
2007-05-23 18:12:05 +00:00
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' ]));
2007-06-20 06:15:35 +00:00
foreach ( $userGroups as $group ) {
2007-05-23 18:12:05 +00:00
//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 );
2007-06-20 06:15:35 +00:00
foreach ( $fileLineArray as $fileLine ) {
2007-05-23 18:12:05 +00:00
$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 ) {
2007-06-20 06:15:35 +00:00
foreach ( $array as $element ) {
2007-05-23 18:12:05 +00:00
$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 ;
}
}
2007-05-15 20:01:44 +00:00
2006-01-12 02:10:47 +00:00
?>