2008-05-30 11:40:08 +00:00
< ? php
/**
* Authentication component
*
* Manages user logins and permissions .
*
2010-10-03 16:38:58 +00:00
* PHP 5
2008-05-30 11:40:08 +00:00
*
2009-11-06 06:46:59 +00:00
* CakePHP ( tm ) : Rapid Development Framework ( http :// cakephp . org )
2010-01-26 19:18:20 +00:00
* Copyright 2005 - 2010 , Cake Software Foundation , Inc . ( http :// cakefoundation . org )
2008-05-30 11:40:08 +00:00
*
* Licensed under The MIT License
* Redistributions of files must retain the above copyright notice .
*
2010-01-26 19:18:20 +00:00
* @ copyright Copyright 2005 - 2010 , Cake Software Foundation , Inc . ( http :// cakefoundation . org )
2009-11-06 06:00:11 +00:00
* @ link http :// cakephp . org CakePHP ( tm ) Project
2010-12-24 18:57:20 +00:00
* @ package cake . libs . controller . components
2008-10-30 17:30:26 +00:00
* @ since CakePHP ( tm ) v 0.10 . 0.1076
2009-11-06 06:51:51 +00:00
* @ license MIT License ( http :// www . opensource . org / licenses / mit - license . php )
2008-05-30 11:40:08 +00:00
*/
2010-11-22 03:11:59 +00:00
App :: import ( 'Core' , 'Router' , false );
App :: import ( 'Core' , 'Security' , false );
2008-05-30 11:40:08 +00:00
/**
* Authentication control component class
*
* Binds access control with user authentication and session management .
*
2010-12-24 18:57:20 +00:00
* @ package cake . libs . controller . components
2010-04-05 01:12:13 +00:00
* @ link http :// book . cakephp . org / view / 1250 / Authentication
2008-05-30 11:40:08 +00:00
*/
2010-07-04 19:12:42 +00:00
class AuthComponent extends Component {
2009-07-24 19:18:37 +00:00
2008-05-30 11:40:08 +00:00
/**
* Maintains current user login state .
*
* @ var boolean
*/
2010-04-04 06:36:12 +00:00
protected $_loggedIn = false ;
2009-07-24 19:18:37 +00:00
2008-05-30 11:40:08 +00:00
/**
* Other components utilized by AuthComponent
*
* @ var array
*/
2010-04-04 07:14:00 +00:00
public $components = array ( 'Session' , 'RequestHandler' );
2009-07-24 19:18:37 +00:00
2008-05-30 11:40:08 +00:00
/**
* A reference to the object used for authentication
*
* @ var object
2010-04-05 01:12:13 +00:00
* @ link http :// book . cakephp . org / view / 1278 / authenticate
2008-05-30 11:40:08 +00:00
*/
2010-04-04 07:14:00 +00:00
public $authenticate = null ;
2009-07-24 19:18:37 +00:00
2008-05-30 11:40:08 +00:00
/**
* The name of the component to use for Authorization or set this to
* 'controller' will validate against Controller :: isAuthorized ()
* 'actions' will validate Controller :: action against an AclComponent :: check ()
* 'crud' will validate mapActions against an AclComponent :: check ()
2008-12-18 14:31:53 +00:00
* array ( 'model' => 'name' ); will validate mapActions against model $name :: isAuthorized ( user , controller , mapAction )
2008-05-30 11:40:08 +00:00
* 'object' will validate Controller :: action against object :: isAuthorized ( user , controller , action )
*
* @ var mixed
2010-04-05 01:12:13 +00:00
* @ link http :// book . cakephp . org / view / 1275 / authorize
2008-05-30 11:40:08 +00:00
*/
2010-04-04 07:14:00 +00:00
public $authorize = false ;
2009-07-24 19:18:37 +00:00
2008-05-30 11:40:08 +00:00
/**
* The name of an optional view element to render when an Ajax request is made
* with an invalid or expired session
*
* @ var string
2010-04-05 01:12:13 +00:00
* @ link http :// book . cakephp . org / view / 1277 / ajaxLogin
2008-05-30 11:40:08 +00:00
*/
2010-04-04 07:14:00 +00:00
public $ajaxLogin = null ;
2009-07-24 19:18:37 +00:00
2009-08-13 15:18:46 +00:00
/**
2009-10-14 21:27:34 +00:00
* The name of the element used for SessionComponent :: setFlash
2009-08-13 15:18:46 +00:00
*
* @ var string
*/
2010-04-04 07:14:00 +00:00
public $flashElement = 'default' ;
2009-08-13 15:18:46 +00:00
2008-05-30 11:40:08 +00:00
/**
* The name of the model that represents users which will be authenticated . Defaults to 'User' .
*
* @ var string
2010-04-05 01:12:13 +00:00
* @ link http :// book . cakephp . org / view / 1266 / userModel
2008-05-30 11:40:08 +00:00
*/
2010-04-04 07:14:00 +00:00
public $userModel = 'User' ;
2009-07-24 19:18:37 +00:00
2008-05-30 11:40:08 +00:00
/**
* Additional query conditions to use when looking up and authenticating users ,
* i . e . array ( 'User.is_active' => 1 ) .
*
* @ var array
2010-04-05 01:12:13 +00:00
* @ link http :// book . cakephp . org / view / 1268 / userScope
2008-05-30 11:40:08 +00:00
*/
2010-04-04 07:14:00 +00:00
public $userScope = array ();
2009-07-24 19:18:37 +00:00
2008-05-30 11:40:08 +00:00
/**
* Allows you to specify non - default login name and password fields used in
* $userModel , i . e . array ( 'username' => 'login_name' , 'password' => 'passwd' ) .
*
* @ var array
2010-04-05 01:12:13 +00:00
* @ link http :// book . cakephp . org / view / 1267 / fields
2008-05-30 11:40:08 +00:00
*/
2010-04-04 07:14:00 +00:00
public $fields = array ( 'username' => 'username' , 'password' => 'password' );
2009-07-24 19:18:37 +00:00
2008-05-30 11:40:08 +00:00
/**
* The session key name where the record of the current user is stored . If
* unspecified , it will be " Auth. { $userModel name } " .
*
* @ var string
2010-04-05 01:12:13 +00:00
* @ link http :// book . cakephp . org / view / 1276 / sessionKey
2008-05-30 11:40:08 +00:00
*/
2010-04-04 07:14:00 +00:00
public $sessionKey = null ;
2009-07-24 19:18:37 +00:00
2008-05-30 11:40:08 +00:00
/**
* 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/ " .
*
* @ var string
2010-04-05 01:12:13 +00:00
* @ link http :// book . cakephp . org / view / 1279 / actionPath
2008-05-30 11:40:08 +00:00
*/
2010-04-04 07:14:00 +00:00
public $actionPath = null ;
2009-07-24 19:18:37 +00:00
2008-05-30 11:40:08 +00:00
/**
* A URL ( defined as a string or array ) to the controller action that handles
* logins .
*
* @ var mixed
2010-04-05 01:12:13 +00:00
* @ link http :// book . cakephp . org / view / 1269 / loginAction
2008-05-30 11:40:08 +00:00
*/
2010-04-04 07:14:00 +00:00
public $loginAction = null ;
2009-07-24 19:18:37 +00:00
2008-05-30 11:40:08 +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 .
*
* @ var mixed
2010-04-05 01:12:13 +00:00
* @ link http :// book . cakephp . org / view / 1270 / loginRedirect
2008-05-30 11:40:08 +00:00
*/
2010-04-04 07:14:00 +00:00
public $loginRedirect = null ;
2009-07-24 19:18:37 +00:00
2008-05-30 11:40:08 +00:00
/**
2010-07-19 22:17:02 +00:00
* The default action to redirect to after the user is logged out . While AuthComponent does
2008-05-30 11:40:08 +00:00
* not handle post - logout redirection , a redirect URL will be returned from AuthComponent :: logout () .
* Defaults to AuthComponent :: $loginAction .
*
* @ var mixed
* @ see AuthComponent :: $loginAction
* @ see AuthComponent :: logout ()
2010-04-05 01:12:13 +00:00
* @ link http :// book . cakephp . org / view / 1271 / logoutRedirect
2008-05-30 11:40:08 +00:00
*/
2010-04-04 07:14:00 +00:00
public $logoutRedirect = null ;
2009-07-24 19:18:37 +00:00
2008-05-30 11:40:08 +00:00
/**
* The name of model or model object , or any other object has an isAuthorized method .
*
* @ var string
*/
2010-04-04 07:14:00 +00:00
public $object = null ;
2009-07-24 19:18:37 +00:00
2008-05-30 11:40:08 +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 .
*
* @ var string
2010-04-05 01:12:13 +00:00
* @ link http :// book . cakephp . org / view / 1272 / loginError
2008-05-30 11:40:08 +00:00
*/
2010-04-04 07:14:00 +00:00
public $loginError = null ;
2009-07-24 19:18:37 +00:00
2008-05-30 11:40:08 +00:00
/**
* Error to display when user attempts to access an object or action to which they do not have
* acccess .
*
* @ var string
2010-04-05 01:12:13 +00:00
* @ link http :// book . cakephp . org / view / 1273 / authError
2008-05-30 11:40:08 +00:00
*/
2010-04-04 07:14:00 +00:00
public $authError = null ;
2009-07-24 19:18:37 +00:00
2008-05-30 11:40:08 +00:00
/**
* Determines whether AuthComponent will automatically redirect and exit if login is successful .
*
* @ var boolean
2010-04-05 01:12:13 +00:00
* @ link http :// book . cakephp . org / view / 1274 / autoRedirect
2008-05-30 11:40:08 +00:00
*/
2010-04-04 07:14:00 +00:00
public $autoRedirect = true ;
2009-07-24 19:18:37 +00:00
2008-05-30 11:40:08 +00:00
/**
* Controller actions for which user validation is not required .
*
* @ var array
* @ see AuthComponent :: allow ()
2010-04-05 01:12:13 +00:00
* @ link http :// book . cakephp . org / view / 1251 / Setting - Auth - Component - Variables
2008-05-30 11:40:08 +00:00
*/
2010-04-04 07:14:00 +00:00
public $allowedActions = array ();
2009-07-24 19:18:37 +00:00
2008-05-30 11:40:08 +00:00
/**
* Maps actions to CRUD operations . Used for controller - based validation ( $validate = 'controller' ) .
*
* @ var array
* @ see AuthComponent :: mapActions ()
*/
2010-04-04 07:14:00 +00:00
public $actionMap = array (
2008-05-30 11:40:08 +00:00
'index' => 'read' ,
'add' => 'create' ,
'edit' => 'update' ,
'view' => 'read' ,
'remove' => 'delete'
);
2009-07-24 19:18:37 +00:00
2010-05-15 04:55:15 +00:00
/**
* Request object
*
* @ var CakeRequest
*/
public $request ;
2008-05-30 11:40:08 +00:00
/**
* Form data from Controller :: $data
*
2010-05-15 04:55:15 +00:00
* @ deprecated Use $this -> request -> data instead
2008-05-30 11:40:08 +00:00
* @ var array
*/
2010-04-04 07:14:00 +00:00
public $data = array ();
2009-07-24 19:18:37 +00:00
2008-05-30 11:40:08 +00:00
/**
* Parameter data from Controller :: $params
*
2010-05-15 04:55:15 +00:00
* @ deprecated Use $this -> request instead
2008-05-30 11:40:08 +00:00
* @ var array
*/
2010-04-04 07:14:00 +00:00
public $params = array ();
2009-07-24 19:18:37 +00:00
2010-07-31 19:41:28 +00:00
/**
* AclComponent instance if using Acl + Auth
*
* @ var AclComponent
*/
public $Acl ;
2008-10-15 02:52:19 +00:00
/**
* Method list for bound controller
*
* @ var array
*/
2010-04-04 06:36:12 +00:00
protected $_methods = array ();
2009-07-24 19:18:37 +00:00
2008-05-30 11:40:08 +00:00
/**
* Initializes AuthComponent for use in the controller
*
* @ param object $controller A reference to the instantiating controller object
2008-09-25 16:49:56 +00:00
* @ return void
2008-05-30 11:40:08 +00:00
*/
2010-12-18 05:03:03 +00:00
public function initialize ( $controller ) {
2010-05-15 04:55:15 +00:00
$this -> request = $controller -> request ;
$this -> params = $this -> request ;
2008-05-30 11:40:08 +00:00
$crud = array ( 'create' , 'read' , 'update' , 'delete' );
$this -> actionMap = array_merge ( $this -> actionMap , array_combine ( $crud , $crud ));
2008-11-11 16:34:05 +00:00
$this -> _methods = $controller -> methods ;
2008-05-30 11:40:08 +00:00
2009-12-09 05:25:21 +00:00
$prefixes = Router :: prefixes ();
if ( ! empty ( $prefixes )) {
foreach ( $prefixes as $prefix ) {
$this -> actionMap = array_merge ( $this -> actionMap , array (
$prefix . '_index' => 'read' ,
$prefix . '_add' => 'create' ,
$prefix . '_edit' => 'update' ,
$prefix . '_view' => 'read' ,
$prefix . '_remove' => 'delete' ,
$prefix . '_create' => 'create' ,
$prefix . '_read' => 'read' ,
$prefix . '_update' => 'update' ,
$prefix . '_delete' => 'delete'
));
}
2008-05-30 11:40:08 +00:00
}
2010-07-07 02:46:08 +00:00
if ( Configure :: read ( 'debug' ) > 0 ) {
2008-05-30 11:40:08 +00:00
App :: import ( 'Debugger' );
2010-01-15 21:56:26 +00:00
Debugger :: checkSecurityKeys ();
2008-05-30 11:40:08 +00:00
}
}
2009-07-24 19:18:37 +00:00
2008-05-30 11:40:08 +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
2008-09-25 16:49:56 +00:00
* @ return boolean
2008-05-30 11:40:08 +00:00
*/
2010-12-18 05:03:03 +00:00
public function startup ( $controller ) {
2008-11-11 16:34:05 +00:00
$isErrorOrTests = (
strtolower ( $controller -> name ) == 'cakeerror' ||
2010-07-06 01:50:36 +00:00
( strtolower ( $controller -> name ) == 'tests' && Configure :: read ( 'debug' ) > 0 )
2008-10-15 02:52:19 +00:00
);
2008-11-11 16:34:05 +00:00
if ( $isErrorOrTests ) {
2008-10-15 02:52:19 +00:00
return true ;
2008-05-30 11:40:08 +00:00
}
2009-02-06 23:23:12 +00:00
2010-01-20 22:18:55 +00:00
$methods = array_flip ( $controller -> methods );
2010-07-10 16:00:09 +00:00
$action = $controller -> request -> params [ 'action' ];
2010-07-28 02:32:08 +00:00
2009-02-06 23:23:12 +00:00
$isMissingAction = (
$controller -> scaffold === false &&
2009-07-03 00:20:54 +00:00
! isset ( $methods [ $action ])
2009-02-06 23:23:12 +00:00
);
if ( $isMissingAction ) {
return true ;
}
2008-05-30 11:40:08 +00:00
if ( ! $this -> __setDefaults ()) {
return false ;
}
2010-11-13 04:05:44 +00:00
$request = $controller -> request ;
2010-05-15 04:55:15 +00:00
$this -> request -> data = $controller -> request -> data = $this -> hashPasswords ( $request -> data );
2008-05-30 11:40:08 +00:00
$url = '' ;
2008-10-15 02:52:19 +00:00
2010-05-15 04:55:15 +00:00
if ( isset ( $request -> query [ 'url' ])) {
$url = $request -> query [ 'url' ];
2008-07-31 19:00:12 +00:00
}
2008-05-30 11:40:08 +00:00
$url = Router :: normalize ( $url );
$loginAction = Router :: normalize ( $this -> loginAction );
2009-02-06 23:23:12 +00:00
2010-07-10 16:00:09 +00:00
$allowedActions = $this -> allowedActions ;
2008-09-20 20:18:16 +00:00
$isAllowed = (
$this -> allowedActions == array ( '*' ) ||
2009-07-03 00:20:54 +00:00
in_array ( $action , $allowedActions )
2008-09-20 20:18:16 +00:00
);
2008-05-31 12:36:38 +00:00
2008-09-20 20:18:16 +00:00
if ( $loginAction != $url && $isAllowed ) {
2008-10-15 02:52:19 +00:00
return true ;
2008-05-30 11:40:08 +00:00
}
if ( $loginAction == $url ) {
2010-05-15 04:55:15 +00:00
$model = $this -> getModel ();
if ( empty ( $request -> data ) || ! isset ( $request -> data [ $model -> alias ])) {
2010-01-12 04:54:06 +00:00
if ( ! $this -> Session -> check ( 'Auth.redirect' ) && ! $this -> loginRedirect && env ( 'HTTP_REFERER' )) {
2008-11-14 09:07:22 +00:00
$this -> Session -> write ( 'Auth.redirect' , $controller -> referer ( null , true ));
2008-05-30 11:40:08 +00:00
}
return false ;
}
2010-05-15 04:55:15 +00:00
$isValid = ! empty ( $request -> data [ $model -> alias ][ $this -> fields [ 'username' ]]) &&
! empty ( $request -> data [ $model -> alias ][ $this -> fields [ 'password' ]]);
2008-05-30 11:40:08 +00:00
2009-01-14 05:21:26 +00:00
if ( $isValid ) {
2010-05-15 04:55:15 +00:00
$username = $request -> data [ $model -> alias ][ $this -> fields [ 'username' ]];
$password = $request -> data [ $model -> alias ][ $this -> fields [ 'password' ]];
2009-01-14 05:21:26 +00:00
$data = array (
2009-08-13 14:39:59 +00:00
$model -> alias . '.' . $this -> fields [ 'username' ] => $username ,
$model -> alias . '.' . $this -> fields [ 'password' ] => $password
2009-01-14 05:21:26 +00:00
);
if ( $this -> login ( $data )) {
if ( $this -> autoRedirect ) {
$controller -> redirect ( $this -> redirect (), null , true );
}
return true ;
2008-05-30 11:40:08 +00:00
}
}
2009-01-14 05:21:26 +00:00
2009-10-14 21:27:34 +00:00
$this -> Session -> setFlash ( $this -> loginError , $this -> flashElement , array (), 'auth' );
2010-05-15 04:55:15 +00:00
$request -> data [ $model -> alias ][ $this -> fields [ 'password' ]] = null ;
2008-05-30 11:40:08 +00:00
return false ;
} else {
if ( ! $this -> user ()) {
2010-09-15 02:12:14 +00:00
if ( ! $request -> is ( 'ajax' )) {
2009-10-14 21:27:34 +00:00
$this -> Session -> setFlash ( $this -> authError , $this -> flashElement , array (), 'auth' );
2010-05-15 04:55:15 +00:00
if ( ! empty ( $request -> query ) && count ( $request -> query ) >= 2 ) {
$query = $request -> query ;
2009-06-01 00:01:58 +00:00
unset ( $query [ 'url' ], $query [ 'ext' ]);
2009-04-25 02:16:05 +00:00
$url .= Router :: queryString ( $query , array ());
}
2008-05-30 11:40:08 +00:00
$this -> Session -> write ( 'Auth.redirect' , $url );
2008-09-12 02:10:55 +00:00
$controller -> redirect ( $loginAction );
2008-05-30 11:40:08 +00:00
return false ;
} elseif ( ! empty ( $this -> ajaxLogin )) {
$controller -> viewPath = 'elements' ;
2008-09-20 20:18:16 +00:00
echo $controller -> render ( $this -> ajaxLogin , $this -> RequestHandler -> ajaxLayout );
2008-06-04 19:04:58 +00:00
$this -> _stop ();
2008-05-30 11:40:08 +00:00
return false ;
2008-09-12 02:10:55 +00:00
} else {
$controller -> redirect ( null , 403 );
2008-05-30 11:40:08 +00:00
}
}
}
2008-05-31 12:36:38 +00:00
if ( ! $this -> authorize ) {
return true ;
}
2008-05-30 11:40:08 +00:00
2008-05-31 12:36:38 +00:00
extract ( $this -> __authType ());
switch ( $type ) {
case 'controller' :
2010-05-15 04:55:15 +00:00
$this -> object = $controller ;
2008-05-31 12:36:38 +00:00
break ;
case 'crud' :
case 'actions' :
if ( isset ( $controller -> Acl )) {
2010-05-15 04:55:15 +00:00
$this -> Acl = $controller -> Acl ;
2008-05-31 12:36:38 +00:00
} else {
2010-04-15 15:52:49 +00:00
trigger_error ( __ ( 'Could not find AclComponent. Please include Acl in Controller::$components.' ), E_USER_WARNING );
2008-05-31 12:36:38 +00:00
}
break ;
case 'model' :
if ( ! isset ( $object )) {
2008-10-15 02:52:19 +00:00
$hasModel = (
isset ( $controller -> { $controller -> modelClass }) &&
is_object ( $controller -> { $controller -> modelClass })
);
$isUses = (
! empty ( $controller -> uses ) && isset ( $controller -> { $controller -> uses [ 0 ]}) &&
is_object ( $controller -> { $controller -> uses [ 0 ]})
);
if ( $hasModel ) {
2008-05-31 12:36:38 +00:00
$object = $controller -> modelClass ;
2008-10-15 02:52:19 +00:00
} elseif ( $isUses ) {
2008-05-31 12:36:38 +00:00
$object = $controller -> uses [ 0 ];
}
}
$type = array ( 'model' => $object );
break ;
}
2008-05-30 11:40:08 +00:00
2008-05-31 12:36:38 +00:00
if ( $this -> isAuthorized ( $type )) {
2008-05-30 11:40:08 +00:00
return true ;
}
2008-05-31 12:36:38 +00:00
2009-10-14 21:27:34 +00:00
$this -> Session -> setFlash ( $this -> authError , $this -> flashElement , array (), 'auth' );
2008-05-31 12:36:38 +00:00
$controller -> redirect ( $controller -> referer (), null , true );
return false ;
2008-05-30 11:40:08 +00:00
}
2009-07-24 19:18:37 +00:00
2008-05-30 11:40:08 +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
2008-09-25 16:49:56 +00:00
* @ return boolean
2008-05-30 11:40:08 +00:00
* @ access private
*/
function __setDefaults () {
if ( empty ( $this -> userModel )) {
2010-04-15 15:52:49 +00:00
trigger_error ( __ ( " Could not find \$ userModel. Please set AuthComponent:: \$ userModel in beforeFilter(). " ), E_USER_WARNING );
2008-05-30 11:40:08 +00:00
return false ;
}
2010-03-19 00:49:41 +00:00
list ( $plugin , $model ) = pluginSplit ( $this -> userModel );
2008-05-31 12:36:38 +00:00
$defaults = array (
2009-10-20 18:16:31 +00:00
'loginAction' => array (
2010-03-19 00:49:41 +00:00
'controller' => Inflector :: underscore ( Inflector :: pluralize ( $model )),
'action' => 'login' ,
2010-06-08 00:08:04 +00:00
'plugin' => Inflector :: underscore ( $plugin ),
2009-10-20 18:16:31 +00:00
),
2010-03-19 00:49:41 +00:00
'sessionKey' => 'Auth.' . $model ,
2008-05-31 12:36:38 +00:00
'logoutRedirect' => $this -> loginAction ,
2010-04-15 15:52:49 +00:00
'loginError' => __ ( 'Login failed. Invalid username or password.' ),
'authError' => __ ( 'You are not authorized to access that location.' )
2008-05-31 12:36:38 +00:00
);
foreach ( $defaults as $key => $value ) {
if ( empty ( $this -> { $key })) {
$this -> { $key } = $value ;
}
2008-05-30 11:40:08 +00:00
}
return true ;
}
2009-07-24 19:18:37 +00:00
2008-05-30 11:40:08 +00:00
/**
2008-10-15 02:52:19 +00:00
* Determines whether the given user is authorized to perform an action . The type of
* authorization used is based on the value of AuthComponent :: $authorize or the
* passed $type param .
2008-05-30 11:40:08 +00:00
*
* Types :
2008-10-15 02:52:19 +00:00
* 'controller' will validate against Controller :: isAuthorized () if controller instance is
* passed in $object
2008-05-30 11:40:08 +00:00
* 'actions' will validate Controller :: action against an AclComponent :: check ()
* 'crud' will validate mapActions against an AclComponent :: check ()
2008-10-15 02:52:19 +00:00
* array ( 'model' => 'name' ); will validate mapActions against model
2008-12-18 14:31:53 +00:00
* $name :: isAuthorized ( user , controller , mapAction )
2008-10-15 02:52:19 +00:00
* 'object' will validate Controller :: action against
* object :: isAuthorized ( user , controller , action )
2008-05-30 11:40:08 +00:00
*
* @ param string $type Type of authorization
* @ param mixed $object object , model object , or model name
* @ param mixed $user The user to check the authorization of
* @ return boolean True if $user is authorized , otherwise false
*/
2010-04-05 03:19:38 +00:00
public function isAuthorized ( $type = null , $object = null , $user = null ) {
2008-05-30 11:40:08 +00:00
if ( empty ( $user ) && ! $this -> user ()) {
return false ;
} elseif ( empty ( $user )) {
$user = $this -> user ();
}
extract ( $this -> __authType ( $type ));
if ( ! $object ) {
$object = $this -> object ;
}
$valid = false ;
switch ( $type ) {
case 'controller' :
$valid = $object -> isAuthorized ();
break ;
case 'actions' :
$valid = $this -> Acl -> check ( $user , $this -> action ());
break ;
case 'crud' :
2010-05-15 04:55:15 +00:00
if ( ! isset ( $this -> actionMap [ $this -> request [ 'action' ]])) {
2008-10-15 02:52:19 +00:00
trigger_error (
2010-12-05 01:37:13 +00:00
__ ( 'Auth::startup() - Attempted access of un-mapped action "%1$s" in controller "%2$s"' , $this -> request [ 'action' ], $this -> request [ 'controller' ]),
2008-10-15 02:52:19 +00:00
E_USER_WARNING
);
2008-05-30 11:40:08 +00:00
} else {
2008-10-15 02:52:19 +00:00
$valid = $this -> Acl -> check (
$user ,
$this -> action ( ':controller' ),
2010-05-15 04:55:15 +00:00
$this -> actionMap [ $this -> request [ 'action' ]]
2008-10-15 02:52:19 +00:00
);
2008-05-30 11:40:08 +00:00
}
break ;
case 'model' :
2010-05-15 04:55:15 +00:00
$action = $this -> request [ 'action' ];
2008-10-23 00:10:44 +00:00
if ( isset ( $this -> actionMap [ $action ])) {
2008-05-30 11:40:08 +00:00
$action = $this -> actionMap [ $action ];
}
if ( is_string ( $object )) {
$object = $this -> getModel ( $object );
}
case 'object' :
if ( ! isset ( $action )) {
$action = $this -> action ( ':action' );
}
if ( empty ( $object )) {
2010-12-05 01:37:13 +00:00
trigger_error ( __ ( 'Could not find %s. Set AuthComponent::$object in beforeFilter() or pass a valid object' , get_class ( $object )), E_USER_WARNING );
2008-05-30 11:40:08 +00:00
return ;
}
if ( method_exists ( $object , 'isAuthorized' )) {
$valid = $object -> isAuthorized ( $user , $this -> action ( ':controller' ), $action );
2008-10-23 00:10:44 +00:00
} elseif ( $object ) {
2010-12-05 01:37:13 +00:00
trigger_error ( __ ( '%s::isAuthorized() is not defined.' , get_class ( $object )), E_USER_WARNING );
2008-05-30 11:40:08 +00:00
}
break ;
case null :
case false :
return true ;
break ;
default :
2010-04-15 15:52:49 +00:00
trigger_error ( __ ( 'Auth::isAuthorized() - $authorize is set to an incorrect value. Allowed settings are: "actions", "crud", "model" or null.' ), E_USER_WARNING );
2008-05-30 11:40:08 +00:00
break ;
}
return $valid ;
}
2009-07-24 19:18:37 +00:00
2008-05-30 11:40:08 +00:00
/**
* Get authorization type
*
* @ param string $auth Type of authorization
* @ return array Associative array with : type , object
* @ access private
*/
function __authType ( $auth = null ) {
if ( $auth == null ) {
$auth = $this -> authorize ;
}
$object = null ;
if ( is_array ( $auth )) {
$type = key ( $auth );
$object = $auth [ $type ];
} else {
$type = $auth ;
return compact ( 'type' );
}
return compact ( 'type' , 'object' );
}
2009-07-24 19:18:37 +00:00
2008-05-30 11:40:08 +00:00
/**
* Takes a list of actions in the current controller for which authentication is not required , or
* no parameters to allow all actions .
*
2009-08-13 16:08:30 +00:00
* @ param mixed $action Controller action name or array of actions
2008-05-30 11:40:08 +00:00
* @ param string $action Controller action name
* @ param string ... etc .
2008-09-25 16:49:56 +00:00
* @ return void
2010-04-05 01:12:13 +00:00
* @ link http :// book . cakephp . org / view / 1257 / allow
2008-05-30 11:40:08 +00:00
*/
2010-04-05 03:19:38 +00:00
public function allow () {
2008-05-30 11:40:08 +00:00
$args = func_get_args ();
2008-10-15 02:52:19 +00:00
if ( empty ( $args ) || $args == array ( '*' )) {
$this -> allowedActions = $this -> _methods ;
2008-05-30 11:40:08 +00:00
} else {
if ( isset ( $args [ 0 ]) && is_array ( $args [ 0 ])) {
$args = $args [ 0 ];
}
2010-07-10 16:00:09 +00:00
$this -> allowedActions = array_merge ( $this -> allowedActions , $args );
2008-05-30 11:40:08 +00:00
}
}
2009-07-24 19:18:37 +00:00
2008-05-30 11:40:08 +00:00
/**
* Removes items from the list of allowed actions .
*
2009-08-13 16:08:30 +00:00
* @ param mixed $action Controller action name or array of actions
2008-05-30 11:40:08 +00:00
* @ param string $action Controller action name
* @ param string ... etc .
2008-09-25 16:49:56 +00:00
* @ return void
2008-05-30 11:40:08 +00:00
* @ see AuthComponent :: allow ()
2010-04-05 01:12:13 +00:00
* @ link http :// book . cakephp . org / view / 1258 / deny
2008-05-30 11:40:08 +00:00
*/
2010-04-05 03:19:38 +00:00
public function deny () {
2008-05-30 11:40:08 +00:00
$args = func_get_args ();
2009-08-13 16:08:30 +00:00
if ( isset ( $args [ 0 ]) && is_array ( $args [ 0 ])) {
$args = $args [ 0 ];
}
2008-05-30 11:40:08 +00:00
foreach ( $args as $arg ) {
2010-07-10 16:00:09 +00:00
$i = array_search ( $arg , $this -> allowedActions );
2008-05-30 11:40:08 +00:00
if ( is_int ( $i )) {
unset ( $this -> allowedActions [ $i ]);
}
}
$this -> allowedActions = array_values ( $this -> allowedActions );
}
2009-07-24 19:18:37 +00:00
2008-05-30 11:40:08 +00:00
/**
* Maps action names to CRUD operations . Used for controller - based authentication .
*
* @ param array $map Actions to map
2008-09-25 16:49:56 +00:00
* @ return void
2010-04-05 01:12:13 +00:00
* @ link http :// book . cakephp . org / view / 1260 / mapActions
2008-05-30 11:40:08 +00:00
*/
2010-04-05 03:19:38 +00:00
public function mapActions ( $map = array ()) {
2008-05-30 11:40:08 +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 ;
}
}
}
2009-07-24 19:18:37 +00:00
2008-05-30 11:40:08 +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 .
*
* @ param mixed $data User object
* @ return boolean True on login success , false on failure
2010-04-05 01:12:13 +00:00
* @ link http :// book . cakephp . org / view / 1261 / login
2008-05-30 11:40:08 +00:00
*/
2010-04-05 03:19:38 +00:00
public function login ( $data = null ) {
2008-05-30 11:40:08 +00:00
$this -> __setDefaults ();
$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 ;
}
2009-07-24 19:18:37 +00:00
2008-05-30 11:40:08 +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
* @ see AuthComponent :: $loginAction
2010-04-05 01:12:13 +00:00
* @ link http :// book . cakephp . org / view / 1262 / logout
2008-05-30 11:40:08 +00:00
*/
2010-04-05 03:19:38 +00:00
public function logout () {
2008-05-30 11:40:08 +00:00
$this -> __setDefaults ();
2009-09-11 10:58:23 +00:00
$this -> Session -> delete ( $this -> sessionKey );
$this -> Session -> delete ( 'Auth.redirect' );
2008-05-30 11:40:08 +00:00
$this -> _loggedIn = false ;
return Router :: normalize ( $this -> logoutRedirect );
}
2009-07-24 19:18:37 +00:00
2008-05-30 11:40:08 +00:00
/**
* Get the current user from the session .
*
2008-09-25 16:49:56 +00:00
* @ param string $key field to retrive . Leave null to get entire User record
* @ return mixed User record . or null if no user is logged in .
2010-04-05 01:12:13 +00:00
* @ link http :// book . cakephp . org / view / 1264 / user
2008-05-30 11:40:08 +00:00
*/
2010-04-05 03:19:38 +00:00
public function user ( $key = null ) {
2008-05-30 11:40:08 +00:00
$this -> __setDefaults ();
if ( ! $this -> Session -> check ( $this -> sessionKey )) {
return null ;
}
if ( $key == null ) {
2010-05-15 04:55:15 +00:00
$model = $this -> getModel ();
2009-08-13 14:39:59 +00:00
return array ( $model -> alias => $this -> Session -> read ( $this -> sessionKey ));
2008-05-30 11:40:08 +00:00
} else {
$user = $this -> Session -> read ( $this -> sessionKey );
if ( isset ( $user [ $key ])) {
return $user [ $key ];
}
2008-09-08 20:33:48 +00:00
return null ;
2008-05-30 11:40:08 +00:00
}
}
2009-07-24 19:18:37 +00:00
2008-05-30 11:40:08 +00:00
/**
* If no parameter is passed , gets the authentication redirect URL .
*
* @ param mixed $url Optional URL to write as the login redirect URL .
* @ return string Redirect URL
*/
2010-04-05 03:19:38 +00:00
public function redirect ( $url = null ) {
2008-05-30 11:40:08 +00:00
if ( ! is_null ( $url )) {
2008-12-24 05:40:05 +00:00
$redir = $url ;
$this -> Session -> write ( 'Auth.redirect' , $redir );
2008-12-17 07:30:55 +00:00
} elseif ( $this -> Session -> check ( 'Auth.redirect' )) {
2008-05-30 11:40:08 +00:00
$redir = $this -> Session -> read ( 'Auth.redirect' );
$this -> Session -> delete ( 'Auth.redirect' );
if ( Router :: normalize ( $redir ) == Router :: normalize ( $this -> loginAction )) {
$redir = $this -> loginRedirect ;
}
} else {
$redir = $this -> loginRedirect ;
}
return Router :: normalize ( $redir );
}
2009-07-24 19:18:37 +00:00
2008-05-30 11:40:08 +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 () .
* @ param string $action Optional . The action to validate against .
* @ see AuthComponent :: identify ()
* @ return boolean True if the user validates , false otherwise .
*/
2010-04-05 03:19:38 +00:00
public function validate ( $object , $user = null , $action = null ) {
2008-05-30 11:40:08 +00:00
if ( empty ( $user )) {
$user = $this -> user ();
}
if ( empty ( $user )) {
return false ;
}
return $this -> Acl -> check ( $user , $object , $action );
}
2009-07-24 19:18:37 +00:00
2008-05-30 11:40:08 +00:00
/**
* Returns the path to the ACO node bound to a controller / action .
*
* @ param string $action Optional . The controller / action path to validate the
* user against . The current request action is used if
* none is specified .
* @ return boolean ACO node path
2010-04-05 01:12:13 +00:00
* @ link http :// book . cakephp . org / view / 1256 / action
2008-05-30 11:40:08 +00:00
*/
2010-04-05 03:19:38 +00:00
public function action ( $action = ':plugin/:controller/:action' ) {
2010-05-15 04:55:15 +00:00
$plugin = empty ( $this -> request [ 'plugin' ]) ? null : Inflector :: camelize ( $this -> request [ 'plugin' ]) . '/' ;
2008-05-30 11:40:08 +00:00
return str_replace (
2009-09-14 04:29:33 +00:00
array ( ':controller' , ':action' , ':plugin/' ),
2010-05-15 04:55:15 +00:00
array ( Inflector :: camelize ( $this -> request [ 'controller' ]), $this -> request [ 'action' ], $plugin ),
2008-05-30 11:40:08 +00:00
$this -> actionPath . $action
);
}
2009-07-24 19:18:37 +00:00
2008-05-30 11:40:08 +00:00
/**
* Returns a reference to the model object specified , and attempts
* to load it if it is not found .
*
* @ param string $name Model name ( defaults to AuthComponent :: $userModel )
* @ return object A reference to a model object
*/
2010-04-05 03:19:38 +00:00
public function & getModel ( $name = null ) {
2008-05-30 11:40:08 +00:00
$model = null ;
if ( ! $name ) {
$name = $this -> userModel ;
}
2010-07-06 02:19:22 +00:00
$model = ClassRegistry :: init ( $name );
2008-05-30 11:40:08 +00:00
if ( empty ( $model )) {
2010-04-15 15:52:49 +00:00
trigger_error ( __ ( 'Auth::getModel() - Model is not set or could not be found' ), E_USER_WARNING );
2008-05-30 11:40:08 +00:00
return null ;
}
return $model ;
}
2009-07-24 19:18:37 +00:00
2008-05-30 11:40:08 +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 .
* @ param array $conditions Optional . Additional conditions to a find .
* @ return array User record data , or null , if the user could not be identified .
*/
2010-04-05 03:19:38 +00:00
public function identify ( $user = null , $conditions = null ) {
2008-05-30 11:40:08 +00:00
if ( $conditions === false ) {
$conditions = null ;
} elseif ( is_array ( $conditions )) {
$conditions = array_merge (( array ) $this -> userScope , $conditions );
} else {
$conditions = $this -> userScope ;
}
2010-05-15 04:55:15 +00:00
$model = $this -> getModel ();
2008-05-30 11:40:08 +00:00
if ( empty ( $user )) {
$user = $this -> user ();
if ( empty ( $user )) {
return null ;
}
} elseif ( is_object ( $user ) && is_a ( $user , 'Model' )) {
if ( ! $user -> exists ()) {
return null ;
}
$user = $user -> read ();
2009-08-13 14:39:59 +00:00
$user = $user [ $model -> alias ];
} elseif ( is_array ( $user ) && isset ( $user [ $model -> alias ])) {
$user = $user [ $model -> alias ];
2008-05-30 11:40:08 +00:00
}
2009-08-13 14:39:59 +00:00
if ( is_array ( $user ) && ( isset ( $user [ $this -> fields [ 'username' ]]) || isset ( $user [ $model -> alias . '.' . $this -> fields [ 'username' ]]))) {
2008-05-30 11:40:08 +00:00
if ( isset ( $user [ $this -> fields [ 'username' ]]) && ! empty ( $user [ $this -> fields [ 'username' ]]) && ! empty ( $user [ $this -> fields [ 'password' ]])) {
if ( trim ( $user [ $this -> fields [ 'username' ]]) == '=' || trim ( $user [ $this -> fields [ 'password' ]]) == '=' ) {
return false ;
}
$find = array (
2009-08-13 14:39:59 +00:00
$model -> alias . '.' . $this -> fields [ 'username' ] => $user [ $this -> fields [ 'username' ]],
$model -> alias . '.' . $this -> fields [ 'password' ] => $user [ $this -> fields [ 'password' ]]
2008-05-30 11:40:08 +00:00
);
2009-08-13 14:39:59 +00:00
} elseif ( isset ( $user [ $model -> alias . '.' . $this -> fields [ 'username' ]]) && ! empty ( $user [ $model -> alias . '.' . $this -> fields [ 'username' ]])) {
if ( trim ( $user [ $model -> alias . '.' . $this -> fields [ 'username' ]]) == '=' || trim ( $user [ $model -> alias . '.' . $this -> fields [ 'password' ]]) == '=' ) {
2008-05-30 11:40:08 +00:00
return false ;
}
$find = array (
2009-08-13 14:39:59 +00:00
$model -> alias . '.' . $this -> fields [ 'username' ] => $user [ $model -> alias . '.' . $this -> fields [ 'username' ]],
$model -> alias . '.' . $this -> fields [ 'password' ] => $user [ $model -> alias . '.' . $this -> fields [ 'password' ]]
2008-05-30 11:40:08 +00:00
);
} else {
return false ;
}
2009-10-02 19:36:07 +00:00
$data = $model -> find ( 'first' , array (
'conditions' => array_merge ( $find , $conditions ),
'recursive' => 0
));
2009-08-13 14:39:59 +00:00
if ( empty ( $data ) || empty ( $data [ $model -> alias ])) {
2008-05-30 11:40:08 +00:00
return null ;
}
2009-01-14 05:21:26 +00:00
} elseif ( ! empty ( $user ) && is_string ( $user )) {
2009-10-02 19:36:07 +00:00
$data = $model -> find ( 'first' , array (
'conditions' => array_merge ( array ( $model -> escapeField () => $user ), $conditions ),
));
2009-08-13 14:39:59 +00:00
if ( empty ( $data ) || empty ( $data [ $model -> alias ])) {
2008-05-30 11:40:08 +00:00
return null ;
}
}
2008-07-31 19:00:12 +00:00
if ( ! empty ( $data )) {
2009-08-13 14:39:59 +00:00
if ( ! empty ( $data [ $model -> alias ][ $this -> fields [ 'password' ]])) {
unset ( $data [ $model -> alias ][ $this -> fields [ 'password' ]]);
2008-05-30 11:40:08 +00:00
}
2009-08-13 14:39:59 +00:00
return $data [ $model -> alias ];
2008-05-30 11:40:08 +00:00
}
2008-09-08 20:33:48 +00:00
return null ;
2008-05-30 11:40:08 +00:00
}
2009-07-24 19:18:37 +00:00
2008-05-30 11:40:08 +00:00
/**
* Hash any passwords found in $data using $userModel and $fields [ 'password' ]
*
* @ param array $data Set of data to look for passwords
* @ return array Data with passwords hashed
2010-04-05 01:12:13 +00:00
* @ link http :// book . cakephp . org / view / 1259 / hashPasswords
2008-05-30 11:40:08 +00:00
*/
2010-04-05 03:19:38 +00:00
public function hashPasswords ( $data ) {
2008-05-30 11:40:08 +00:00
if ( is_object ( $this -> authenticate ) && method_exists ( $this -> authenticate , 'hashPasswords' )) {
return $this -> authenticate -> hashPasswords ( $data );
}
2010-04-09 17:53:16 +00:00
if ( is_array ( $data )) {
2010-05-15 04:55:15 +00:00
$model = $this -> getModel ();
2010-04-09 17:53:16 +00:00
if ( isset ( $data [ $model -> alias ])) {
if ( isset ( $data [ $model -> alias ][ $this -> fields [ 'username' ]]) && isset ( $data [ $model -> alias ][ $this -> fields [ 'password' ]])) {
$data [ $model -> alias ][ $this -> fields [ 'password' ]] = $this -> password ( $data [ $model -> alias ][ $this -> fields [ 'password' ]]);
}
2008-05-30 11:40:08 +00:00
}
}
return $data ;
}
2009-07-24 19:18:37 +00:00
2008-05-30 11:40:08 +00:00
/**
* Hash a password with the application 's salt value (as defined with Configure::write(' Security . salt ' );
*
* @ param string $password Password to hash
* @ return string Hashed password
2010-04-05 01:12:13 +00:00
* @ link http :// book . cakephp . org / view / 1263 / password
2008-05-30 11:40:08 +00:00
*/
2010-04-05 03:19:38 +00:00
public function password ( $password ) {
2008-05-30 11:40:08 +00:00
return Security :: hash ( $password , null , true );
}
2009-07-24 19:18:37 +00:00
2008-05-30 11:40:08 +00:00
/**
* Component shutdown . If user is logged in , wipe out redirect .
*
* @ param object $controller Instantiating controller
*/
2010-12-18 05:03:03 +00:00
public function shutdown ( $controller ) {
2008-05-30 11:40:08 +00:00
if ( $this -> _loggedIn ) {
2009-09-11 10:58:23 +00:00
$this -> Session -> delete ( 'Auth.redirect' );
2008-05-30 11:40:08 +00:00
}
}
2010-06-10 04:33:49 +00:00
/**
* Sets or gets whether the user is logged in
*
* @ param boolean $logged sets the status of the user , true to logged in , false to logged out
* @ return boolean true if the user is logged in , false otherwise
* @ access public
*/
public function loggedIn ( $logged = null ) {
if ( ! is_null ( $logged )) {
$this -> _loggedIn = $logged ;
}
return $this -> _loggedIn ;
}
2008-05-30 11:40:08 +00:00
}