source: Dev/branches/cakephp/cake/libs/controller/components/auth.php @ 126

Last change on this file since 126 was 126, checked in by fpvanagthoven, 14 years ago

Cakephp branch.

File size: 27.3 KB
Line 
1<?php
2/**
3 * Authentication component
4 *
5 * Manages user logins and permissions.
6 *
7 * PHP versions 4 and 5
8 *
9 * CakePHP(tm) : Rapid Development Framework (http://cakephp.org)
10 * Copyright 2005-2011, Cake Software Foundation, Inc. (http://cakefoundation.org)
11 *
12 * Licensed under The MIT License
13 * Redistributions of files must retain the above copyright notice.
14 *
15 * @copyright     Copyright 2005-2011, Cake Software Foundation, Inc. (http://cakefoundation.org)
16 * @link          http://cakephp.org CakePHP(tm) Project
17 * @package       cake
18 * @subpackage    cake.cake.libs.controller.components
19 * @since         CakePHP(tm) v 0.10.0.1076
20 * @license       MIT License (http://www.opensource.org/licenses/mit-license.php)
21 */
22
23App::import('Core', array('Router', 'Security'), false);
24
25/**
26 * Authentication control component class
27 *
28 * Binds access control with user authentication and session management.
29 *
30 * @package       cake
31 * @subpackage    cake.cake.libs.controller.components
32 * @link http://book.cakephp.org/view/1250/Authentication
33 */
34class AuthComponent extends Object {
35
36/**
37 * Maintains current user login state.
38 *
39 * @var boolean
40 * @access private
41 */
42        var $_loggedIn = false;
43
44/**
45 * Other components utilized by AuthComponent
46 *
47 * @var array
48 * @access public
49 */
50        var $components = array('Session', 'RequestHandler');
51
52/**
53 * A reference to the object used for authentication
54 *
55 * @var object
56 * @access public
57 * @link http://book.cakephp.org/view/1278/authenticate
58 */
59        var $authenticate = null;
60
61/**
62 * The name of the component to use for Authorization or set this to
63 * 'controller' will validate against Controller::isAuthorized()
64 * 'actions' will validate Controller::action against an AclComponent::check()
65 * 'crud' will validate mapActions against an AclComponent::check()
66 * array('model'=> 'name'); will validate mapActions against model $name::isAuthorized(user, controller, mapAction)
67 * 'object' will validate Controller::action against object::isAuthorized(user, controller, action)
68 *
69 * @var mixed
70 * @access public
71 * @link http://book.cakephp.org/view/1275/authorize
72 */
73        var $authorize = false;
74
75/**
76 * The name of an optional view element to render when an Ajax request is made
77 * with an invalid or expired session
78 *
79 * @var string
80 * @access public
81 * @link http://book.cakephp.org/view/1277/ajaxLogin
82 */
83        var $ajaxLogin = null;
84
85/**
86 * The name of the element used for SessionComponent::setFlash
87 *
88 * @var string
89 * @access public
90 */
91        var $flashElement = 'default';
92
93/**
94 * The name of the model that represents users which will be authenticated.  Defaults to 'User'.
95 *
96 * @var string
97 * @access public
98 * @link http://book.cakephp.org/view/1266/userModel
99 */
100        var $userModel = 'User';
101
102/**
103 * Additional query conditions to use when looking up and authenticating users,
104 * i.e. array('User.is_active' => 1).
105 *
106 * @var array
107 * @access public
108 * @link http://book.cakephp.org/view/1268/userScope
109 */
110        var $userScope = array();
111
112/**
113 * Allows you to specify non-default login name and password fields used in
114 * $userModel, i.e. array('username' => 'login_name', 'password' => 'passwd').
115 *
116 * @var array
117 * @access public
118 * @link http://book.cakephp.org/view/1267/fields
119 */
120        var $fields = array('username' => 'username', 'password' => 'password');
121
122/**
123 * The session key name where the record of the current user is stored.  If
124 * unspecified, it will be "Auth.{$userModel name}".
125 *
126 * @var string
127 * @access public
128 * @link http://book.cakephp.org/view/1276/sessionKey
129 */
130        var $sessionKey = null;
131
132/**
133 * If using action-based access control, this defines how the paths to action
134 * ACO nodes is computed.  If, for example, all controller nodes are nested
135 * under an ACO node named 'Controllers', $actionPath should be set to
136 * "Controllers/".
137 *
138 * @var string
139 * @access public
140 * @link http://book.cakephp.org/view/1279/actionPath
141 */
142        var $actionPath = null;
143
144/**
145 * A URL (defined as a string or array) to the controller action that handles
146 * logins.
147 *
148 * @var mixed
149 * @access public
150 * @link http://book.cakephp.org/view/1269/loginAction
151 */
152        var $loginAction = null;
153
154/**
155 * Normally, if a user is redirected to the $loginAction page, the location they
156 * were redirected from will be stored in the session so that they can be
157 * redirected back after a successful login.  If this session value is not
158 * set, the user will be redirected to the page specified in $loginRedirect.
159 *
160 * @var mixed
161 * @access public
162 * @link http://book.cakephp.org/view/1270/loginRedirect
163 */
164        var $loginRedirect = null;
165
166/**
167 * The default action to redirect to after the user is logged out.  While AuthComponent does
168 * not handle post-logout redirection, a redirect URL will be returned from AuthComponent::logout().
169 * Defaults to AuthComponent::$loginAction.
170 *
171 * @var mixed
172 * @access public
173 * @see AuthComponent::$loginAction
174 * @see AuthComponent::logout()
175 * @link http://book.cakephp.org/view/1271/logoutRedirect
176 */
177        var $logoutRedirect = null;
178
179/**
180 * The name of model or model object, or any other object has an isAuthorized method.
181 *
182 * @var string
183 * @access public
184 */
185        var $object = null;
186
187/**
188 * Error to display when user login fails.  For security purposes, only one error is used for all
189 * login failures, so as not to expose information on why the login failed.
190 *
191 * @var string
192 * @access public
193 * @link http://book.cakephp.org/view/1272/loginError
194 */
195        var $loginError = null;
196
197/**
198 * Error to display when user attempts to access an object or action to which they do not have
199 * acccess.
200 *
201 * @var string
202 * @access public
203 * @link http://book.cakephp.org/view/1273/authError
204 */
205        var $authError = null;
206
207/**
208 * Determines whether AuthComponent will automatically redirect and exit if login is successful.
209 *
210 * @var boolean
211 * @access public
212 * @link http://book.cakephp.org/view/1274/autoRedirect
213 */
214        var $autoRedirect = true;
215
216/**
217 * Controller actions for which user validation is not required.
218 *
219 * @var array
220 * @access public
221 * @see AuthComponent::allow()
222 * @link http://book.cakephp.org/view/1251/Setting-Auth-Component-Variables
223 */
224        var $allowedActions = array();
225
226/**
227 * Maps actions to CRUD operations.  Used for controller-based validation ($validate = 'controller').
228 *
229 * @var array
230 * @access public
231 * @see AuthComponent::mapActions()
232 */
233        var $actionMap = array(
234                'index'         => 'read',
235                'add'           => 'create',
236                'edit'          => 'update',
237                'view'          => 'read',
238                'remove'        => 'delete'
239        );
240
241/**
242 * Form data from Controller::$data
243 *
244 * @var array
245 * @access public
246 */
247        var $data = array();
248
249/**
250 * Parameter data from Controller::$params
251 *
252 * @var array
253 * @access public
254 */
255        var $params = array();
256
257/**
258 * Method list for bound controller
259 *
260 * @var array
261 * @access protected
262 */
263        var $_methods = array();
264
265/**
266 * Initializes AuthComponent for use in the controller
267 *
268 * @param object $controller A reference to the instantiating controller object
269 * @return void
270 * @access public
271 */
272        function initialize(&$controller, $settings = array()) {
273                $this->params = $controller->params;
274                $crud = array('create', 'read', 'update', 'delete');
275                $this->actionMap = array_merge($this->actionMap, array_combine($crud, $crud));
276                $this->_methods = $controller->methods;
277
278                $prefixes = Router::prefixes();
279                if (!empty($prefixes)) {
280                        foreach ($prefixes as $prefix) {
281                                $this->actionMap = array_merge($this->actionMap, array(
282                                        $prefix . '_index' => 'read',
283                                        $prefix . '_add' => 'create',
284                                        $prefix . '_edit' => 'update',
285                                        $prefix . '_view' => 'read',
286                                        $prefix . '_remove' => 'delete',
287                                        $prefix . '_create' => 'create',
288                                        $prefix . '_read' => 'read',
289                                        $prefix . '_update' => 'update',
290                                        $prefix . '_delete' => 'delete'
291                                ));
292                        }
293                }
294                $this->_set($settings);
295                if (Configure::read() > 0) {
296                        App::import('Debugger');
297                        Debugger::checkSecurityKeys();
298                }
299        }
300
301/**
302 * Main execution method.  Handles redirecting of invalid users, and processing
303 * of login form data.
304 *
305 * @param object $controller A reference to the instantiating controller object
306 * @return boolean
307 * @access public
308 */
309        function startup(&$controller) {
310                $isErrorOrTests = (
311                        strtolower($controller->name) == 'cakeerror' ||
312                        (strtolower($controller->name) == 'tests' && Configure::read() > 0)
313                );
314                if ($isErrorOrTests) {
315                        return true;
316                }
317
318                $methods = array_flip($controller->methods);
319                $action = strtolower($controller->params['action']);
320                $isMissingAction = (
321                        $controller->scaffold === false &&
322                        !isset($methods[$action])
323                );
324
325                if ($isMissingAction) {
326                        return true;
327                }
328
329                if (!$this->__setDefaults()) {
330                        return false;
331                }
332
333                $this->data = $controller->data = $this->hashPasswords($controller->data);
334                $url = '';
335
336                if (isset($controller->params['url']['url'])) {
337                        $url = $controller->params['url']['url'];
338                }
339                $url = Router::normalize($url);
340                $loginAction = Router::normalize($this->loginAction);
341
342                $allowedActions = array_map('strtolower', $this->allowedActions);
343                $isAllowed = (
344                        $this->allowedActions == array('*') ||
345                        in_array($action, $allowedActions)
346                );
347
348                if ($loginAction != $url && $isAllowed) {
349                        return true;
350                }
351
352                if ($loginAction == $url) {
353                        $model =& $this->getModel();
354                        if (empty($controller->data) || !isset($controller->data[$model->alias])) {
355                                if (!$this->Session->check('Auth.redirect') && !$this->loginRedirect && env('HTTP_REFERER')) {
356                                        $this->Session->write('Auth.redirect', $controller->referer(null, true));
357                                }
358                                return false;
359                        }
360
361                        $isValid = !empty($controller->data[$model->alias][$this->fields['username']]) &&
362                                !empty($controller->data[$model->alias][$this->fields['password']]);
363
364                        if ($isValid) {
365                                $username = $controller->data[$model->alias][$this->fields['username']];
366                                $password = $controller->data[$model->alias][$this->fields['password']];
367
368                                $data = array(
369                                        $model->alias . '.' . $this->fields['username'] => $username,
370                                        $model->alias . '.' . $this->fields['password'] => $password
371                                );
372
373                                if ($this->login($data)) {
374                                        if ($this->autoRedirect) {
375                                                $controller->redirect($this->redirect(), null, true);
376                                        }
377                                        return true;
378                                }
379                        }
380
381                        $this->Session->setFlash($this->loginError, $this->flashElement, array(), 'auth');
382                        $controller->data[$model->alias][$this->fields['password']] = null;
383                        return false;
384                } else {
385                        $user = $this->user();
386                        if (!$user) {
387                                if (!$this->RequestHandler->isAjax()) {
388                                        $this->Session->setFlash($this->authError, $this->flashElement, array(), 'auth');
389                                        if (!empty($controller->params['url']) && count($controller->params['url']) >= 2) {
390                                                $query = $controller->params['url'];
391                                                unset($query['url'], $query['ext']);
392                                                $url .= Router::queryString($query, array());
393                                        }
394                                        $this->Session->write('Auth.redirect', $url);
395                                        $controller->redirect($loginAction);
396                                        return false;
397                                } elseif (!empty($this->ajaxLogin)) {
398                                        $controller->viewPath = 'elements';
399                                        echo $controller->render($this->ajaxLogin, $this->RequestHandler->ajaxLayout);
400                                        $this->_stop();
401                                        return false;
402                                } else {
403                                        $controller->redirect(null, 403);
404                                }
405                        }
406                }
407
408                if (!$this->authorize) {
409                        return true;
410                }
411
412                extract($this->__authType());
413                switch ($type) {
414                        case 'controller':
415                                $this->object =& $controller;
416                        break;
417                        case 'crud':
418                        case 'actions':
419                                if (isset($controller->Acl)) {
420                                        $this->Acl =& $controller->Acl;
421                                } else {
422                                        trigger_error(__('Could not find AclComponent. Please include Acl in Controller::$components.', true), E_USER_WARNING);
423                                }
424                        break;
425                        case 'model':
426                                if (!isset($object)) {
427                                        $hasModel = (
428                                                isset($controller->{$controller->modelClass}) &&
429                                                is_object($controller->{$controller->modelClass})
430                                        );
431                                        $isUses = (
432                                                !empty($controller->uses) && isset($controller->{$controller->uses[0]}) &&
433                                                is_object($controller->{$controller->uses[0]})
434                                        );
435
436                                        if ($hasModel) {
437                                                $object = $controller->modelClass;
438                                        } elseif ($isUses) {
439                                                $object = $controller->uses[0];
440                                        }
441                                }
442                                $type = array('model' => $object);
443                        break;
444                }
445
446                if ($this->isAuthorized($type, null, $user)) {
447                        return true;
448                }
449
450                $this->Session->setFlash($this->authError, $this->flashElement, array(), 'auth');
451                $controller->redirect($controller->referer(), null, true);
452                return false;
453        }
454
455/**
456 * Attempts to introspect the correct values for object properties including
457 * $userModel and $sessionKey.
458 *
459 * @param object $controller A reference to the instantiating controller object
460 * @return boolean
461 * @access private
462 */
463        function __setDefaults() {
464                if (empty($this->userModel)) {
465                        trigger_error(__("Could not find \$userModel. Please set AuthComponent::\$userModel in beforeFilter().", true), E_USER_WARNING);
466                        return false;
467                }
468                list($plugin, $model) = pluginSplit($this->userModel);
469                $defaults = array(
470                        'loginAction' => array(
471                                'controller' => Inflector::underscore(Inflector::pluralize($model)),
472                                'action' => 'login',
473                                'plugin' => Inflector::underscore($plugin),
474                        ),
475                        'sessionKey' => 'Auth.' . $model,
476                        'logoutRedirect' => $this->loginAction,
477                        'loginError' => __('Login failed. Invalid username or password.', true),
478                        'authError' => __('You are not authorized to access that location.', true)
479                );
480                foreach ($defaults as $key => $value) {
481                        if (empty($this->{$key})) {
482                                $this->{$key} = $value;
483                        }
484                }
485                return true;
486        }
487
488/**
489 * Determines whether the given user is authorized to perform an action.  The type of
490 * authorization used is based on the value of AuthComponent::$authorize or the
491 * passed $type param.
492 *
493 * Types:
494 * 'controller' will validate against Controller::isAuthorized() if controller instance is
495 *                              passed in $object
496 * 'actions' will validate Controller::action against an AclComponent::check()
497 * 'crud' will validate mapActions against an AclComponent::check()
498 *              array('model'=> 'name'); will validate mapActions against model
499 *              $name::isAuthorized(user, controller, mapAction)
500 * 'object' will validate Controller::action against
501 *              object::isAuthorized(user, controller, action)
502 *
503 * @param string $type Type of authorization
504 * @param mixed $object object, model object, or model name
505 * @param mixed $user The user to check the authorization of
506 * @return boolean True if $user is authorized, otherwise false
507 * @access public
508 */
509        function isAuthorized($type = null, $object = null, $user = null) {
510                if (empty($user) && !$this->user()) {
511                        return false;
512                } elseif (empty($user)) {
513                        $user = $this->user();
514                }
515
516                extract($this->__authType($type));
517
518                if (!$object) {
519                        $object = $this->object;
520                }
521
522                $valid = false;
523                switch ($type) {
524                        case 'controller':
525                                $valid = $object->isAuthorized();
526                        break;
527                        case 'actions':
528                                $valid = $this->Acl->check($user, $this->action());
529                        break;
530                        case 'crud':
531                                if (!isset($this->actionMap[$this->params['action']])) {
532                                        trigger_error(
533                                                sprintf(__('Auth::startup() - Attempted access of un-mapped action "%1$s" in controller "%2$s"', true), $this->params['action'], $this->params['controller']),
534                                                E_USER_WARNING
535                                        );
536                                } else {
537                                        $valid = $this->Acl->check(
538                                                $user,
539                                                $this->action(':controller'),
540                                                $this->actionMap[$this->params['action']]
541                                        );
542                                }
543                        break;
544                        case 'model':
545                                $action = $this->params['action'];
546                                if (isset($this->actionMap[$action])) {
547                                        $action = $this->actionMap[$action];
548                                }
549                                if (is_string($object)) {
550                                        $object = $this->getModel($object);
551                                }
552                        case 'object':
553                                if (!isset($action)) {
554                                        $action = $this->action(':action');
555                                }
556                                if (empty($object)) {
557                                        trigger_error(sprintf(__('Could not find %s. Set AuthComponent::$object in beforeFilter() or pass a valid object', true), get_class($object)), E_USER_WARNING);
558                                        return;
559                                }
560                                if (method_exists($object, 'isAuthorized')) {
561                                        $valid = $object->isAuthorized($user, $this->action(':controller'), $action);
562                                } elseif ($object) {
563                                        trigger_error(sprintf(__('%s::isAuthorized() is not defined.', true), get_class($object)), E_USER_WARNING);
564                                }
565                        break;
566                        case null:
567                        case false:
568                                return true;
569                        break;
570                        default:
571                                trigger_error(__('Auth::isAuthorized() - $authorize is set to an incorrect value.  Allowed settings are: "actions", "crud", "model" or null.', true), E_USER_WARNING);
572                        break;
573                }
574                return $valid;
575        }
576
577/**
578 * Get authorization type
579 *
580 * @param string $auth Type of authorization
581 * @return array Associative array with: type, object
582 * @access private
583 */
584        function __authType($auth = null) {
585                if ($auth == null) {
586                        $auth = $this->authorize;
587                }
588                $object = null;
589                if (is_array($auth)) {
590                        $type = key($auth);
591                        $object = $auth[$type];
592                } else {
593                        $type = $auth;
594                        return compact('type');
595                }
596                return compact('type', 'object');
597        }
598
599/**
600 * Takes a list of actions in the current controller for which authentication is not required, or
601 * no parameters to allow all actions.
602 *
603 * @param mixed $action Controller action name or array of actions
604 * @param string $action Controller action name
605 * @param string ... etc.
606 * @return void
607 * @access public
608 * @link http://book.cakephp.org/view/1257/allow
609 */
610        function allow() {
611                $args = func_get_args();
612                if (empty($args) || $args == array('*')) {
613                        $this->allowedActions = $this->_methods;
614                } else {
615                        if (isset($args[0]) && is_array($args[0])) {
616                                $args = $args[0];
617                        }
618                        $this->allowedActions = array_merge($this->allowedActions, array_map('strtolower', $args));
619                }
620        }
621
622/**
623 * Removes items from the list of allowed actions.
624 *
625 * @param mixed $action Controller action name or array of actions
626 * @param string $action Controller action name
627 * @param string ... etc.
628 * @return void
629 * @see AuthComponent::allow()
630 * @access public
631 * @link http://book.cakephp.org/view/1258/deny
632 */
633        function deny() {
634                $args = func_get_args();
635                if (isset($args[0]) && is_array($args[0])) {
636                        $args = $args[0];
637                }
638                foreach ($args as $arg) {
639                        $i = array_search(strtolower($arg), $this->allowedActions);
640                        if (is_int($i)) {
641                                unset($this->allowedActions[$i]);
642                        }
643                }
644                $this->allowedActions = array_values($this->allowedActions);
645        }
646
647/**
648 * Maps action names to CRUD operations. Used for controller-based authentication.
649 *
650 * @param array $map Actions to map
651 * @return void
652 * @access public
653 * @link http://book.cakephp.org/view/1260/mapActions
654 */
655        function mapActions($map = array()) {
656                $crud = array('create', 'read', 'update', 'delete');
657                foreach ($map as $action => $type) {
658                        if (in_array($action, $crud) && is_array($type)) {
659                                foreach ($type as $typedAction) {
660                                        $this->actionMap[$typedAction] = $action;
661                                }
662                        } else {
663                                $this->actionMap[$action] = $type;
664                        }
665                }
666        }
667
668/**
669 * Manually log-in a user with the given parameter data.  The $data provided can be any data
670 * structure used to identify a user in AuthComponent::identify().  If $data is empty or not
671 * specified, POST data from Controller::$data will be used automatically.
672 *
673 * After (if) login is successful, the user record is written to the session key specified in
674 * AuthComponent::$sessionKey.
675 *
676 * @param mixed $data User object
677 * @return boolean True on login success, false on failure
678 * @access public
679 * @link http://book.cakephp.org/view/1261/login
680 */
681        function login($data = null) {
682                $this->__setDefaults();
683                $this->_loggedIn = false;
684
685                if (empty($data)) {
686                        $data = $this->data;
687                }
688
689                if ($user = $this->identify($data)) {
690                        $this->Session->write($this->sessionKey, $user);
691                        $this->_loggedIn = true;
692                }
693                return $this->_loggedIn;
694        }
695
696/**
697 * Logs a user out, and returns the login action to redirect to.
698 *
699 * @param mixed $url Optional URL to redirect the user to after logout
700 * @return string AuthComponent::$loginAction
701 * @see AuthComponent::$loginAction
702 * @access public
703 * @link http://book.cakephp.org/view/1262/logout
704 */
705        function logout() {
706                $this->__setDefaults();
707                $this->Session->delete($this->sessionKey);
708                $this->Session->delete('Auth.redirect');
709                $this->_loggedIn = false;
710                return Router::normalize($this->logoutRedirect);
711        }
712
713/**
714 * Get the current user from the session.
715 *
716 * @param string $key field to retrive.  Leave null to get entire User record
717 * @return mixed User record. or null if no user is logged in.
718 * @access public
719 * @link http://book.cakephp.org/view/1264/user
720 */
721        function user($key = null) {
722                $this->__setDefaults();
723                if (!$this->Session->check($this->sessionKey)) {
724                        return null;
725                }
726
727                if ($key == null) {
728                        $model =& $this->getModel();
729                        return array($model->alias => $this->Session->read($this->sessionKey));
730                } else {
731                        $user = $this->Session->read($this->sessionKey);
732                        if (isset($user[$key])) {
733                                return $user[$key];
734                        }
735                        return null;
736                }
737        }
738
739/**
740 * If no parameter is passed, gets the authentication redirect URL.
741 *
742 * @param mixed $url Optional URL to write as the login redirect URL.
743 * @return string Redirect URL
744 * @access public
745 */
746        function redirect($url = null) {
747                if (!is_null($url)) {
748                        $redir = $url;
749                        $this->Session->write('Auth.redirect', $redir);
750                } elseif ($this->Session->check('Auth.redirect')) {
751                        $redir = $this->Session->read('Auth.redirect');
752                        $this->Session->delete('Auth.redirect');
753
754                        if (Router::normalize($redir) == Router::normalize($this->loginAction)) {
755                                $redir = $this->loginRedirect;
756                        }
757                } else {
758                        $redir = $this->loginRedirect;
759                }
760                return Router::normalize($redir);
761        }
762
763/**
764 * Validates a user against an abstract object.
765 *
766 * @param mixed $object  The object to validate the user against.
767 * @param mixed $user    Optional.  The identity of the user to be validated.
768 *                       Uses the current user session if none specified.  For
769 *                       valid forms of identifying users, see
770 *                       AuthComponent::identify().
771 * @param string $action Optional. The action to validate against.
772 * @see AuthComponent::identify()
773 * @return boolean True if the user validates, false otherwise.
774 * @access public
775 */
776        function validate($object, $user = null, $action = null) {
777                if (empty($user)) {
778                        $user = $this->user();
779                }
780                if (empty($user)) {
781                        return false;
782                }
783                return $this->Acl->check($user, $object, $action);
784        }
785
786/**
787 * Returns the path to the ACO node bound to a controller/action.
788 *
789 * @param string $action  Optional.  The controller/action path to validate the
790 *                        user against.  The current request action is used if
791 *                        none is specified.
792 * @return boolean ACO node path
793 * @access public
794 * @link http://book.cakephp.org/view/1256/action
795 */
796        function action($action = ':plugin/:controller/:action') {
797                $plugin = empty($this->params['plugin']) ? null : Inflector::camelize($this->params['plugin']) . '/';
798                return str_replace(
799                        array(':controller', ':action', ':plugin/'),
800                        array(Inflector::camelize($this->params['controller']), $this->params['action'], $plugin),
801                        $this->actionPath . $action
802                );
803        }
804
805/**
806 * Returns a reference to the model object specified, and attempts
807 * to load it if it is not found.
808 *
809 * @param string $name Model name (defaults to AuthComponent::$userModel)
810 * @return object A reference to a model object
811 * @access public
812 */
813        function &getModel($name = null) {
814                $model = null;
815                if (!$name) {
816                        $name = $this->userModel;
817                }
818
819                if (PHP5) {
820                        $model = ClassRegistry::init($name);
821                } else {
822                        $model =& ClassRegistry::init($name);
823                }
824
825                if (empty($model)) {
826                        trigger_error(__('Auth::getModel() - Model is not set or could not be found', true), E_USER_WARNING);
827                        return null;
828                }
829
830                return $model;
831        }
832
833/**
834 * Identifies a user based on specific criteria.
835 *
836 * @param mixed $user Optional. The identity of the user to be validated.
837 *              Uses the current user session if none specified.
838 * @param array $conditions Optional. Additional conditions to a find.
839 * @return array User record data, or null, if the user could not be identified.
840 * @access public
841 */
842        function identify($user = null, $conditions = null) {
843                if ($conditions === false) {
844                        $conditions = array();
845                } elseif (is_array($conditions)) {
846                        $conditions = array_merge((array)$this->userScope, $conditions);
847                } else {
848                        $conditions = $this->userScope;
849                }
850                $model =& $this->getModel();
851                if (empty($user)) {
852                        $user = $this->user();
853                        if (empty($user)) {
854                                return null;
855                        }
856                } elseif (is_object($user) && is_a($user, 'Model')) {
857                        if (!$user->exists()) {
858                                return null;
859                        }
860                        $user = $user->read();
861                        $user = $user[$model->alias];
862                } elseif (is_array($user) && isset($user[$model->alias])) {
863                        $user = $user[$model->alias];
864                }
865
866                if (is_array($user) && (isset($user[$this->fields['username']]) || isset($user[$model->alias . '.' . $this->fields['username']]))) {
867                        if (isset($user[$this->fields['username']]) && !empty($user[$this->fields['username']])  && !empty($user[$this->fields['password']])) {
868                                if (trim($user[$this->fields['username']]) == '=' || trim($user[$this->fields['password']]) == '=') {
869                                        return false;
870                                }
871                                $find = array(
872                                        $model->alias.'.'.$this->fields['username'] => $user[$this->fields['username']],
873                                        $model->alias.'.'.$this->fields['password'] => $user[$this->fields['password']]
874                                );
875                        } elseif (isset($user[$model->alias . '.' . $this->fields['username']]) && !empty($user[$model->alias . '.' . $this->fields['username']])) {
876                                if (trim($user[$model->alias . '.' . $this->fields['username']]) == '=' || trim($user[$model->alias . '.' . $this->fields['password']]) == '=') {
877                                        return false;
878                                }
879                                $find = array(
880                                        $model->alias.'.'.$this->fields['username'] => $user[$model->alias . '.' . $this->fields['username']],
881                                        $model->alias.'.'.$this->fields['password'] => $user[$model->alias . '.' . $this->fields['password']]
882                                );
883                        } else {
884                                return false;
885                        }
886                        $data = $model->find('first', array(
887                                'conditions' => array_merge($find, $conditions),
888                                'recursive' => 0
889                        ));
890                        if (empty($data) || empty($data[$model->alias])) {
891                                return null;
892                        }
893                } elseif (!empty($user) && is_string($user)) {
894                        $data = $model->find('first', array(
895                                'conditions' => array_merge(array($model->escapeField() => $user), $conditions),
896                        ));
897                        if (empty($data) || empty($data[$model->alias])) {
898                                return null;
899                        }
900                }
901
902                if (!empty($data)) {
903                        if (!empty($data[$model->alias][$this->fields['password']])) {
904                                unset($data[$model->alias][$this->fields['password']]);
905                        }
906                        return $data[$model->alias];
907                }
908                return null;
909        }
910
911/**
912 * Hash any passwords found in $data using $userModel and $fields['password']
913 *
914 * @param array $data Set of data to look for passwords
915 * @return array Data with passwords hashed
916 * @access public
917 * @link http://book.cakephp.org/view/1259/hashPasswords
918 */
919        function hashPasswords($data) {
920                if (is_object($this->authenticate) && method_exists($this->authenticate, 'hashPasswords')) {
921                        return $this->authenticate->hashPasswords($data);
922                }
923
924                if (is_array($data)) {
925                        $model =& $this->getModel();
926                       
927                        if(isset($data[$model->alias])) {
928                                if (isset($data[$model->alias][$this->fields['username']]) && isset($data[$model->alias][$this->fields['password']])) {
929                                        $data[$model->alias][$this->fields['password']] = $this->password($data[$model->alias][$this->fields['password']]);
930                                }
931                        }
932                }
933                return $data;
934        }
935
936/**
937 * Hash a password with the application's salt value (as defined with Configure::write('Security.salt');
938 *
939 * @param string $password Password to hash
940 * @return string Hashed password
941 * @access public
942 * @link http://book.cakephp.org/view/1263/password
943 */
944        function password($password) {
945                return Security::hash($password, null, true);
946        }
947
948/**
949 * Component shutdown.  If user is logged in, wipe out redirect.
950 *
951 * @param object $controller Instantiating controller
952 * @access public
953 */
954        function shutdown(&$controller) {
955                if ($this->_loggedIn) {
956                        $this->Session->delete('Auth.redirect');
957                }
958        }
959}
Note: See TracBrowser for help on using the repository browser.