auth.php

Go to the documentation of this file.
00001 <?php
00002 /* SVN FILE: $Id: auth_8php-source.html 580 2008-07-01 14:45:49Z gwoo $ */
00003 
00004 /**
00005  * Authentication component
00006  *
00007  * Manages user logins and permissions.
00008  *
00009  * PHP versions 4 and 5
00010  *
00011  * CakePHP(tm) :  Rapid Development Framework <http://www.cakephp.org/>
00012  * Copyright 2005-2008, Cake Software Foundation, Inc.
00013  *                              1785 E. Sahara Avenue, Suite 490-204
00014  *                              Las Vegas, Nevada 89104
00015  *
00016  * Licensed under The MIT License
00017  * Redistributions of files must retain the above copyright notice.
00018  *
00019  * @filesource
00020  * @copyright       Copyright 2005-2008, Cake Software Foundation, Inc.
00021  * @link                http://www.cakefoundation.org/projects/info/cakephp CakePHP(tm) Project
00022  * @package         cake
00023  * @subpackage      cake.cake.libs.controller.components
00024  * @since           CakePHP(tm) v 0.10.0.1076
00025  * @version         $Revision: 580 $
00026  * @modifiedby      $LastChangedBy: gwoo $
00027  * @lastmodified    $Date: 2008-07-01 09:45:49 -0500 (Tue, 01 Jul 2008) $
00028  * @license         http://www.opensource.org/licenses/mit-license.php The MIT License
00029  */
00030 
00031 App::import(array('Router', 'Security'));
00032 
00033 /**
00034  * Authentication control component class
00035  *
00036  * Binds access control with user authentication and session management.
00037  *
00038  * @package     cake
00039  * @subpackage  cake.cake.libs.controller.components
00040  */
00041 class AuthComponent extends Object {
00042 /**
00043  * Maintains current user login state.
00044  *
00045  * @var boolean
00046  * @access private
00047  */
00048     var $_loggedIn = false;
00049 /**
00050  * Other components utilized by AuthComponent
00051  *
00052  * @var array
00053  * @access public
00054  */
00055     var $components = array('Session', 'RequestHandler');
00056 /**
00057  * A reference to the object used for authentication
00058  *
00059  * @var object
00060  * @access public
00061  */
00062     var $authenticate = null;
00063 /**
00064  * The name of the component to use for Authorization or set this to
00065  * 'controller' will validate against Controller::isAuthorized()
00066  * 'actions' will validate Controller::action against an AclComponent::check()
00067  * 'crud' will validate mapActions against an AclComponent::check()
00068  * array('model'=> 'name'); will validate mapActions against model $name::isAuthorize(user, controller, mapAction)
00069  * 'object' will validate Controller::action against object::isAuthorized(user, controller, action)
00070  *
00071  * @var mixed
00072  * @access public
00073  */
00074     var $authorize = false;
00075 /**
00076  * The name of an optional view element to render when an Ajax request is made
00077  * with an invalid or expired session
00078  *
00079  * @var string
00080  * @access public
00081  */
00082     var $ajaxLogin = null;
00083 /**
00084  * The name of the model that represents users which will be authenticated.  Defaults to 'User'.
00085  *
00086  * @var string
00087  * @access public
00088  */
00089     var $userModel = 'User';
00090 /**
00091  * Additional query conditions to use when looking up and authenticating users,
00092  * i.e. array('User.is_active' => 1).
00093  *
00094  * @var array
00095  * @access public
00096  */
00097     var $userScope = array();
00098 /**
00099  * Allows you to specify non-default login name and password fields used in
00100  * $userModel, i.e. array('username' => 'login_name', 'password' => 'passwd').
00101  *
00102  * @var array
00103  * @access public
00104  */
00105     var $fields = array('username' => 'username', 'password' => 'password');
00106 /**
00107  * The session key name where the record of the current user is stored.  If
00108  * unspecified, it will be "Auth.{$userModel name}".
00109  *
00110  * @var string
00111  * @access public
00112  */
00113     var $sessionKey = null;
00114 /**
00115  * If using action-based access control, this defines how the paths to action
00116  * ACO nodes is computed.  If, for example, all controller nodes are nested
00117  * under an ACO node named 'Controllers', $actionPath should be set to
00118  * "Controllers/".
00119  *
00120  * @var string
00121  * @access public
00122  */
00123     var $actionPath = null;
00124 /**
00125  * A URL (defined as a string or array) to the controller action that handles
00126  * logins.
00127  *
00128  * @var mixed
00129  * @access public
00130  */
00131     var $loginAction = null;
00132 /**
00133  * Normally, if a user is redirected to the $loginAction page, the location they
00134  * were redirected from will be stored in the session so that they can be
00135  * redirected back after a successful login.  If this session value is not
00136  * set, the user will be redirected to the page specified in $loginRedirect.
00137  *
00138  * @var mixed
00139  * @access public
00140  */
00141     var $loginRedirect = null;
00142 /**
00143  * The the default action to redirect to after the user is logged out.  While AuthComponent does
00144  * not handle post-logout redirection, a redirect URL will be returned from AuthComponent::logout().
00145  * Defaults to AuthComponent::$loginAction.
00146  *
00147  * @var mixed
00148  * @access public
00149  * @see AuthComponent::$loginAction
00150  * @see AuthComponent::logout()
00151  */
00152     var $logoutRedirect = null;
00153 /**
00154  * The name of model or model object, or any other object has an isAuthorized method.
00155  *
00156  * @var string
00157  * @access public
00158  */
00159     var $object = null;
00160 /**
00161  * Error to display when user login fails.  For security purposes, only one error is used for all
00162  * login failures, so as not to expose information on why the login failed.
00163  *
00164  * @var string
00165  * @access public
00166  */
00167     var $loginError = null;
00168 /**
00169  * Error to display when user attempts to access an object or action to which they do not have
00170  * acccess.
00171  *
00172  * @var string
00173  * @access public
00174  */
00175     var $authError = null;
00176 /**
00177  * Determines whether AuthComponent will automatically redirect and exit if login is successful.
00178  *
00179  * @var boolean
00180  * @access public
00181  */
00182     var $autoRedirect = true;
00183 /**
00184  * Controller actions for which user validation is not required.
00185  *
00186  * @var array
00187  * @access public
00188  * @see AuthComponent::allow()
00189  */
00190     var $allowedActions = array();
00191 /**
00192  * Maps actions to CRUD operations.  Used for controller-based validation ($validate = 'controller').
00193  *
00194  * @var array
00195  * @access public
00196  * @see AuthComponent::mapActions()
00197  */
00198     var $actionMap = array(
00199         'index'     => 'read',
00200         'add'       => 'create',
00201         'edit'      => 'update',
00202         'view'      => 'read',
00203         'remove'    => 'delete'
00204     );
00205 /**
00206  * Form data from Controller::$data
00207  *
00208  * @var array
00209  * @access public
00210  */
00211     var $data = array();
00212 /**
00213  * Parameter data from Controller::$params
00214  *
00215  * @var array
00216  * @access public
00217  */
00218     var $params = array();
00219 /**
00220  * Initializes AuthComponent for use in the controller
00221  *
00222  * @param object $controller A reference to the instantiating controller object
00223  * @access public
00224  */
00225     function initialize(&$controller) {
00226         $this->params = $controller->params;
00227         $crud = array('create', 'read', 'update', 'delete');
00228         $this->actionMap = array_merge($this->actionMap, array_combine($crud, $crud));
00229 
00230         $admin = Configure::read('Routing.admin');
00231         if (!empty($admin)) {
00232             $this->actionMap = array_merge($this->actionMap, array(
00233                 $admin . '_index'   => 'read',
00234                 $admin . '_add'     => 'create',
00235                 $admin . '_edit'    => 'update',
00236                 $admin . '_view'    => 'read',
00237                 $admin . '_remove'  => 'delete',
00238                 $admin . '_create'  => 'create',
00239                 $admin . '_read'    => 'read',
00240                 $admin . '_update'  => 'update',
00241                 $admin . '_delete'  => 'delete'
00242             ));
00243         }
00244         if (Configure::read() > 0) {
00245             App::import('Debugger');
00246             Debugger::checkSessionKey();
00247         }
00248     }
00249 /**
00250  * Main execution method.  Handles redirecting of invalid users, and processing
00251  * of login form data.
00252  *
00253  * @param object $controller A reference to the instantiating controller object
00254  * @access public
00255  */
00256     function startup(&$controller) {
00257         if (strtolower($controller->name) == 'app' || (strtolower($controller->name) == 'tests' && Configure::read() > 0)) {
00258             return;
00259         }
00260 
00261         if (!$this->__setDefaults()) {
00262             return false;
00263         }
00264 
00265         $this->data = $controller->data = $this->hashPasswords($controller->data);
00266 
00267         $url = '';
00268         if (is_array($this->loginAction)) {
00269             $params = $controller->params;
00270             $keys = array('pass', 'named', 'controller', 'action', 'plugin');
00271             $url = array();
00272 
00273             foreach($keys as $key) {
00274                 if (!empty($params[$key])) {
00275                     if (is_array($params[$key])) {
00276                         foreach ($params[$key] as $name => $value) {
00277                             $url[$name] = $value;
00278                         }
00279                     } else {
00280                         $url[$key] = $params[$key];
00281                     }
00282                 }
00283             }
00284         } elseif (isset($controller->params['url']['url'])) {
00285             $url = $controller->params['url']['url'];
00286         }   
00287         $url = Router::normalize($url);
00288         $loginAction = Router::normalize($this->loginAction);
00289 
00290         if ($loginAction != $url && ($this->allowedActions == array('*') || in_array($controller->action, $this->allowedActions))) {
00291             return false;
00292         }
00293 
00294         if ($loginAction == $url) {
00295             if (empty($controller->data) || !isset($controller->data[$this->userModel])) {
00296                 if (!$this->Session->check('Auth.redirect') && env('HTTP_REFERER')) {
00297                     $this->Session->write('Auth.redirect', $controller->referer());
00298                 }
00299                 return false;
00300             }
00301 
00302             $data = array(
00303                 $this->userModel . '.' . $this->fields['username'] => $controller->data[$this->userModel][$this->fields['username']],
00304                 $this->userModel . '.' . $this->fields['password'] => $controller->data[$this->userModel][$this->fields['password']]
00305             );
00306 
00307             if ($this->login($data)) {
00308                 if ($this->autoRedirect) {
00309                     $controller->redirect($this->redirect(), null, true);
00310                 }
00311                 return true;
00312             } else {
00313                 $this->Session->setFlash($this->loginError, 'default', array(), 'auth');
00314                 $controller->data[$this->userModel][$this->fields['password']] = null;
00315             }
00316             return false;
00317         } else {
00318             if (!$this->user()) {
00319                 if (!$this->RequestHandler->isAjax()) {
00320                     $this->Session->setFlash($this->authError, 'default', array(), 'auth');
00321                     $this->Session->write('Auth.redirect', $url);
00322                     $controller->redirect($loginAction, null, true);
00323                     return false;
00324                 } elseif (!empty($this->ajaxLogin)) {
00325                     $controller->viewPath = 'elements';
00326                     echo $controller->render($this->ajaxLogin, 'ajax');
00327                     $this->_stop();
00328                     return false;
00329                 }
00330             }
00331         }
00332 
00333         if (!$this->authorize) {
00334             return true;
00335         }
00336 
00337         extract($this->__authType());
00338         switch ($type) {
00339             case 'controller':
00340                 $this->object =& $controller;
00341             break;
00342             case 'crud':
00343             case 'actions':
00344                 if (isset($controller->Acl)) {
00345                     $this->Acl =& $controller->Acl;
00346                 } else {
00347                     trigger_error(__('Could not find AclComponent. Please include Acl in Controller::$components.', true), E_USER_WARNING);
00348                 }
00349             break;
00350             case 'model':
00351                 if (!isset($object)) {
00352                     if (isset($controller->{$controller->modelClass}) && is_object($controller->{$controller->modelClass})) {
00353                         $object = $controller->modelClass;
00354                     } elseif (!empty($controller->uses) && isset($controller->{$controller->uses[0]}) && is_object($controller->{$controller->uses[0]})) {
00355                         $object = $controller->uses[0];
00356                     }
00357                 }
00358                 $type = array('model' => $object);
00359             break;
00360         }
00361 
00362         if ($this->isAuthorized($type)) {
00363             return true;
00364         }
00365 
00366         $this->Session->setFlash($this->authError, 'default', array(), 'auth');
00367         $controller->redirect($controller->referer(), null, true);
00368         return false;
00369     }
00370 /**
00371  * Attempts to introspect the correct values for object properties including
00372  * $userModel and $sessionKey.
00373  *
00374  * @param object $controller A reference to the instantiating controller object
00375  * @access private
00376  */
00377     function __setDefaults() {
00378         if (empty($this->userModel)) {
00379             trigger_error(__("Could not find \$userModel. Please set AuthComponent::\$userModel in beforeFilter().", true), E_USER_WARNING);
00380             return false;
00381         }
00382         $defaults = array(
00383             'loginAction' => Router::normalize(array(
00384                 'controller'=> Inflector::underscore(Inflector::pluralize($this->userModel)),
00385                 'action' => 'login'
00386             )),
00387             'sessionKey' => 'Auth.' . $this->userModel,
00388             'logoutRedirect' => $this->loginAction,
00389             'loginError' => __('Login failed. Invalid username or password.', true),
00390             'authError' => __('You are not authorized to access that location.', true)
00391         );
00392         foreach ($defaults as $key => $value) {
00393             if (empty($this->{$key})) {
00394                 $this->{$key} = $value;
00395             }
00396         }
00397         return true;
00398     }
00399 /**
00400  * Determines whether the given user is authorized to perform an action.  The type of authorization
00401  * used is based on the value of AuthComponent::$authorize or the passed $type param.
00402  *
00403  * Types:
00404  * 'controller' will validate against Controller::isAuthorized() if controller instance is passed in $object
00405  * 'actions' will validate Controller::action against an AclComponent::check()
00406  * 'crud' will validate mapActions against an AclComponent::check()
00407  * array('model'=> 'name'); will validate mapActions against model $name::isAuthorize(user, controller, mapAction)
00408  * 'object' will validate Controller::action against object::isAuthorized(user, controller, action)
00409  *
00410  * @param string $type Type of authorization
00411  * @param mixed $object object, model object, or model name
00412  * @param mixed $user The user to check the authorization of
00413  * @return boolean True if $user is authorized, otherwise false
00414  * @access public
00415  */
00416     function isAuthorized($type = null, $object = null, $user = null) {
00417         if (empty($user) && !$this->user()) {
00418             return false;
00419         } elseif (empty($user)) {
00420             $user = $this->user();
00421         }
00422 
00423         extract($this->__authType($type));
00424 
00425         if (!$object) {
00426             $object = $this->object;
00427         }
00428 
00429         $valid = false;
00430         switch ($type) {
00431             case 'controller':
00432                 $valid = $object->isAuthorized();
00433             break;
00434             case 'actions':
00435                 $valid = $this->Acl->check($user, $this->action());
00436             break;
00437             case 'crud':
00438                 $this->mapActions();
00439                 if (!isset($this->actionMap[$this->params['action']])) {
00440                     trigger_error(sprintf(__('Auth::startup() - Attempted access of un-mapped action "%1$s" in controller "%2$s"', true), $this->params['action'], $this->params['controller']), E_USER_WARNING);
00441                 } else {
00442                     $valid = $this->Acl->check($user, $this->action(':controller'), $this->actionMap[$this->params['action']]);
00443                 }
00444             break;
00445             case 'model':
00446                 $this->mapActions();
00447                 $action = $this->params['action'];
00448                 if(isset($this->actionMap[$action])) {
00449                     $action = $this->actionMap[$action];
00450                 }
00451                 if (is_string($object)) {
00452                     $object = $this->getModel($object);
00453                 }
00454             case 'object':
00455                 if (!isset($action)) {
00456                     $action = $this->action(':action');
00457                 }
00458                 if (empty($object)) {
00459                     trigger_error(sprintf(__('Could not find %s. Set AuthComponent::$object in beforeFilter() or pass a valid object', true), get_class($object)), E_USER_WARNING);
00460                     return;
00461                 }
00462                 if (method_exists($object, 'isAuthorized')) {
00463                     $valid = $object->isAuthorized($user, $this->action(':controller'), $action);
00464                 } elseif ($object){
00465                     trigger_error(sprintf(__('%s::isAuthorized() is not defined.', true), get_class($object)), E_USER_WARNING);
00466                 }
00467             break;
00468             case null:
00469             case false:
00470                 return true;
00471             break;
00472             default:
00473                 trigger_error(__('Auth::isAuthorized() - $authorize is set to an incorrect value.  Allowed settings are: "actions", "crud", "model" or null.', true), E_USER_WARNING);
00474             break;
00475         }
00476         return $valid;
00477     }
00478 /**
00479  * Get authorization type
00480  *
00481  * @param string $auth Type of authorization
00482  * @return array Associative array with: type, object
00483  * @access private
00484  */
00485     function __authType($auth = null) {
00486         if ($auth == null) {
00487             $auth = $this->authorize;
00488         }
00489         $object = null;
00490         if (is_array($auth)) {
00491             $type = key($auth);
00492             $object = $auth[$type];
00493         } else {
00494             $type = $auth;
00495             return compact('type');
00496         }
00497         return compact('type', 'object');
00498     }
00499 /**
00500  * Takes a list of actions in the current controller for which authentication is not required, or
00501  * no parameters to allow all actions.
00502  *
00503  * @param string $action Controller action name
00504  * @param string $action Controller action name
00505  * @param string ... etc.
00506  * @access public
00507  */
00508     function allow() {
00509         $args = func_get_args();
00510         if (empty($args)) {
00511             $this->allowedActions = array('*');
00512         } else {
00513             if (isset($args[0]) && is_array($args[0])) {
00514                 $args = $args[0];
00515             }
00516             $this->allowedActions = array_merge($this->allowedActions, $args);
00517         }
00518     }
00519 /**
00520  * Removes items from the list of allowed actions.
00521  *
00522  * @param string $action Controller action name
00523  * @param string $action Controller action name
00524  * @param string ... etc.
00525  * @see AuthComponent::allow()
00526  * @access public
00527  */
00528     function deny() {
00529         $args = func_get_args();
00530         foreach ($args as $arg) {
00531             $i = array_search($arg, $this->allowedActions);
00532             if (is_int($i)) {
00533                 unset($this->allowedActions[$i]);
00534             }
00535         }
00536         $this->allowedActions = array_values($this->allowedActions);
00537     }
00538 /**
00539  * Maps action names to CRUD operations. Used for controller-based authentication.
00540  *
00541  * @param array $map Actions to map
00542  * @access public
00543  */
00544     function mapActions($map = array()) {
00545         $crud = array('create', 'read', 'update', 'delete');
00546         foreach ($map as $action => $type) {
00547             if (in_array($action, $crud) && is_array($type)) {
00548                 foreach ($type as $typedAction) {
00549                     $this->actionMap[$typedAction] = $action;
00550                 }
00551             } else {
00552                 $this->actionMap[$action] = $type;
00553             }
00554         }
00555     }
00556 /**
00557  * Manually log-in a user with the given parameter data.  The $data provided can be any data
00558  * structure used to identify a user in AuthComponent::identify().  If $data is empty or not
00559  * specified, POST data from Controller::$data will be used automatically.
00560  *
00561  * After (if) login is successful, the user record is written to the session key specified in
00562  * AuthComponent::$sessionKey.
00563  *
00564  * @param mixed $data User object
00565  * @return boolean True on login success, false on failure
00566  * @access public
00567  */
00568     function login($data = null) {
00569         $this->__setDefaults();
00570         $this->_loggedIn = false;
00571 
00572         if (empty($data)) {
00573             $data = $this->data;
00574         }
00575 
00576         if ($user = $this->identify($data)) {
00577             $this->Session->write($this->sessionKey, $user);
00578             $this->_loggedIn = true;
00579         }
00580         return $this->_loggedIn;
00581     }
00582 /**
00583  * Logs a user out, and returns the login action to redirect to.
00584  *
00585  * @param mixed $url Optional URL to redirect the user to after logout
00586  * @return string AuthComponent::$loginAction
00587  * @see AuthComponent::$loginAction
00588  * @access public
00589  */
00590     function logout() {
00591         $this->__setDefaults();
00592         $this->Session->del($this->sessionKey);
00593         $this->Session->del('Auth.redirect');
00594         $this->_loggedIn = false;
00595         return Router::normalize($this->logoutRedirect);
00596     }
00597 /**
00598  * Get the current user from the session.
00599  *
00600  * @return array User record, or null if no user is logged in.
00601  * @access public
00602  */
00603     function user($key = null) {
00604         $this->__setDefaults();
00605         if (!$this->Session->check($this->sessionKey)) {
00606             return null;
00607         }
00608 
00609         if ($key == null) {
00610             return array($this->userModel => $this->Session->read($this->sessionKey));
00611         } else {
00612             $user = $this->Session->read($this->sessionKey);
00613             if (isset($user[$key])) {
00614                 return $user[$key];
00615             } else {
00616                 return null;
00617             }
00618         }
00619     }
00620 /**
00621  * If no parameter is passed, gets the authentication redirect URL.
00622  *
00623  * @param mixed $url Optional URL to write as the login redirect URL.
00624  * @return string Redirect URL
00625  * @access public
00626  */
00627     function redirect($url = null) {
00628         if (!is_null($url)) {
00629             return $this->Session->write('Auth.redirect', $url);
00630         }
00631         if ($this->Session->check('Auth.redirect')) {
00632             $redir = $this->Session->read('Auth.redirect');
00633             $this->Session->delete('Auth.redirect');
00634 
00635             if (Router::normalize($redir) == Router::normalize($this->loginAction)) {
00636                 $redir = $this->loginRedirect;
00637             }
00638         } else {
00639             $redir = $this->loginRedirect;
00640         }
00641         return Router::normalize($redir);
00642     }
00643 /**
00644  * Validates a user against an abstract object.
00645  *
00646  * @param mixed $object  The object to validate the user against.
00647  * @param mixed $user    Optional.  The identity of the user to be validated.
00648  *                       Uses the current user session if none specified.  For
00649  *                       valid forms of identifying users, see
00650  *                       AuthComponent::identify().
00651  * @param string $action Optional. The action to validate against.
00652  * @see AuthComponent::identify()
00653  * @return boolean True if the user validates, false otherwise.
00654  * @access public
00655  */
00656     function validate($object, $user = null, $action = null) {
00657         if (empty($user)) {
00658             $user = $this->user();
00659         }
00660         if (empty($user)) {
00661             return false;
00662         }
00663         return $this->Acl->check($user, $object, $action);
00664     }
00665 /**
00666  * Returns the path to the ACO node bound to a controller/action.
00667  *
00668  * @param string $action  Optional.  The controller/action path to validate the
00669  *                        user against.  The current request action is used if
00670  *                        none is specified.
00671  * @return boolean ACO node path
00672  * @access public
00673  */
00674     function action($action = ':controller/:action') {
00675         return str_replace(
00676             array(':controller', ':action'),
00677             array(Inflector::camelize($this->params['controller']), $this->params['action']),
00678             $this->actionPath . $action
00679         );
00680     }
00681 /**
00682  * Returns a reference to the model object specified, and attempts
00683  * to load it if it is not found.
00684  *
00685  * @param string $name Model name (defaults to AuthComponent::$userModel)
00686  * @return object A reference to a model object
00687  * @access public
00688  */
00689     function &getModel($name = null) {
00690         $model = null;
00691         if (!$name) {
00692             $name = $this->userModel;
00693         }
00694 
00695         if (PHP5) {
00696             $model = ClassRegistry::init($name);
00697         } else {
00698             $model =& ClassRegistry::init($name);
00699         }
00700 
00701         if (empty($model)) {
00702             trigger_error(__('Auth::getModel() - Model is not set or could not be found', true), E_USER_WARNING);
00703             return null;
00704         }
00705 
00706         return $model;
00707     }
00708 /**
00709  * Identifies a user based on specific criteria.
00710  *
00711  * @param mixed $user Optional. The identity of the user to be validated.
00712  *              Uses the current user session if none specified.
00713  * @param array $conditions Optional. Additional conditions to a find.
00714  * @return array User record data, or null, if the user could not be identified.
00715  * @access public
00716  */
00717     function identify($user = null, $conditions = null) {
00718         if ($conditions === false) {
00719             $conditions = null;
00720         } elseif (is_array($conditions)) {
00721             $conditions = array_merge((array)$this->userScope, $conditions);
00722         } else {
00723             $conditions = $this->userScope;
00724         }
00725         if (empty($user)) {
00726             $user = $this->user();
00727             if (empty($user)) {
00728                 return null;
00729             }
00730         } elseif (is_object($user) && is_a($user, 'Model')) {
00731             if (!$user->exists()) {
00732                 return null;
00733             }
00734             $user = $user->read();
00735             $user = $user[$this->userModel];
00736         } elseif (is_array($user) && isset($user[$this->userModel])) {
00737             $user = $user[$this->userModel];
00738         }
00739 
00740         if (is_array($user) && (isset($user[$this->fields['username']]) || isset($user[$this->userModel . '.' . $this->fields['username']]))) {
00741 
00742             if (isset($user[$this->fields['username']]) && !empty($user[$this->fields['username']])  && !empty($user[$this->fields['password']])) {
00743                 if (trim($user[$this->fields['username']]) == '=' || trim($user[$this->fields['password']]) == '=') {
00744                     return false;
00745                 }
00746                 $find = array(
00747                     $this->userModel.'.'.$this->fields['username'] => $user[$this->fields['username']],
00748                     $this->userModel.'.'.$this->fields['password'] => $user[$this->fields['password']]
00749                 );
00750             } elseif (isset($user[$this->userModel . '.' . $this->fields['username']]) && !empty($user[$this->userModel . '.' . $this->fields['username']])) {
00751                 if (trim($user[$this->userModel . '.' . $this->fields['username']]) == '=' || trim($user[$this->userModel . '.' . $this->fields['password']]) == '=') {
00752                     return false;
00753                 }
00754                 $find = array(
00755                     $this->userModel.'.'.$this->fields['username'] => $user[$this->userModel . '.' . $this->fields['username']],
00756                     $this->userModel.'.'.$this->fields['password'] => $user[$this->userModel . '.' . $this->fields['password']]
00757                 );
00758             } else {
00759                 return false;
00760             }
00761             $model =& $this->getModel();
00762             $data = $model->find(array_merge($find, $conditions), null, null, 0);
00763             if (empty($data) || empty($data[$this->userModel])) {
00764                 return null;
00765             }
00766         } elseif (is_numeric($user)) {
00767             $model =& $this->getModel();
00768             $data = $model->find(array_merge(array($model->escapeField() => $user), $conditions));
00769 
00770             if (empty($data) || empty($data[$this->userModel])) {
00771                 return null;
00772             }
00773         }
00774 
00775         if (isset($data) && !empty($data)) {
00776             if (!empty($data[$this->userModel][$this->fields['password']])) {
00777                 unset($data[$this->userModel][$this->fields['password']]);
00778             }
00779             return $data[$this->userModel];
00780         } else {
00781             return null;
00782         }
00783     }
00784 /**
00785  * Hash any passwords found in $data using $userModel and $fields['password']
00786  *
00787  * @param array $data Set of data to look for passwords
00788  * @return array Data with passwords hashed
00789  * @access public
00790  */
00791     function hashPasswords($data) {
00792         if (is_object($this->authenticate) && method_exists($this->authenticate, 'hashPasswords')) {
00793             return $this->authenticate->hashPasswords($data);
00794         }
00795 
00796         if (isset($data[$this->userModel])) {
00797             if (isset($data[$this->userModel][$this->fields['username']]) && isset($data[$this->userModel][$this->fields['password']])) {
00798                 $data[$this->userModel][$this->fields['password']] = $this->password($data[$this->userModel][$this->fields['password']]);
00799             }
00800         }
00801         return $data;
00802     }
00803 /**
00804  * Hash a password with the application's salt value (as defined with Configure::write('Security.salt');
00805  *
00806  * @param string $password Password to hash
00807  * @return string Hashed password
00808  * @access public
00809  */
00810     function password($password) {
00811         return Security::hash($password, null, true);
00812     }
00813 /**
00814  * Component shutdown.  If user is logged in, wipe out redirect.
00815  *
00816  * @param object $controller Instantiating controller
00817  * @access public
00818  */
00819     function shutdown(&$controller) {
00820         if ($this->_loggedIn) {
00821             $this->Session->del('Auth.redirect');
00822         }
00823     }
00824 }
00825 ?>