Subversion-Projekte lars-tiefland.cakephp

Revision

Details | Letzte Änderung | Log anzeigen | RSS feed

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