Refactoring ACL system to require less model code

git-svn-id: https://svn.cakephp.org/repo/branches/1.2.x.x@4502 3807eeeb-6ff5-0310-8944-8be069107fe0
This commit is contained in:
nate 2007-02-10 22:59:08 +00:00
parent c87b48e034
commit 2a954b5fbf
4 changed files with 88 additions and 47 deletions

View file

@ -56,15 +56,12 @@ class AuthComponent extends Object {
*/
var $ajaxLogin = null;
/**
* The name of the model that represents users which will be authenticated. If
* this value is unspecified, AuthComponent will look for one of the following:
* 'User', 'Person', 'Contact', 'Member', 'Customer', 'Account', 'Client',
* 'Employee', 'Staff', or 'Friend', in that order.
* The name of the model that represents users which will be authenticated. Defaults to 'User'.
*
* @var string
* @access public
*/
var $userModel = null;
var $userModel = 'User';
/**
* Additional query conditions to use when looking up and authenticating users,
* i.e. array('User.is_active' => 1).
@ -93,12 +90,12 @@ class AuthComponent extends Object {
* If using action-based access control, this defines how the paths to action
* ACO nodes is computed. If, for example, all controller nodes are nested
* under an ACO node named 'Controllers', $actionPath should be set to
* "Controllers/:controller/:action".
* "Controllers/".
*
* @var string
* @access public
*/
var $actionPath = ':controller/:action';
var $actionPath = null;
/**
* A URL (defined as a string or array) to the controller action that handles
* logins.
@ -163,6 +160,20 @@ class AuthComponent extends Object {
* @see AuthComponent::allow()
*/
var $allowedActions = array();
/**
* Form data from Controller::$data
*
* @var array
* @access public
*/
var $data = array();
/**
* Parameter data from Controller::$params
*
* @var array
* @access public
*/
var $params = array();
/**
* Main execution method. Handles redirecting of invalid users, and processing
* of login form data.
@ -178,15 +189,9 @@ class AuthComponent extends Object {
if (!$this->_setDefaults($controller)) {
return;
}
// Hash incoming passwords
if (isset($controller->data[$this->userModel])) {
if (isset($controller->data[$this->userModel][$this->fields['username']]) && isset($controller->data[$this->userModel][$this->fields['password']])) {
$model =& $this->getUserModel();
$controller->data[$this->userModel][$this->fields['password']] = Security::hash($controller->data[$this->userModel][$this->fields['password']]);
}
}
$this->hashPasswords($controller);
$this->data = $controller->data;
$this->params = $controller->params;
if ($this->allowedActions == array('*') || in_array($controller->action, $this->allowedActions)) {
return false;
@ -214,31 +219,45 @@ class AuthComponent extends Object {
}
return;
} else {
if (!$this->Session->check($this->sessionKey)) {
if (!$this->user()) {
if (!$this->RequestHandler->isAjax()) {
$this->Session->write('Auth.redirect', $url);
$controller->redirect('/' . $this->loginAction, null, true);
} elseif ($this->ajaxLogin != null) {
$controller->redirect('/' . $this->loginAction);
} elseif (!empty($this->ajaxLogin)) {
$this->viewPath = 'elements';
$this->render($this->ajaxLogin, 'ajax');
exit();
}
exit();
}
}
switch ($this->validate) {
$object = $assoc = null;
if (is_array($this->validate)) {
$type = key($this->validate);
$object = $this->validate[$type];
if (isset($this->validate[0])) {
$assoc = $this->validate[0];
}
} elseif (is_string($this->validate)) {
$type = $this->validate;
}
switch ($type) {
case 'actions':
$valid = $this->validateAction();
break;
case 'objects':
break;
case 'association':
break;
case null:
case false:
return;
break;
default:
trigger_error(__('Auth::startup() - $type is set to an incorrect value. Should be "actions", "objects", or null.'), E_USER_WARNING);
trigger_error(__('Auth::startup() - $validate is set to an incorrect value. Should be "actions", "objects", "association" or null.'), E_USER_WARNING);
break;
}
}
@ -251,17 +270,6 @@ class AuthComponent extends Object {
* @return void
*/
function _setDefaults(&$controller) {
if (empty($this->userModel)) {
$classes = array_values(array_intersect(
array_map('strtolower', get_declared_classes()),
array('user', 'person', 'contact', 'member', 'customer', 'account', 'client', 'employee', 'staff', 'friend')
));
if (!empty($classes)) {
$this->userModel = ucwords($classes[0]);
}
}
if (empty($this->userModel)) {
trigger_error(__('Could not find $userModel. Please set AuthComponent::$userModel in beforeFilter().'), E_USER_WARNING);
return false;
@ -383,11 +391,13 @@ class AuthComponent extends Object {
* @return boolean True if the user validates, false otherwise.
*/
function validate($object, $user = null) {
$user = $this->identify($user);
if (empty($user)) {
$user = $this->user();
}
if (empty($user)) {
return false;
}
pr($user);
return $this->Acl->check($user, $object);
}
/**
* Validates a user against a controller action.
@ -403,13 +413,14 @@ class AuthComponent extends Object {
* @see AuthComponent::validate()
* @return boolean True if the user validates, false otherwise.
*/
function validateAction($action = null, $user = null) {
$path = r(
function validateAction($action = ':controller/:action', $user = null) {
$action = $this->actionPath . $action;
$action = r(
array(':controller', ':action'),
array($this->params['controller'], $this->params['action']),
$path
array(Inflector::camelize($this->params['controller']), $this->params['action']),
$action
);
return $this->validate($path, $user);
return $this->validate($action, $user);
}
/**
* Returns a reference to the model object specified by $userModel, and attempts
@ -497,6 +508,21 @@ class AuthComponent extends Object {
return null;
}
}
/**
* Hash any passwords found in Controller::$data.
*
* @access public
* @param object $controller
* @return void
*/
function hashPasswords(&$controller) {
if (isset($controller->data[$this->userModel])) {
if (isset($controller->data[$this->userModel][$this->fields['username']]) && isset($controller->data[$this->userModel][$this->fields['password']])) {
$model =& $this->getUserModel();
$controller->data[$this->userModel][$this->fields['password']] = Security::hash($controller->data[$this->userModel][$this->fields['password']]);
}
}
}
/**
* Component shutdown. If user is logged in, wipe out redirect.
*

View file

@ -86,10 +86,19 @@ class AclNode extends AppModel {
}
} elseif (is_object($ref) && is_a($ref, 'Model')) {
$ref = array('model' => $ref->name, 'foreign_key' => $ref->id);
} elseif (is_array($ref) && !isset($ref['model'])) {
$name = key($ref);
if (!ClassRegistry::isKeySet($name)) {
return null;
}
$model =& ClassRegistry::getObject($name);
$ref = array('model' => $name, 'foreign_key' => $ref[$name][$model->primaryKey]);
}
if (is_array($ref)) {
list($result) = array_values($this->find($ref, null, null, -1));
$result = $this->find($ref, null, null, -1);
if ($result) {
list($result) = array_values($result);
}
}
return $result;
}

View file

@ -1,9 +1,9 @@
<?php
/* SVN FILE: $Id$ */
/**
* Tree behavior class.
* ACL behavior class.
*
* Enables a model object to act as a node-based tree.
* Enables objects to easily tie into an ACL system
*
* PHP versions 4 and 5
*
@ -95,9 +95,17 @@ class AclBehavior extends ModelBehavior {
function afterSave(&$model, $created) {
if ($created) {
$type = $this->__typeMaps[low($this->settings[$model->name]['type'])];
$parent = $this->node($model, $model->parentNode());
if(isset($parent['id'])) {
$parent = $parent['id'];
} else {
$parent = null;
}
$model->{$type}->create();
$model->{$type}->save(array(
'parent_id' => $model->parentNode(),
'parent_id' => $parent,
'model' => $model->name,
'foreign_key' => $model->id
));

View file

@ -1204,8 +1204,6 @@ class Model extends Overloadable {
* @return boolean True on success
*/
function del($id = null, $cascade = true) {
pr($this->name);
pr($this->trace());
if (!empty($id)) {
$this->id = $id;
}