2007-01-12 17:49:02 +00:00
< ? php
/* SVN FILE: $Id$ */
/**
* Authentication component
*
* Manages user logins and permissions .
*
* 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 .
2007-01-12 17:49:02 +00:00
* 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
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
2007-01-12 17:49:02 +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
2007-01-12 17:49:02 +00:00
* @ version $Revision $
* @ modifiedby $LastChangedBy $
* @ lastmodified $Date $
* @ license http :// www . opensource . org / licenses / mit - license . php The MIT License
*/
uses ( 'set' , 'security' );
/**
* Authentication control component class
*
* Binds access control with user authentication and session management .
*
* @ package cake
* @ subpackage cake . cake . libs . controller . components
*/
class AuthComponent extends Object {
2007-07-26 06:43:44 +00:00
/**
* Maintains current user login state .
*
* @ var boolean
* @ access private
*/
var $_loggedIn = false ;
2007-01-12 17:49:02 +00:00
/**
* Other components utilized by AuthComponent
*
* @ var array
* @ access public
*/
2007-07-08 21:01:31 +00:00
var $components = array ( 'Session' , 'RequestHandler' );
2007-10-09 21:00:32 +00:00
/**
* A reference to the object used for authentication
*
* @ var object
* @ access public
*/
var $authenticate = null ;
2007-01-12 17:49:02 +00:00
/**
2007-07-26 06:43:44 +00:00
* The name of the component to use for Authorization or set this to
2007-09-24 10:11:08 +00:00
* 'controller' will validate against Controller :: isAuthorized ()
2007-07-26 06:43:44 +00:00
* 'actions' will validate Controller :: action against an AclComponent :: check ()
* 'crud' will validate mapActions against an AclComponent :: check ()
* array ( 'model' => 'name' ); will validate mapActions against model $name :: isAuthorize ( user , controller , mapAction )
* 'object' will validate Controller :: action against object :: isAuthorized ( user , controller , action )
2007-01-12 17:49:02 +00:00
*
2007-10-09 21:00:32 +00:00
* @ var mixed
2007-01-12 17:49:02 +00:00
* @ access public
*/
2007-07-09 18:56:45 +00:00
var $authorize = false ;
2007-01-12 17:49:02 +00:00
/**
2007-07-08 21:01:31 +00:00
* The name of an optional view element to render when an Ajax request is made
* with an invalid or expired session
2007-01-12 17:49:02 +00:00
*
* @ var string
* @ access public
*/
2007-07-08 21:01:31 +00:00
var $ajaxLogin = null ;
2007-02-11 18:09:27 +00:00
/**
2007-07-08 21:01:31 +00:00
* The name of the model that represents users which will be authenticated . Defaults to 'User' .
2007-02-11 18:09:27 +00:00
*
* @ var string
* @ access public
*/
2007-07-08 21:01:31 +00:00
var $userModel = 'User' ;
2007-01-12 17:49:02 +00:00
/**
* Additional query conditions to use when looking up and authenticating users ,
* i . e . array ( 'User.is_active' => 1 ) .
*
* @ var array
* @ access public
*/
var $userScope = array ();
/**
* Allows you to specify non - default login name and password fields used in
* $userModel , i . e . array ( 'username' => 'login_name' , 'password' => 'passwd' ) .
*
* @ var array
* @ access public
*/
var $fields = array ( 'username' => 'username' , 'password' => 'password' );
/**
* The session key name where the record of the current user is stored . If
* unspecified , it will be " Auth. { $userModel name } " .
*
* @ var string
* @ access public
*/
var $sessionKey = null ;
/**
* 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
2007-02-10 22:59:08 +00:00
* " Controllers/ " .
2007-01-12 17:49:02 +00:00
*
* @ var string
* @ access public
*/
2007-02-10 22:59:08 +00:00
var $actionPath = null ;
2007-01-12 17:49:02 +00:00
/**
* A URL ( defined as a string or array ) to the controller action that handles
* logins .
*
* @ var mixed
* @ access public
*/
2007-01-22 08:08:34 +00:00
var $loginAction = null ;
2007-01-12 17:49:02 +00:00
/**
* Normally , if a user is redirected to the $loginAction page , the location they
* were redirected from will be stored in the session so that they can be
* redirected back after a successful login . If this session value is not
* set , the user will be redirected to the page specified in $loginRedirect .
*
2007-03-21 05:55:04 +00:00
* @ var mixed
2007-01-12 17:49:02 +00:00
* @ access public
*/
var $loginRedirect = null ;
2007-03-21 05:55:04 +00:00
/**
* The the default action to redirect to after the user is logged out . While AuthComponent does
* not handle post - logout redirection , a redirect URL will be returned from AuthComponent :: logout () .
* Defaults to AuthComponent :: $loginAction .
*
* @ var mixed
* @ access public
* @ see AuthComponent :: $loginAction
* @ see AuthComponent :: logout ()
*/
var $logoutRedirect = null ;
2007-01-12 17:49:02 +00:00
/**
2007-07-26 06:43:44 +00:00
* The name of model or model object , or any other object has an isAuthorized method .
2007-01-12 17:49:02 +00:00
*
2007-01-22 08:08:34 +00:00
* @ var string
2007-01-12 17:49:02 +00:00
* @ access public
*/
2007-07-26 06:43:44 +00:00
var $object = null ;
2007-01-16 12:51:56 +00:00
/**
* Error to display when user login fails . For security purposes , only one error is used for all
* login failures , so as not to expose information on why the login failed .
*
2007-01-22 08:08:34 +00:00
* @ var string
2007-01-16 12:51:56 +00:00
* @ access public
*/
2007-10-20 05:55:37 +00:00
var $loginError = '' ;
2007-02-12 05:05:31 +00:00
/**
* Error to display when user attempts to access an object or action to which they do not have
* acccess .
*
* @ var string
* @ access public
*/
2007-10-20 05:55:37 +00:00
var $authError = '' ;
2007-01-24 02:28:16 +00:00
/**
* Determines whether AuthComponent will automatically redirect and exit if login is successful .
*
* @ var boolean
* @ access public
*/
var $autoRedirect = true ;
2007-01-22 08:08:34 +00:00
/**
* Controller actions for which user validation is not required .
*
* @ var array
* @ access public
* @ see AuthComponent :: allow ()
*/
var $allowedActions = array ();
2007-02-12 05:05:31 +00:00
/**
* Maps actions to CRUD operations . Used for controller - based validation ( $validate = 'controller' ) .
*
* @ var array
* @ access public
* @ see AuthComponent :: mapActions ()
*/
var $actionMap = array (
'index' => 'read' ,
'add' => 'create' ,
'edit' => 'update' ,
'view' => 'read' ,
'remove' => 'delete'
);
2007-02-10 22:59:08 +00:00
/**
* Form data from Controller :: $data
*
* @ var array
* @ access public
*/
var $data = array ();
/**
* Parameter data from Controller :: $params
*
* @ var array
* @ access public
*/
var $params = array ();
2007-02-11 00:29:23 +00:00
/**
* Initializes AuthComponent for use in the controller
*
* @ param object $controller A reference to the instantiating controller object
2007-10-22 06:58:51 +00:00
* @ access public
2007-02-11 00:29:23 +00:00
*/
function initialize ( & $controller ) {
$this -> params = $controller -> params ;
2007-02-12 05:05:31 +00:00
$crud = array ( 'create' , 'read' , 'update' , 'delete' );
$this -> actionMap = am ( $this -> actionMap , array_combine ( $crud , $crud ));
2007-10-20 05:55:37 +00:00
$this -> loginError = __ ( 'Login failed. Invalid username or password.' , true );
$this -> authError = __ ( 'You are not authorized to access that location.' , true );
2007-02-12 05:05:31 +00:00
2007-08-25 18:26:21 +00:00
$admin = Configure :: read ( 'Routing.admin' );
if ( ! empty ( $admin )) {
2007-02-12 05:05:31 +00:00
$this -> actionMap = am ( $this -> actionMap , array (
2007-08-25 18:26:21 +00:00
$admin . '_index' => 'read' ,
$admin . '_add' => 'create' ,
$admin . '_edit' => 'update' ,
$admin . '_view' => 'read' ,
$admin . '_remove' => 'delete' ,
$admin . '_create' => 'create' ,
$admin . '_read' => 'read' ,
$admin . '_update' => 'update' ,
$admin . '_delete' => 'delete'
2007-02-12 05:05:31 +00:00
));
}
2007-06-20 06:15:35 +00:00
if ( Configure :: read () > 0 ) {
2007-04-24 00:26:10 +00:00
uses ( 'debugger' );
Debugger :: checkSessionKey ();
}
2007-02-11 00:29:23 +00:00
}
2007-01-12 17:49:02 +00:00
/**
* Main execution method . Handles redirecting of invalid users , and processing
* of login form data .
*
* @ param object $controller A reference to the instantiating controller object
2007-10-22 06:58:51 +00:00
* @ access public
2007-01-12 17:49:02 +00:00
*/
function startup ( & $controller ) {
2007-03-05 15:14:35 +00:00
if ( low ( $controller -> name ) == 'app' || ( low ( $controller -> name ) == 'tests' && Configure :: read () > 0 )) {
2007-01-12 17:49:02 +00:00
return ;
}
2007-07-08 21:01:31 +00:00
2007-10-02 18:32:44 +00:00
if ( ! $this -> __setDefaults ()) {
2007-02-08 22:10:58 +00:00
return false ;
2007-01-12 17:49:02 +00:00
}
2007-07-26 06:43:44 +00:00
2007-10-02 18:32:44 +00:00
$this -> data = $controller -> data = $this -> hashPasswords ( $controller -> data );
2007-10-09 21:00:32 +00:00
if ( $this -> allowedActions == array ( '*' ) || in_array ( $controller -> action , $this -> allowedActions )) {
return false ;
}
2007-01-16 12:51:56 +00:00
if ( ! isset ( $controller -> params [ 'url' ][ 'url' ])) {
$url = '' ;
} else {
$url = $controller -> params [ 'url' ][ 'url' ];
}
2007-08-15 18:37:43 +00:00
$this -> loginAction = $this -> _normalizeURL ( $this -> loginAction );
if ( $this -> loginAction == $this -> _normalizeURL ( $url )) {
2007-01-22 08:08:34 +00:00
if ( empty ( $controller -> data ) || ! isset ( $controller -> data [ $this -> userModel ])) {
2007-08-15 18:37:43 +00:00
if ( ! $this -> Session -> check ( 'Auth.redirect' ) && env ( 'HTTP_REFERER' )) {
2007-02-11 18:09:27 +00:00
$this -> Session -> write ( 'Auth.redirect' , $controller -> referer ());
}
2007-07-08 21:01:31 +00:00
return false ;
2007-01-12 17:49:02 +00:00
}
2007-07-26 06:43:44 +00:00
2007-01-22 08:08:34 +00:00
$data = array (
2007-02-05 20:19:34 +00:00
$this -> userModel . '.' . $this -> fields [ 'username' ] => '= ' . $controller -> data [ $this -> userModel ][ $this -> fields [ 'username' ]],
$this -> userModel . '.' . $this -> fields [ 'password' ] => '= ' . $controller -> data [ $this -> userModel ][ $this -> fields [ 'password' ]]
2007-01-22 08:08:34 +00:00
);
2007-07-08 21:01:31 +00:00
2007-07-26 06:43:44 +00:00
if ( $this -> login ( $data )) {
if ( $this -> autoRedirect ) {
$controller -> redirect ( $this -> redirect (), null , true );
}
2007-07-08 21:01:31 +00:00
return true ;
2007-01-22 08:08:34 +00:00
} else {
2007-08-07 07:44:12 +00:00
$this -> Session -> setFlash ( $this -> loginError , 'default' , array (), 'auth' );
2007-02-05 20:19:34 +00:00
unset ( $controller -> data [ $this -> userModel ][ $this -> fields [ 'password' ]]);
2007-01-12 17:49:02 +00:00
}
2007-07-26 07:16:46 +00:00
return false ;
2007-01-12 17:49:02 +00:00
} else {
2007-02-10 22:59:08 +00:00
if ( ! $this -> user ()) {
2007-01-12 17:49:02 +00:00
if ( ! $this -> RequestHandler -> isAjax ()) {
2007-09-21 01:57:27 +00:00
$this -> Session -> setFlash ( $this -> authError , 'default' , array (), 'auth' );
2007-01-16 12:51:56 +00:00
$this -> Session -> write ( 'Auth.redirect' , $url );
2007-08-15 18:37:43 +00:00
$controller -> redirect ( $this -> loginAction , null , true );
2007-07-08 21:01:31 +00:00
return false ;
2007-02-10 22:59:08 +00:00
} elseif ( ! empty ( $this -> ajaxLogin )) {
2007-02-11 18:09:27 +00:00
$controller -> viewPath = 'elements' ;
$controller -> render ( $this -> ajaxLogin , 'ajax' );
2007-07-08 21:01:31 +00:00
exit ();
2007-01-12 17:49:02 +00:00
}
}
}
2007-07-09 04:38:58 +00:00
2007-07-25 04:38:28 +00:00
if ( $this -> authorize ) {
2007-07-09 05:27:04 +00:00
extract ( $this -> __authType ());
2007-10-06 01:00:55 +00:00
switch ( $type ) {
case 'controller' :
$this -> object =& $controller ;
break ;
case 'crud' :
case 'actions' :
if ( isset ( $controller -> Acl )) {
$this -> Acl =& $controller -> Acl ;
} else {
trigger_error ( __ ( 'Could not find AclComponent. Please include Acl in Controller::$components.' , true ), E_USER_WARNING );
}
break ;
case 'model' :
if ( ! isset ( $object )) {
if ( isset ( $controller -> { $controller -> modelClass }) && is_object ( $controller -> { $controller -> modelClass })) {
$object = $controller -> modelClass ;
} elseif ( ! empty ( $controller -> uses ) && isset ( $controller -> { $controller -> uses [ 0 ]}) && is_object ( $controller -> { $controller -> uses [ 0 ]})) {
$object = $controller -> uses [ 0 ];
2007-07-26 06:43:44 +00:00
}
2007-10-06 01:00:55 +00:00
}
$type = array ( 'model' => $object );
break ;
default :
2007-07-09 05:27:04 +00:00
return true ;
2007-10-06 01:00:55 +00:00
break ;
2007-07-08 21:01:31 +00:00
}
2007-10-06 01:00:55 +00:00
if ( $this -> isAuthorized ( $type )) {
return true ;
}
2007-08-07 07:44:12 +00:00
$this -> Session -> setFlash ( $this -> authError , 'default' , array (), 'auth' );
2007-07-09 05:27:04 +00:00
$controller -> redirect ( $controller -> referer (), null , true );
return false ;
} else {
return true ;
2007-02-12 05:05:31 +00:00
}
}
/**
* Attempts to introspect the correct values for object properties including
* $userModel and $sessionKey .
*
* @ param object $controller A reference to the instantiating controller object
2007-10-22 06:58:51 +00:00
* @ access private
2007-02-12 05:05:31 +00:00
*/
2007-05-23 18:15:58 +00:00
function __setDefaults () {
2007-02-12 05:05:31 +00:00
if ( empty ( $this -> userModel )) {
2007-10-20 05:55:37 +00:00
trigger_error ( __ ( " Could not find \$ userModel. Please set AuthComponent:: \$ userModel in beforeFilter(). " , true ), E_USER_WARNING );
2007-02-12 05:05:31 +00:00
return false ;
}
if ( empty ( $this -> loginAction )) {
2007-07-08 21:01:31 +00:00
$this -> loginAction = Router :: url ( array ( 'controller' => Inflector :: underscore ( Inflector :: pluralize ( $this -> userModel )), 'action' => 'login' ));
2007-02-12 05:05:31 +00:00
}
if ( empty ( $this -> sessionKey )) {
$this -> sessionKey = 'Auth.' . $this -> userModel ;
}
2007-09-03 05:08:48 +00:00
if ( empty ( $this -> logoutRedirect )) {
2007-03-21 05:55:04 +00:00
$this -> logoutRedirect = $this -> loginAction ;
}
2007-02-12 05:05:31 +00:00
return true ;
}
/**
* Determines whether the given user is authorized to perform an action . The type of authorization
2007-07-26 06:43:44 +00:00
* used is based on the value of AuthComponent :: $authorize or the passed $type param .
*
* Types :
2007-10-06 01:00:55 +00:00
* 'controller' will validate against Controller :: isAuthorized () if controller instance is passed in $object
2007-07-26 06:43:44 +00:00
* 'actions' will validate Controller :: action against an AclComponent :: check ()
* 'crud' will validate mapActions against an AclComponent :: check ()
* array ( 'model' => 'name' ); will validate mapActions against model $name :: isAuthorize ( user , controller , mapAction )
* 'object' will validate Controller :: action against object :: isAuthorized ( user , controller , action )
2007-02-12 05:05:31 +00:00
*
2007-10-22 06:58:51 +00:00
* @ param string $type Type of authorization
2007-07-26 06:43:44 +00:00
* @ param mixed $object object , model object , or model name
2007-10-22 06:58:51 +00:00
* @ param mixed $user The user to check the authorization of
2007-10-22 16:09:35 +00:00
* @ return boolean True if $user is authorized , otherwise false
2007-10-22 06:58:51 +00:00
* @ access public
2007-02-12 05:05:31 +00:00
*/
2007-07-26 06:43:44 +00:00
function isAuthorized ( $type = null , $object = null , $user = null ) {
2007-04-10 16:48:45 +00:00
if ( empty ( $user ) && ! $this -> user ()) {
return false ;
} elseif ( empty ( $user )) {
2007-02-12 05:05:31 +00:00
$user = $this -> user ();
2007-02-10 22:59:08 +00:00
}
2007-07-08 21:01:31 +00:00
2007-07-26 06:43:44 +00:00
extract ( $this -> __authType ( $type ));
2007-02-10 22:59:08 +00:00
2007-07-25 04:38:28 +00:00
if ( ! $object ) {
2007-07-26 06:43:44 +00:00
$object = $this -> object ;
2007-02-11 18:09:27 +00:00
}
2007-02-12 05:05:31 +00:00
$valid = false ;
2007-02-10 22:59:08 +00:00
switch ( $type ) {
2007-10-06 01:00:55 +00:00
case 'controller' :
$valid = $object -> isAuthorized ();
break ;
2007-01-12 17:49:02 +00:00
case 'actions' :
2007-04-10 16:48:45 +00:00
$valid = $this -> Acl -> check ( $user , $this -> action ());
2007-01-12 17:49:02 +00:00
break ;
2007-07-08 21:01:31 +00:00
case 'crud' :
2007-02-12 05:05:31 +00:00
$this -> mapActions ();
if ( ! isset ( $this -> actionMap [ $this -> params [ 'action' ]])) {
2007-09-18 04:16:04 +00:00
trigger_error ( sprintf ( __ ( 'Auth::startup() - Attempted access of un-mapped action "%s" in controller "%s"' , true ), $this -> params [ 'action' ], $this -> params [ 'controller' ]), E_USER_WARNING );
2007-02-12 05:05:31 +00:00
} else {
2007-04-10 16:48:45 +00:00
$valid = $this -> Acl -> check ( $user , $this -> action ( ':controller' ), $this -> actionMap [ $this -> params [ 'action' ]]);
2007-02-12 05:05:31 +00:00
}
2007-01-12 17:49:02 +00:00
break ;
2007-07-08 21:01:31 +00:00
case 'model' :
2007-07-26 06:43:44 +00:00
$this -> mapActions ();
2007-10-03 00:50:23 +00:00
$action = $this -> params [ 'action' ];
if ( isset ( $this -> actionMap [ $action ])) {
$action = $this -> actionMap [ $action ];
}
2007-07-26 06:43:44 +00:00
if ( is_string ( $object )) {
$object = $this -> getModel ( $object );
}
case 'object' :
if ( ! isset ( $action )) {
$action = $this -> action ( ':action' );
}
2007-07-25 04:38:28 +00:00
if ( empty ( $object )) {
2007-09-18 04:16:04 +00:00
trigger_error ( sprintf ( __ ( 'Could not find %s. Set AuthComponent::$object in beforeFilter() or pass a valid object' , true ), get_class ( $object )), E_USER_WARNING );
2007-07-08 21:01:31 +00:00
return ;
}
2007-07-26 06:43:44 +00:00
if ( method_exists ( $object , 'isAuthorized' )) {
$valid = $object -> isAuthorized ( $user , $this -> action ( ':controller' ), $action );
} elseif ( $object ){
2007-09-18 04:16:04 +00:00
trigger_error ( sprintf ( __ ( '%s::isAuthorized() is not defined.' , true ), get_class ( $object )), E_USER_WARNING );
2007-07-08 21:01:31 +00:00
}
break ;
2007-01-23 15:22:23 +00:00
case null :
case false :
2007-03-14 20:53:14 +00:00
return true ;
2007-01-23 15:22:23 +00:00
break ;
2007-01-12 17:49:02 +00:00
default :
2007-07-26 06:43:44 +00:00
trigger_error ( __ ( 'Auth::isAuthorized() - $authorize is set to an incorrect value. Allowed settings are: "actions", "crud", "model" or null.' , true ), E_USER_WARNING );
2007-01-12 17:49:02 +00:00
break ;
}
2007-02-12 05:05:31 +00:00
return $valid ;
2007-01-12 17:49:02 +00:00
}
2007-05-23 18:15:58 +00:00
/**
2007-10-22 06:58:51 +00:00
* Get authorization type
2007-05-23 18:15:58 +00:00
*
2007-10-22 06:58:51 +00:00
* @ param string $auth Type of authorization
* @ return array Associative array with : type , object
2007-05-23 18:15:58 +00:00
* @ access private
*/
2007-02-12 05:05:31 +00:00
function __authType ( $auth = null ) {
2007-07-26 06:43:44 +00:00
if ( $auth == null ) {
2007-07-08 21:01:31 +00:00
$auth = $this -> authorize ;
2007-01-22 08:08:34 +00:00
}
2007-07-26 06:43:44 +00:00
$object = null ;
2007-02-12 05:05:31 +00:00
if ( is_array ( $auth )) {
$type = key ( $auth );
$object = $auth [ $type ];
} else {
$type = $auth ;
2007-08-07 07:44:12 +00:00
return compact ( 'type' );
2007-01-12 17:49:02 +00:00
}
2007-07-08 21:01:31 +00:00
return compact ( 'type' , 'object' );
2007-01-12 17:49:02 +00:00
}
2007-01-22 08:08:34 +00:00
/**
2007-01-24 04:38:39 +00:00
* Takes a list of actions in the current controller for which authentication is not required , or
2007-01-22 08:08:34 +00:00
* no parameters to allow all actions .
*
2007-01-23 15:22:23 +00:00
* @ param string $action Controller action name
* @ param string $action Controller action name
* @ param string ... etc .
2007-10-22 06:58:51 +00:00
* @ access public
2007-01-22 08:08:34 +00:00
*/
function allow () {
$args = func_get_args ();
if ( empty ( $args )) {
$this -> allowedActions = array ( '*' );
} else {
2007-02-11 18:09:27 +00:00
$this -> allowedActions = am ( $this -> allowedActions , $args );
}
}
/**
* Removes items from the list of allowed actions .
*
* @ param string $action Controller action name
* @ param string $action Controller action name
* @ param string ... etc .
* @ see AuthComponent :: allow ()
2007-10-22 06:58:51 +00:00
* @ access public
2007-02-11 18:09:27 +00:00
*/
function deny () {
$args = func_get_args ();
foreach ( $args as $arg ) {
$i = array_search ( $arg , $this -> allowedActions );
if ( is_int ( $i )) {
unset ( $this -> allowedActions [ $i ]);
}
2007-01-22 08:08:34 +00:00
}
2007-02-11 18:09:27 +00:00
$this -> allowedActions = array_values ( $this -> allowedActions );
2007-01-22 08:08:34 +00:00
}
2007-02-12 05:05:31 +00:00
/**
2007-10-22 06:58:51 +00:00
* Maps action names to CRUD operations . Used for controller - based authentication .
2007-02-12 05:05:31 +00:00
*
2007-10-22 06:58:51 +00:00
* @ param array $map Actions to map
2007-02-12 05:05:31 +00:00
* @ access public
*/
function mapActions ( $map = array ()) {
2007-02-12 21:56:06 +00:00
$crud = array ( 'create' , 'read' , 'update' , 'delete' );
foreach ( $map as $action => $type ) {
if ( in_array ( $action , $crud ) && is_array ( $type )) {
foreach ( $type as $typedAction ) {
$this -> actionMap [ $typedAction ] = $action ;
}
} else {
$this -> actionMap [ $action ] = $type ;
}
}
2007-02-12 05:05:31 +00:00
}
2007-01-23 15:22:23 +00:00
/**
2007-01-24 04:38:39 +00:00
* Manually log - in a user with the given parameter data . The $data provided can be any data
* structure used to identify a user in AuthComponent :: identify () . If $data is empty or not
* specified , POST data from Controller :: $data will be used automatically .
*
* After ( if ) login is successful , the user record is written to the session key specified in
* AuthComponent :: $sessionKey .
2007-01-23 15:22:23 +00:00
*
* @ param mixed $data User object
2007-10-22 16:09:35 +00:00
* @ return boolean True on login success , false on failure
2007-10-22 06:58:51 +00:00
* @ access public
2007-01-23 15:22:23 +00:00
*/
function login ( $data = null ) {
2007-05-23 18:15:58 +00:00
$this -> __setDefaults ();
2007-01-23 15:22:23 +00:00
$this -> _loggedIn = false ;
if ( empty ( $data )) {
$data = $this -> data ;
}
if ( $user = $this -> identify ( $data )) {
$this -> Session -> write ( $this -> sessionKey , $user );
$this -> _loggedIn = true ;
}
return $this -> _loggedIn ;
}
2007-01-24 02:28:16 +00:00
/**
* Logs a user out , and returns the login action to redirect to .
*
* @ param mixed $url Optional URL to redirect the user to after logout
* @ return string AuthComponent :: $loginAction
2007-01-24 04:38:39 +00:00
* @ see AuthComponent :: $loginAction
2007-10-22 06:58:51 +00:00
* @ access public
2007-01-24 02:28:16 +00:00
*/
function logout () {
2007-05-23 18:15:58 +00:00
$this -> __setDefaults ();
2007-01-24 07:26:52 +00:00
$this -> Session -> del ( $this -> sessionKey );
$this -> Session -> del ( 'Auth.redirect' );
2007-01-24 02:28:16 +00:00
$this -> _loggedIn = false ;
2007-03-21 05:55:04 +00:00
return $this -> _normalizeURL ( $this -> logoutRedirect );
2007-01-24 02:28:16 +00:00
}
2007-01-23 16:27:34 +00:00
/**
* Get the current user from the session .
*
* @ return array User record , or null if no user is logged in .
2007-10-22 06:58:51 +00:00
* @ access public
2007-01-23 16:27:34 +00:00
*/
2007-01-24 07:26:52 +00:00
function user ( $key = null ) {
2007-05-23 18:15:58 +00:00
$this -> __setDefaults ();
2007-01-23 16:27:34 +00:00
if ( ! $this -> Session -> check ( $this -> sessionKey )) {
return null ;
}
2007-07-08 21:01:31 +00:00
2007-01-24 07:26:52 +00:00
if ( $key == null ) {
return array ( $this -> userModel => $this -> Session -> read ( $this -> sessionKey ));
} else {
$user = $this -> Session -> read ( $this -> sessionKey );
if ( isset ( $user [ $key ])) {
return $user [ $key ];
} else {
return null ;
}
}
2007-01-23 16:27:34 +00:00
}
2007-01-23 15:22:23 +00:00
/**
2007-02-11 18:09:27 +00:00
* If no parameter is passed , gets the authentication redirect URL .
2007-01-23 15:22:23 +00:00
*
2007-02-11 18:09:27 +00:00
* @ param mixed $url Optional URL to write as the login redirect URL .
2007-01-23 15:22:23 +00:00
* @ return string Redirect URL
2007-10-22 06:58:51 +00:00
* @ access public
2007-01-23 15:22:23 +00:00
*/
2007-02-11 18:09:27 +00:00
function redirect ( $url = null ) {
2007-06-20 06:15:35 +00:00
if ( ! is_null ( $url )) {
2007-02-11 18:09:27 +00:00
return $this -> Session -> write ( 'Auth.redirect' , $url );
}
2007-01-23 15:22:23 +00:00
if ( $this -> Session -> check ( 'Auth.redirect' )) {
$redir = $this -> Session -> read ( 'Auth.redirect' );
$this -> Session -> delete ( 'Auth.redirect' );
2007-02-20 17:45:41 +00:00
2007-08-15 18:37:43 +00:00
if ( $this -> _normalizeURL ( $redir ) == $this -> loginAction ) {
2007-02-20 17:45:41 +00:00
$redir = $this -> loginRedirect ;
}
2007-01-23 15:22:23 +00:00
} else {
$redir = $this -> loginRedirect ;
}
2007-03-23 16:46:19 +00:00
return $this -> _normalizeURL ( $redir );
2007-01-23 15:22:23 +00:00
}
2007-01-12 17:49:02 +00:00
/**
* Validates a user against an abstract object .
*
* @ param mixed $object The object to validate the user against .
* @ param mixed $user Optional . The identity of the user to be validated .
* Uses the current user session if none specified . For
* valid forms of identifying users , see
* AuthComponent :: identify () .
2007-10-22 06:58:51 +00:00
* @ param string $action Optional . The action to validate against .
2007-01-12 17:49:02 +00:00
* @ see AuthComponent :: identify ()
2007-10-22 16:09:35 +00:00
* @ return boolean True if the user validates , false otherwise .
2007-10-22 06:58:51 +00:00
* @ access public
2007-01-12 17:49:02 +00:00
*/
2007-02-11 00:29:23 +00:00
function validate ( $object , $user = null , $action = null ) {
2007-02-10 22:59:08 +00:00
if ( empty ( $user )) {
2007-07-08 21:01:31 +00:00
$this -> getModel ();
2007-02-10 22:59:08 +00:00
$user = $this -> user ();
}
2007-02-08 22:10:58 +00:00
if ( empty ( $user )) {
2007-01-12 17:49:02 +00:00
return false ;
}
2007-02-11 18:09:27 +00:00
return $this -> Acl -> check ( $user , $object , $action );
2007-01-12 17:49:02 +00:00
}
/**
2007-02-11 18:09:27 +00:00
* Returns the path to the ACO node bound to a controller / action .
2007-01-12 17:49:02 +00:00
*
* @ param string $action Optional . The controller / action path to validate the
* user against . The current request action is used if
* none is specified .
2007-10-22 16:09:35 +00:00
* @ return boolean ACO node path
2007-10-22 06:58:51 +00:00
* @ access public
2007-01-12 17:49:02 +00:00
*/
2007-02-11 18:09:27 +00:00
function action ( $action = ':controller/:action' ) {
return r (
2007-01-12 17:49:02 +00:00
array ( ':controller' , ':action' ),
2007-02-10 22:59:08 +00:00
array ( Inflector :: camelize ( $this -> params [ 'controller' ]), $this -> params [ 'action' ]),
2007-02-11 18:09:27 +00:00
$this -> actionPath . $action
2007-01-12 17:49:02 +00:00
);
}
/**
2007-10-22 06:58:51 +00:00
* Returns a reference to the model object specified , and attempts
2007-01-12 17:49:02 +00:00
* to load it if it is not found .
*
2007-10-22 06:58:51 +00:00
* @ param string $name Model name ( defaults to AuthComponent :: $userModel )
* @ return object A reference to a model object
2007-01-12 17:49:02 +00:00
* @ access public
*/
2007-07-08 21:01:31 +00:00
function & getModel ( $name = null ) {
$model = null ;
2007-07-25 04:38:28 +00:00
if ( ! $name ) {
2007-07-08 21:01:31 +00:00
$name = $this -> userModel ;
}
if ( ! ClassRegistry :: isKeySet ( $name )) {
if ( ! loadModel ( Inflector :: underscore ( $name ))) {
2007-09-18 04:16:04 +00:00
trigger_error ( sprintf ( __ ( 'Auth::getModel() - %s is not set or could not be found' , true ), $name ), E_USER_WARNING );
2007-07-09 05:27:04 +00:00
return $model ;
2007-02-11 00:29:23 +00:00
} else {
2007-07-08 21:01:31 +00:00
$model = new $name ();
2007-01-12 17:49:02 +00:00
}
}
2007-02-12 00:57:44 +00:00
2007-07-08 21:01:31 +00:00
if ( empty ( $model )) {
2007-02-11 00:29:23 +00:00
if ( PHP5 ) {
2007-07-08 21:01:31 +00:00
$model = ClassRegistry :: getObject ( $name );
2007-02-11 00:29:23 +00:00
} else {
2007-07-08 21:01:31 +00:00
$model =& ClassRegistry :: getObject ( $name );
2007-02-11 00:29:23 +00:00
}
2007-01-12 17:49:02 +00:00
}
2007-02-11 00:29:23 +00:00
2007-07-08 21:01:31 +00:00
if ( empty ( $model )) {
2007-09-18 04:16:04 +00:00
trigger_error ( sprintf ( __ ( 'Auth::getModel() - %s is not set or could not be found' , true ), $name ), E_USER_WARNING );
2007-01-12 17:49:02 +00:00
return null ;
}
2007-07-08 21:01:31 +00:00
return $model ;
2007-01-12 17:49:02 +00:00
}
/**
* Identifies a user based on specific criteria .
*
* @ param mixed $user Optional . The identity of the user to be validated .
* Uses the current user session if none specified .
* @ return array User record data , or null , if the user could not be identified .
2007-10-22 06:58:51 +00:00
* @ access public
2007-01-12 17:49:02 +00:00
*/
function identify ( $user = null ) {
2007-02-08 22:10:58 +00:00
if ( empty ( $user )) {
$user = $this -> user ();
if ( empty ( $user )) {
return null ;
}
2007-06-20 06:15:35 +00:00
} elseif ( is_object ( $user ) && is_a ( $user , 'Model' )) {
2007-01-23 15:22:23 +00:00
if ( ! $user -> exists ()) {
return null ;
}
$user = $user -> read ();
$user = $user [ $this -> userModel ];
2007-06-20 06:15:35 +00:00
} elseif ( is_array ( $user ) && isset ( $user [ $this -> userModel ])) {
2007-01-12 17:49:02 +00:00
$user = $user [ $this -> userModel ];
2007-01-23 15:22:23 +00:00
}
2007-07-06 03:47:35 +00:00
2007-01-23 15:22:23 +00:00
if ( is_array ( $user ) && ( isset ( $user [ $this -> fields [ 'username' ]]) || isset ( $user [ $this -> userModel . '.' . $this -> fields [ 'username' ]]))) {
2007-05-23 18:15:58 +00:00
if ( isset ( $user [ $this -> fields [ 'username' ]]) && ! empty ( $user [ $this -> fields [ 'username' ]]) && ! empty ( $user [ $this -> fields [ 'password' ]])) {
2007-06-20 05:59:56 +00:00
if ( trim ( $user [ $this -> fields [ 'username' ]]) == '=' || trim ( $user [ $this -> fields [ 'password' ]]) == '=' ) {
2007-04-12 02:32:16 +00:00
return false ;
}
2007-01-23 15:22:23 +00:00
$find = array (
$this -> fields [ 'username' ] => $user [ $this -> fields [ 'username' ]],
$this -> fields [ 'password' ] => $user [ $this -> fields [ 'password' ]]
);
2007-04-12 02:32:16 +00:00
} elseif ( isset ( $user [ $this -> userModel . '.' . $this -> fields [ 'username' ]]) && ! empty ( $user [ $this -> userModel . '.' . $this -> fields [ 'username' ]])) {
2007-06-20 05:59:56 +00:00
if ( trim ( $user [ $this -> userModel . '.' . $this -> fields [ 'username' ]]) == '=' || trim ( $user [ $this -> userModel . '.' . $this -> fields [ 'password' ]]) == '=' ) {
2007-04-12 02:32:16 +00:00
return false ;
}
2007-01-23 15:22:23 +00:00
$find = array (
$this -> fields [ 'username' ] => $user [ $this -> userModel . '.' . $this -> fields [ 'username' ]],
$this -> fields [ 'password' ] => $user [ $this -> userModel . '.' . $this -> fields [ 'password' ]]
);
2007-09-25 14:22:05 +00:00
} else {
return false ;
2007-01-23 15:22:23 +00:00
}
2007-07-08 21:01:31 +00:00
$model =& $this -> getModel ();
2007-09-25 14:22:05 +00:00
$data = $model -> find ( am ( $find , $this -> userScope ), null , null , - 1 );
2007-01-12 17:49:02 +00:00
if ( empty ( $data ) || empty ( $data [ $this -> userModel ])) {
return null ;
}
2007-06-20 06:15:35 +00:00
} elseif ( is_numeric ( $user )) {
2007-01-12 17:49:02 +00:00
// Assume it's a user's ID
2007-07-08 21:01:31 +00:00
$model =& $this -> getModel ();
2007-02-11 18:09:27 +00:00
$data = $model -> find ( am ( array ( $model -> escapeField () => $user ), $this -> userScope ));
2007-01-12 17:49:02 +00:00
if ( empty ( $data ) || empty ( $data [ $this -> userModel ])) {
return null ;
}
2007-02-08 23:44:58 +00:00
}
if ( isset ( $data ) && ! empty ( $data )) {
2007-06-20 06:15:35 +00:00
if ( ! empty ( $data [ $this -> userModel ][ $this -> fields [ 'password' ]])) {
2007-02-08 23:44:58 +00:00
unset ( $data [ $this -> userModel ][ $this -> fields [ 'password' ]]);
}
2007-01-12 17:49:02 +00:00
return $data [ $this -> userModel ];
} else {
return null ;
}
}
2007-02-10 22:59:08 +00:00
/**
2007-04-02 20:00:56 +00:00
* Hash any passwords found in $data using $userModel and $fields [ 'password' ]
2007-02-10 22:59:08 +00:00
*
2007-10-22 06:58:51 +00:00
* @ param array $data Set of data to look for passwords
* @ return array Data with passwords hashed
2007-02-10 22:59:08 +00:00
* @ access public
*/
2007-03-21 15:40:46 +00:00
function hashPasswords ( $data ) {
2007-10-09 21:00:32 +00:00
if ( is_object ( $this -> authenticate ) && method_exists ( $this -> authenticate , 'hashPasswords' )) {
return $this -> authenticate -> hashPasswords ( $data );
}
2007-03-21 15:40:46 +00:00
if ( isset ( $data [ $this -> userModel ])) {
2007-10-19 21:49:29 +00:00
if ( isset ( $data [ $this -> userModel ][ $this -> fields [ 'username' ]]) && isset ( $data [ $this -> userModel ][ $this -> fields [ 'password' ]])) {
2007-04-02 20:00:56 +00:00
$data [ $this -> userModel ][ $this -> fields [ 'password' ]] = $this -> password ( $data [ $this -> userModel ][ $this -> fields [ 'password' ]]);
2007-02-10 22:59:08 +00:00
}
}
2007-03-21 15:40:46 +00:00
return $data ;
2007-02-10 22:59:08 +00:00
}
2007-04-02 20:00:56 +00:00
/**
2007-10-16 09:05:25 +00:00
* Hash a password with the application 's salt value (as defined with Configure::write(' Security . salt ' );
2007-04-02 20:00:56 +00:00
*
2007-10-22 06:58:51 +00:00
* @ param string $password Password to hash
* @ return string Hashed password
2007-04-02 20:00:56 +00:00
* @ access public
*/
function password ( $password ) {
2007-10-16 09:05:25 +00:00
return Security :: hash ( Configure :: read ( 'Security.salt' ) . $password );
2007-04-02 20:00:56 +00:00
}
2007-01-23 15:22:23 +00:00
/**
* Component shutdown . If user is logged in , wipe out redirect .
*
2007-10-22 06:58:51 +00:00
* @ param object $controller Instantiating controller
2007-01-23 15:22:23 +00:00
* @ access public
*/
function shutdown ( & $controller ) {
if ( $this -> _loggedIn ) {
$this -> Session -> del ( 'Auth.redirect' );
}
}
2007-01-22 08:08:34 +00:00
/**
2007-10-22 06:58:51 +00:00
* Normalizes a URL
*
* @ param string $url URL to normalize
* @ return string Normalized URL
2007-05-23 18:15:58 +00:00
* @ access protected
2007-01-22 08:08:34 +00:00
*/
function _normalizeURL ( $url = '/' ) {
if ( is_array ( $url )) {
$url = Router :: url ( $url );
2007-07-08 21:01:31 +00:00
}
$paths = Router :: getPaths ();
2007-07-25 19:42:58 +00:00
if ( ! empty ( $paths [ 'base' ]) && stristr ( $url , $paths [ 'base' ])) {
2007-01-22 08:08:34 +00:00
$url = r ( $paths [ 'base' ], '' , $url );
}
2007-07-08 21:01:31 +00:00
2007-01-24 02:28:16 +00:00
$url = '/' . $url . '/' ;
while ( strpos ( $url , '//' ) !== false ) {
$url = r ( '//' , '/' , $url );
}
return $url ;
2007-01-22 08:08:34 +00:00
}
2007-01-12 17:49:02 +00:00
}
2007-10-06 01:00:55 +00:00
?>