Skip to content

Commit

Permalink
Making AclComponent throw exceptions when it encounters an error.
Browse files Browse the repository at this point in the history
Making AclBase an abstract class.
Adding AclComponent::adapter() for runtime modification of the Acl implementation.
Tests added, updated and fixed.
  • Loading branch information
markstory committed Apr 24, 2010
1 parent 33a2907 commit 62982c5
Show file tree
Hide file tree
Showing 2 changed files with 80 additions and 43 deletions.
63 changes: 40 additions & 23 deletions cake/libs/controller/components/acl.php
Expand Up @@ -44,19 +44,46 @@ class AclComponent extends Object {
/**
* Constructor. Will return an instance of the correct ACL class as defined in `Configure::read('Acl.classname')`
*
* @throws Exception when Acl.classname could not be loaded.
*/
function __construct() {
public function __construct() {
$name = Inflector::camelize(strtolower(Configure::read('Acl.classname')));
if (!class_exists($name)) {
if (App::import('Component', $name)) {
list($plugin, $name) = pluginSplit($name);
$name .= 'Component';
} else {
trigger_error(sprintf(__('Could not find %s.'), $name), E_USER_WARNING);
throw new Exception(sprintf(__('Could not find %s.'), $name));
}
}
$this->adapter($name);
}

/**
* Sets or gets the Adapter object currently in the AclComponent.
*
* `$this->Acl->adapter();` will get the current adapter class while
* `$this->Acl->adapter($obj);` will set the adapter class
*
* Will call the initialize method on the adapter if setting a new one.
*
* @param mixed $adapter Instance of AclBase or a string name of the class to use. (optional)
* @return mixed either null, or instance of AclBase
* @throws Exception when the given class is not an AclBase
*/
public function adapter($adapter = null) {
if ($adapter) {
if (is_string($adapter)) {
$adapter = new $adapter();
}
if (!$adapter instanceof AclBase) {
throw new Exception(__('AclComponent adapters must extend AclBase'));
}
$this->_Instance = $adapter;
$this->_Instance->initialize($this);
return;
}
$this->_Instance =& new $name();
$this->_Instance->initialize($this);
return $this->_Instance;
}

/**
Expand Down Expand Up @@ -161,18 +188,7 @@ public function revoke($aro, $aco, $action = "*") {
* @subpackage cake.cake.libs.controller.components
* @abstract
*/
class AclBase extends Object {

/**
* This class should never be instantiated, just subclassed.
*
*/
function __construct() {
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."), E_USER_ERROR);
return NULL;
}
}
abstract class AclBase extends Object {

/**
* Empty method to be overridden in subclasses
Expand All @@ -181,16 +197,14 @@ function __construct() {
* @param string $aco ACO The controlled object identifier.
* @param string $action Action (defaults to *)
*/
public function check($aro, $aco, $action = "*") {
}
public abstract function check($aro, $aco, $action = "*");

/**
* Empty method to be overridden in subclasses
*
* @param object $component Component
*/
public function initialize(&$component) {
}
public abstract function initialize($component);
}

/**
Expand Down Expand Up @@ -234,7 +248,7 @@ function __construct() {
* @param AclComponent $component
* @return void
*/
public function initialize(&$component) {
public function initialize($component) {
$component->Aro =& $this->Aro;
$component->Aco =& $this->Aco;
}
Expand Down Expand Up @@ -494,10 +508,13 @@ class IniAcl extends AclBase {
public $config = null;

/**
* The constructor must be overridden, as AclBase is abstract.
* Initialize method
*
* @param AclBase $component
* @return void
*/
function __construct() {
public function initialize($component) {

}

/**
Expand Down
60 changes: 40 additions & 20 deletions cake/tests/cases/libs/controller/components/acl.test.php
Expand Up @@ -17,9 +17,6 @@
* @since CakePHP(tm) v 1.2.0.5435
* @license http://www.opensource.org/licenses/opengroup.php The Open Group Test Suite License
*/
if (!defined('CAKEPHP_UNIT_TEST_EXECUTION')) {
define('CAKEPHP_UNIT_TEST_EXECUTION', 1);
}
App::import(array('controller' .DS . 'components' . DS . 'acl', 'model' . DS . 'db_acl'));

/**
Expand Down Expand Up @@ -184,15 +181,6 @@ function __construct() {
}
}

/**
* IniAclTest class
*
* @package cake
* @subpackage cake.tests.cases.libs.controller.components
*/
class IniAclTest extends IniAcl {
}

/**
* Short description for class.
*
Expand Down Expand Up @@ -242,6 +230,41 @@ function tearDown() {
unset($this->Acl);
}

/**
* test that construtor throws an exception when Acl.classname is a
* non-existant class
*
* @return void
*/
function testConstrutorException() {
$this->expectException();
Configure::write('Acl.classname', 'AclClassNameThatDoesNotExist');
$acl = new AclComponent();
}

/**
* test that adapter() allows control of the interal implementation AclComponent uses.
*
* @return void
*/
function testAdapter() {
$implementation = new IniAcl();
$this->assertNull($this->Acl->adapter($implementation));

$this->assertEqual($this->Acl->adapter(), $implementation, 'Returned object is different %s');
}

/**
* test that adapter() whines when the class is not an AclBase
*
* @return void
*/
function testAdapterException() {
$this->expectException();
$thing = new StdClass();
$this->Acl->adapter($thing);
}

/**
* testAclCreate method
*
Expand Down Expand Up @@ -513,11 +536,9 @@ function testStartup() {
* @return void
*/
function testIniReadConfigFile() {
Configure::write('Acl.classname', 'IniAclTest');
unset($this->Acl);
$this->Acl = new AclComponent();
$Ini = new IniAcl();
$iniFile = TEST_CAKE_CORE_INCLUDE_PATH . 'tests' . DS . 'test_app' . DS . 'config'. DS . 'acl.ini.php';
$result = $this->Acl->_Instance->readConfigFile($iniFile);
$result = $Ini->readConfigFile($iniFile);
$expected = array(
'admin' => array(
'groups' => 'administrators',
Expand Down Expand Up @@ -562,12 +583,11 @@ function testIniReadConfigFile() {
* @return void
*/
function testIniCheck() {
Configure::write('Acl.classname', 'IniAclTest');
unset($this->Acl);
$iniFile = TEST_CAKE_CORE_INCLUDE_PATH . 'tests' . DS . 'test_app' . DS . 'config'. DS . 'acl.ini.php';

$this->Acl = new AclComponent();
$this->Acl->_Instance->config= $this->Acl->_Instance->readConfigFile($iniFile);
$Ini = new IniAcl();
$Ini->config = $Ini->readConfigFile($iniFile);
$this->Acl->adapter($Ini);

$this->assertFalse($this->Acl->check('admin', 'ads'));
$this->assertTrue($this->Acl->check('admin', 'posts'));
Expand Down

0 comments on commit 62982c5

Please sign in to comment.