Subversion Repositories SmartDukaan

Rev

Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
12345 anikendra 1
<?php
2
/**
3
 * Authentication component
4
 *
5
 * Manages user logins and permissions.
6
 *
7
 * CakePHP(tm) : Rapid Development Framework (http://cakephp.org)
8
 * Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org)
9
 *
10
 * Licensed under The MIT License
11
 * For full copyright and license information, please see the LICENSE.txt
12
 * Redistributions of files must retain the above copyright notice.
13
 *
14
 * @copyright     Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org)
15
 * @link          http://cakephp.org CakePHP(tm) Project
16
 * @package       Cake.Controller.Component
17
 * @since         CakePHP(tm) v 0.10.0.1076
18
 * @license       http://www.opensource.org/licenses/mit-license.php MIT License
19
 */
20
 
21
App::uses('Component', 'Controller');
22
App::uses('Router', 'Routing');
23
App::uses('Security', 'Utility');
24
App::uses('Debugger', 'Utility');
25
App::uses('Hash', 'Utility');
26
App::uses('CakeSession', 'Model/Datasource');
27
App::uses('BaseAuthorize', 'Controller/Component/Auth');
28
App::uses('BaseAuthenticate', 'Controller/Component/Auth');
29
 
30
/**
31
 * Authentication control component class
32
 *
33
 * Binds access control with user authentication and session management.
34
 *
35
 * @package       Cake.Controller.Component
36
 * @link http://book.cakephp.org/2.0/en/core-libraries/components/authentication.html
37
 */
38
class AuthComponent extends Component {
39
 
40
/**
41
 * Constant for 'all'
42
 *
43
 * @var string
44
 */
45
	const ALL = 'all';
46
 
47
/**
48
 * Other components utilized by AuthComponent
49
 *
50
 * @var array
51
 */
52
	public $components = array('Session', 'RequestHandler');
53
 
54
/**
55
 * An array of authentication objects to use for authenticating users. You can configure
56
 * multiple adapters and they will be checked sequentially when users are identified.
57
 *
58
 * {{{
59
 *	$this->Auth->authenticate = array(
60
 *		'Form' => array(
61
 *			'userModel' => 'Users.User'
62
 *		)
63
 *	);
64
 * }}}
65
 *
66
 * Using the class name without 'Authenticate' as the key, you can pass in an array of settings for each
67
 * authentication object. Additionally you can define settings that should be set to all authentications objects
68
 * using the 'all' key:
69
 *
70
 * {{{
71
 *	$this->Auth->authenticate = array(
72
 *		'all' => array(
73
 *			'userModel' => 'Users.User',
74
 *			'scope' => array('User.active' => 1)
75
 *		),
76
 *		'Form',
77
 *		'Basic'
78
 *	);
79
 * }}}
80
 *
81
 * You can also use AuthComponent::ALL instead of the string 'all'.
82
 *
83
 * @var array
84
 * @link http://book.cakephp.org/2.0/en/core-libraries/components/authentication.html
85
 */
86
	public $authenticate = array('Form');
87
 
88
/**
89
 * Objects that will be used for authentication checks.
90
 *
91
 * @var array
92
 */
93
	protected $_authenticateObjects = array();
94
 
95
/**
96
 * An array of authorization objects to use for authorizing users. You can configure
97
 * multiple adapters and they will be checked sequentially when authorization checks are done.
98
 *
99
 * {{{
100
 *	$this->Auth->authorize = array(
101
 *		'Crud' => array(
102
 *			'actionPath' => 'controllers/'
103
 *		)
104
 *	);
105
 * }}}
106
 *
107
 * Using the class name without 'Authorize' as the key, you can pass in an array of settings for each
108
 * authorization object. Additionally you can define settings that should be set to all authorization objects
109
 * using the 'all' key:
110
 *
111
 * {{{
112
 *	$this->Auth->authorize = array(
113
 *		'all' => array(
114
 *			'actionPath' => 'controllers/'
115
 *		),
116
 *		'Crud',
117
 *		'CustomAuth'
118
 *	);
119
 * }}}
120
 *
121
 * You can also use AuthComponent::ALL instead of the string 'all'
122
 *
123
 * @var mixed
124
 * @link http://book.cakephp.org/2.0/en/core-libraries/components/authentication.html#authorization
125
 */
126
	public $authorize = false;
127
 
128
/**
129
 * Objects that will be used for authorization checks.
130
 *
131
 * @var array
132
 */
133
	protected $_authorizeObjects = array();
134
 
135
/**
136
 * The name of an optional view element to render when an Ajax request is made
137
 * with an invalid or expired session
138
 *
139
 * @var string
140
 */
141
	public $ajaxLogin = null;
142
 
143
/**
144
 * Settings to use when Auth needs to do a flash message with SessionComponent::setFlash().
145
 * Available keys are:
146
 *
147
 * - `element` - The element to use, defaults to 'default'.
148
 * - `key` - The key to use, defaults to 'auth'
149
 * - `params` - The array of additional params to use, defaults to array()
150
 *
151
 * @var array
152
 */
153
	public $flash = array(
154
		'element' => 'default',
155
		'key' => 'auth',
156
		'params' => array()
157
	);
158
 
159
/**
160
 * The session key name where the record of the current user is stored. Default
161
 * key is "Auth.User". If you are using only stateless authenticators set this
162
 * to false to ensure session is not started.
163
 *
164
 * @var string
165
 */
166
	public static $sessionKey = 'Auth.User';
167
 
168
/**
169
 * The current user, used for stateless authentication when
170
 * sessions are not available.
171
 *
172
 * @var array
173
 */
174
	protected static $_user = array();
175
 
176
/**
177
 * A URL (defined as a string or array) to the controller action that handles
178
 * logins. Defaults to `/users/login`.
179
 *
180
 * @var mixed
181
 */
182
	public $loginAction = array(
183
		'controller' => 'users',
184
		'action' => 'login',
185
		'plugin' => null
186
	);
187
 
188
/**
189
 * Normally, if a user is redirected to the $loginAction page, the location they
190
 * were redirected from will be stored in the session so that they can be
191
 * redirected back after a successful login. If this session value is not
192
 * set, redirectUrl() method will return the URL specified in $loginRedirect.
193
 *
194
 * @var mixed
195
 * @link http://book.cakephp.org/2.0/en/core-libraries/components/authentication.html#AuthComponent::$loginRedirect
196
 */
197
	public $loginRedirect = null;
198
 
199
/**
200
 * The default action to redirect to after the user is logged out. While AuthComponent does
201
 * not handle post-logout redirection, a redirect URL will be returned from AuthComponent::logout().
202
 * Defaults to AuthComponent::$loginAction.
203
 *
204
 * @var mixed
205
 * @see AuthComponent::$loginAction
206
 * @see AuthComponent::logout()
207
 */
208
	public $logoutRedirect = null;
209
 
210
/**
211
 * Error to display when user attempts to access an object or action to which they do not have
212
 * access.
213
 *
214
 * @var string|bool
215
 * @link http://book.cakephp.org/2.0/en/core-libraries/components/authentication.html#AuthComponent::$authError
216
 */
217
	public $authError = null;
218
 
219
/**
220
 * Controls handling of unauthorized access.
221
 * - For default value `true` unauthorized user is redirected to the referrer URL
222
 *   or AuthComponent::$loginRedirect or '/'.
223
 * - If set to a string or array the value is used as a URL to redirect to.
224
 * - If set to false a ForbiddenException exception is thrown instead of redirecting.
225
 *
226
 * @var mixed
227
 */
228
	public $unauthorizedRedirect = true;
229
 
230
/**
231
 * Controller actions for which user validation is not required.
232
 *
233
 * @var array
234
 * @see AuthComponent::allow()
235
 */
236
	public $allowedActions = array();
237
 
238
/**
239
 * Request object
240
 *
241
 * @var CakeRequest
242
 */
243
	public $request;
244
 
245
/**
246
 * Response object
247
 *
248
 * @var CakeResponse
249
 */
250
	public $response;
251
 
252
/**
253
 * Method list for bound controller.
254
 *
255
 * @var array
256
 */
257
	protected $_methods = array();
258
 
259
/**
260
 * Initializes AuthComponent for use in the controller.
261
 *
262
 * @param Controller $controller A reference to the instantiating controller object
263
 * @return void
264
 */
265
	public function initialize(Controller $controller) {
266
		$this->request = $controller->request;
267
		$this->response = $controller->response;
268
		$this->_methods = $controller->methods;
269
 
270
		if (Configure::read('debug') > 0) {
271
			Debugger::checkSecurityKeys();
272
		}
273
	}
274
 
275
/**
276
 * Main execution method. Handles redirecting of invalid users, and processing
277
 * of login form data.
278
 *
279
 * @param Controller $controller A reference to the instantiating controller object
280
 * @return bool
281
 */
282
	public function startup(Controller $controller) {
283
		$methods = array_flip(array_map('strtolower', $controller->methods));
284
		$action = strtolower($controller->request->params['action']);
285
 
286
		$isMissingAction = (
287
			$controller->scaffold === false &&
288
			!isset($methods[$action])
289
		);
290
 
291
		if ($isMissingAction) {
292
			return true;
293
		}
294
 
295
		if (!$this->_setDefaults()) {
296
			return false;
297
		}
298
 
299
		if ($this->_isAllowed($controller)) {
300
			return true;
301
		}
302
 
303
		if (!$this->_getUser()) {
304
			return $this->_unauthenticated($controller);
305
		}
306
 
307
		if ($this->_isLoginAction($controller) ||
308
			empty($this->authorize) ||
309
			$this->isAuthorized($this->user())
310
		) {
311
			return true;
312
		}
313
 
314
		return $this->_unauthorized($controller);
315
	}
316
 
317
/**
318
 * Checks whether current action is accessible without authentication.
319
 *
320
 * @param Controller $controller A reference to the instantiating controller object
321
 * @return bool True if action is accessible without authentication else false
322
 */
323
	protected function _isAllowed(Controller $controller) {
324
		$action = strtolower($controller->request->params['action']);
325
		if (in_array($action, array_map('strtolower', $this->allowedActions))) {
326
			return true;
327
		}
328
		return false;
329
	}
330
 
331
/**
332
 * Handles unauthenticated access attempt. First the `unathenticated()` method
333
 * of the last authenticator in the chain will be called. The authenticator can
334
 * handle sending response or redirection as appropriate and return `true` to
335
 * indicate no furthur action is necessary. If authenticator returns null this
336
 * method redirects user to login action. If it's an ajax request and
337
 * $ajaxLogin is specified that element is rendered else a 403 http status code
338
 * is returned.
339
 *
340
 * @param Controller $controller A reference to the controller object.
341
 * @return bool True if current action is login action else false.
342
 */
343
	protected function _unauthenticated(Controller $controller) {
344
		if (empty($this->_authenticateObjects)) {
345
			$this->constructAuthenticate();
346
		}
347
		$auth = $this->_authenticateObjects[count($this->_authenticateObjects) - 1];
348
		if ($auth->unauthenticated($this->request, $this->response)) {
349
			return false;
350
		}
351
 
352
		if ($this->_isLoginAction($controller)) {
353
			if (empty($controller->request->data)) {
354
				if (!$this->Session->check('Auth.redirect') && env('HTTP_REFERER')) {
355
					$this->Session->write('Auth.redirect', $controller->referer(null, true));
356
				}
357
			}
358
			return true;
359
		}
360
 
361
		if (!$controller->request->is('ajax')) {
362
			$this->flash($this->authError);
363
			$this->Session->write('Auth.redirect', $controller->request->here(false));
364
			$controller->redirect($this->loginAction);
365
			return false;
366
		}
367
		if (!empty($this->ajaxLogin)) {
368
			$controller->response->statusCode(403);
369
			$controller->viewPath = 'Elements';
370
			echo $controller->render($this->ajaxLogin, $this->RequestHandler->ajaxLayout);
371
			$this->_stop();
372
			return false;
373
		}
374
		$controller->redirect(null, 403);
375
		return false;
376
	}
377
 
378
/**
379
 * Normalizes $loginAction and checks if current request URL is same as login action.
380
 *
381
 * @param Controller $controller A reference to the controller object.
382
 * @return bool True if current action is login action else false.
383
 */
384
	protected function _isLoginAction(Controller $controller) {
385
		$url = '';
386
		if (isset($controller->request->url)) {
387
			$url = $controller->request->url;
388
		}
389
		$url = Router::normalize($url);
390
		$loginAction = Router::normalize($this->loginAction);
391
 
392
		return $loginAction === $url;
393
	}
394
 
395
/**
396
 * Handle unauthorized access attempt
397
 *
398
 * @param Controller $controller A reference to the controller object
399
 * @return bool Returns false
400
 * @throws ForbiddenException
401
 * @see AuthComponent::$unauthorizedRedirect
402
 */
403
	protected function _unauthorized(Controller $controller) {
404
		if ($this->unauthorizedRedirect === false) {
405
			throw new ForbiddenException($this->authError);
406
		}
407
 
408
		$this->flash($this->authError);
409
		if ($this->unauthorizedRedirect === true) {
410
			$default = '/';
411
			if (!empty($this->loginRedirect)) {
412
				$default = $this->loginRedirect;
413
			}
414
			$url = $controller->referer($default, true);
415
		} else {
416
			$url = $this->unauthorizedRedirect;
417
		}
418
		$controller->redirect($url, null, true);
419
		return false;
420
	}
421
 
422
/**
423
 * Attempts to introspect the correct values for object properties.
424
 *
425
 * @return bool True
426
 */
427
	protected function _setDefaults() {
428
		$defaults = array(
429
			'logoutRedirect' => $this->loginAction,
430
			'authError' => __d('cake', 'You are not authorized to access that location.')
431
		);
432
		foreach ($defaults as $key => $value) {
433
			if (!isset($this->{$key}) || $this->{$key} === true) {
434
				$this->{$key} = $value;
435
			}
436
		}
437
		return true;
438
	}
439
 
440
/**
441
 * Check if the provided user is authorized for the request.
442
 *
443
 * Uses the configured Authorization adapters to check whether or not a user is authorized.
444
 * Each adapter will be checked in sequence, if any of them return true, then the user will
445
 * be authorized for the request.
446
 *
447
 * @param array $user The user to check the authorization of. If empty the user in the session will be used.
448
 * @param CakeRequest $request The request to authenticate for. If empty, the current request will be used.
449
 * @return bool True if $user is authorized, otherwise false
450
 */
451
	public function isAuthorized($user = null, CakeRequest $request = null) {
452
		if (empty($user) && !$this->user()) {
453
			return false;
454
		}
455
		if (empty($user)) {
456
			$user = $this->user();
457
		}
458
		if (empty($request)) {
459
			$request = $this->request;
460
		}
461
		if (empty($this->_authorizeObjects)) {
462
			$this->constructAuthorize();
463
		}
464
		foreach ($this->_authorizeObjects as $authorizer) {
465
			if ($authorizer->authorize($user, $request) === true) {
466
				return true;
467
			}
468
		}
469
		return false;
470
	}
471
 
472
/**
473
 * Loads the authorization objects configured.
474
 *
475
 * @return mixed Either null when authorize is empty, or the loaded authorization objects.
476
 * @throws CakeException
477
 */
478
	public function constructAuthorize() {
479
		if (empty($this->authorize)) {
480
			return;
481
		}
482
		$this->_authorizeObjects = array();
483
		$config = Hash::normalize((array)$this->authorize);
484
		$global = array();
485
		if (isset($config[AuthComponent::ALL])) {
486
			$global = $config[AuthComponent::ALL];
487
			unset($config[AuthComponent::ALL]);
488
		}
489
		foreach ($config as $class => $settings) {
490
			list($plugin, $class) = pluginSplit($class, true);
491
			$className = $class . 'Authorize';
492
			App::uses($className, $plugin . 'Controller/Component/Auth');
493
			if (!class_exists($className)) {
494
				throw new CakeException(__d('cake_dev', 'Authorization adapter "%s" was not found.', $class));
495
			}
496
			if (!method_exists($className, 'authorize')) {
497
				throw new CakeException(__d('cake_dev', 'Authorization objects must implement an %s method.', 'authorize()'));
498
			}
499
			$settings = array_merge($global, (array)$settings);
500
			$this->_authorizeObjects[] = new $className($this->_Collection, $settings);
501
		}
502
		return $this->_authorizeObjects;
503
	}
504
 
505
/**
506
 * Takes a list of actions in the current controller for which authentication is not required, or
507
 * no parameters to allow all actions.
508
 *
509
 * You can use allow with either an array, or var args.
510
 *
511
 * `$this->Auth->allow(array('edit', 'add'));` or
512
 * `$this->Auth->allow('edit', 'add');` or
513
 * `$this->Auth->allow();` to allow all actions
514
 *
515
 * @param string|array $action Controller action name or array of actions
516
 * @return void
517
 * @link http://book.cakephp.org/2.0/en/core-libraries/components/authentication.html#making-actions-public
518
 */
519
	public function allow($action = null) {
520
		$args = func_get_args();
521
		if (empty($args) || $action === null) {
522
			$this->allowedActions = $this->_methods;
523
			return;
524
		}
525
		if (isset($args[0]) && is_array($args[0])) {
526
			$args = $args[0];
527
		}
528
		$this->allowedActions = array_merge($this->allowedActions, $args);
529
	}
530
 
531
/**
532
 * Removes items from the list of allowed/no authentication required actions.
533
 *
534
 * You can use deny with either an array, or var args.
535
 *
536
 * `$this->Auth->deny(array('edit', 'add'));` or
537
 * `$this->Auth->deny('edit', 'add');` or
538
 * `$this->Auth->deny();` to remove all items from the allowed list
539
 *
540
 * @param string|array $action Controller action name or array of actions
541
 * @return void
542
 * @see AuthComponent::allow()
543
 * @link http://book.cakephp.org/2.0/en/core-libraries/components/authentication.html#making-actions-require-authorization
544
 */
545
	public function deny($action = null) {
546
		$args = func_get_args();
547
		if (empty($args) || $action === null) {
548
			$this->allowedActions = array();
549
			return;
550
		}
551
		if (isset($args[0]) && is_array($args[0])) {
552
			$args = $args[0];
553
		}
554
		foreach ($args as $arg) {
555
			$i = array_search($arg, $this->allowedActions);
556
			if (is_int($i)) {
557
				unset($this->allowedActions[$i]);
558
			}
559
		}
560
		$this->allowedActions = array_values($this->allowedActions);
561
	}
562
 
563
/**
564
 * Maps action names to CRUD operations.
565
 *
566
 * Used for controller-based authentication. Make sure
567
 * to configure the authorize property before calling this method. As it delegates $map to all the
568
 * attached authorize objects.
569
 *
570
 * @param array $map Actions to map
571
 * @return void
572
 * @see BaseAuthorize::mapActions()
573
 * @link http://book.cakephp.org/2.0/en/core-libraries/components/authentication.html#mapping-actions-when-using-crudauthorize
574
 */
575
	public function mapActions($map = array()) {
576
		if (empty($this->_authorizeObjects)) {
577
			$this->constructAuthorize();
578
		}
579
		foreach ($this->_authorizeObjects as $auth) {
580
			$auth->mapActions($map);
581
		}
582
	}
583
 
584
/**
585
 * Log a user in.
586
 *
587
 * If a $user is provided that data will be stored as the logged in user. If `$user` is empty or not
588
 * specified, the request will be used to identify a user. If the identification was successful,
589
 * the user record is written to the session key specified in AuthComponent::$sessionKey. Logging in
590
 * will also change the session id in order to help mitigate session replays.
591
 *
592
 * @param array $user Either an array of user data, or null to identify a user using the current request.
593
 * @return bool True on login success, false on failure
594
 * @link http://book.cakephp.org/2.0/en/core-libraries/components/authentication.html#identifying-users-and-logging-them-in
595
 */
596
	public function login($user = null) {
597
		$this->_setDefaults();
598
 
599
		if (empty($user)) {
600
			$user = $this->identify($this->request, $this->response);
601
		}
602
		if ($user) {
603
			$this->Session->renew();
604
			$this->Session->write(self::$sessionKey, $user);
605
		}
606
		return $this->loggedIn();
607
	}
608
 
609
/**
610
 * Log a user out.
611
 *
612
 * Returns the logout action to redirect to. Triggers the logout() method of
613
 * all the authenticate objects, so they can perform custom logout logic.
614
 * AuthComponent will remove the session data, so there is no need to do that
615
 * in an authentication object. Logging out will also renew the session id.
616
 * This helps mitigate issues with session replays.
617
 *
618
 * @return string AuthComponent::$logoutRedirect
619
 * @see AuthComponent::$logoutRedirect
620
 * @link http://book.cakephp.org/2.0/en/core-libraries/components/authentication.html#logging-users-out
621
 */
622
	public function logout() {
623
		$this->_setDefaults();
624
		if (empty($this->_authenticateObjects)) {
625
			$this->constructAuthenticate();
626
		}
627
		$user = $this->user();
628
		foreach ($this->_authenticateObjects as $auth) {
629
			$auth->logout($user);
630
		}
631
		$this->Session->delete(self::$sessionKey);
632
		$this->Session->delete('Auth.redirect');
633
		$this->Session->renew();
634
		return Router::normalize($this->logoutRedirect);
635
	}
636
 
637
/**
638
 * Get the current user.
639
 *
640
 * Will prefer the static user cache over sessions. The static user
641
 * cache is primarily used for stateless authentication. For stateful authentication,
642
 * cookies + sessions will be used.
643
 *
644
 * @param string $key field to retrieve. Leave null to get entire User record
645
 * @return mixed User record. or null if no user is logged in.
646
 * @link http://book.cakephp.org/2.0/en/core-libraries/components/authentication.html#accessing-the-logged-in-user
647
 */
648
	public static function user($key = null) {
649
		if (!empty(self::$_user)) {
650
			$user = self::$_user;
651
		} elseif (self::$sessionKey && CakeSession::check(self::$sessionKey)) {
652
			$user = CakeSession::read(self::$sessionKey);
653
		} else {
654
			return null;
655
		}
656
		if ($key === null) {
657
			return $user;
658
		}
659
		return Hash::get($user, $key);
660
	}
661
 
662
/**
663
 * Similar to AuthComponent::user() except if the session user cannot be found, connected authentication
664
 * objects will have their getUser() methods called. This lets stateless authentication methods function correctly.
665
 *
666
 * @return bool true if a user can be found, false if one cannot.
667
 */
668
	protected function _getUser() {
669
		$user = $this->user();
670
		if ($user) {
671
			$this->Session->delete('Auth.redirect');
672
			return true;
673
		}
674
 
675
		if (empty($this->_authenticateObjects)) {
676
			$this->constructAuthenticate();
677
		}
678
		foreach ($this->_authenticateObjects as $auth) {
679
			$result = $auth->getUser($this->request);
680
			if (!empty($result) && is_array($result)) {
681
				self::$_user = $result;
682
				return true;
683
			}
684
		}
685
 
686
		return false;
687
	}
688
 
689
/**
690
 * Backwards compatible alias for AuthComponent::redirectUrl().
691
 *
692
 * @param string|array $url Optional URL to write as the login redirect URL.
693
 * @return string Redirect URL
694
 * @deprecated 2.3 Use AuthComponent::redirectUrl() instead
695
 */
696
	public function redirect($url = null) {
697
		return $this->redirectUrl($url);
698
	}
699
 
700
/**
701
 * Get the URL a user should be redirected to upon login.
702
 *
703
 * Pass a URL in to set the destination a user should be redirected to upon
704
 * logging in.
705
 *
706
 * If no parameter is passed, gets the authentication redirect URL. The URL
707
 * returned is as per following rules:
708
 *
709
 *  - Returns the normalized URL from session Auth.redirect value if it is
710
 *    present and for the same domain the current app is running on.
711
 *  - If there is no session value and there is a $loginRedirect, the $loginRedirect
712
 *    value is returned.
713
 *  - If there is no session and no $loginRedirect, / is returned.
714
 *
715
 * @param string|array $url Optional URL to write as the login redirect URL.
716
 * @return string Redirect URL
717
 */
718
	public function redirectUrl($url = null) {
719
		if ($url !== null) {
720
			$redir = $url;
721
			$this->Session->write('Auth.redirect', $redir);
722
		} elseif ($this->Session->check('Auth.redirect')) {
723
			$redir = $this->Session->read('Auth.redirect');
724
			$this->Session->delete('Auth.redirect');
725
 
726
			if (Router::normalize($redir) === Router::normalize($this->loginAction)) {
727
				$redir = $this->loginRedirect;
728
			}
729
		} elseif ($this->loginRedirect) {
730
			$redir = $this->loginRedirect;
731
		} else {
732
			$redir = '/';
733
		}
734
		if (is_array($redir)) {
735
			return Router::url($redir + array('base' => false));
736
		}
737
		return $redir;
738
	}
739
 
740
/**
741
 * Use the configured authentication adapters, and attempt to identify the user
742
 * by credentials contained in $request.
743
 *
744
 * @param CakeRequest $request The request that contains authentication data.
745
 * @param CakeResponse $response The response
746
 * @return array User record data, or false, if the user could not be identified.
747
 */
748
	public function identify(CakeRequest $request, CakeResponse $response) {
749
		if (empty($this->_authenticateObjects)) {
750
			$this->constructAuthenticate();
751
		}
752
		foreach ($this->_authenticateObjects as $auth) {
753
			$result = $auth->authenticate($request, $response);
754
			if (!empty($result) && is_array($result)) {
755
				return $result;
756
			}
757
		}
758
		return false;
759
	}
760
 
761
/**
762
 * Loads the configured authentication objects.
763
 *
764
 * @return mixed either null on empty authenticate value, or an array of loaded objects.
765
 * @throws CakeException
766
 */
767
	public function constructAuthenticate() {
768
		if (empty($this->authenticate)) {
769
			return;
770
		}
771
		$this->_authenticateObjects = array();
772
		$config = Hash::normalize((array)$this->authenticate);
773
		$global = array();
774
		if (isset($config[AuthComponent::ALL])) {
775
			$global = $config[AuthComponent::ALL];
776
			unset($config[AuthComponent::ALL]);
777
		}
778
		foreach ($config as $class => $settings) {
779
			if (!empty($settings['className'])) {
780
				$class = $settings['className'];
781
				unset($settings['className']);
782
			}
783
			list($plugin, $class) = pluginSplit($class, true);
784
			$className = $class . 'Authenticate';
785
			App::uses($className, $plugin . 'Controller/Component/Auth');
786
			if (!class_exists($className)) {
787
				throw new CakeException(__d('cake_dev', 'Authentication adapter "%s" was not found.', $class));
788
			}
789
			if (!method_exists($className, 'authenticate')) {
790
				throw new CakeException(__d('cake_dev', 'Authentication objects must implement an %s method.', 'authenticate()'));
791
			}
792
			$settings = array_merge($global, (array)$settings);
793
			$this->_authenticateObjects[] = new $className($this->_Collection, $settings);
794
		}
795
		return $this->_authenticateObjects;
796
	}
797
 
798
/**
799
 * Hash a password with the application's salt value (as defined with Configure::write('Security.salt');
800
 *
801
 * This method is intended as a convenience wrapper for Security::hash(). If you want to use
802
 * a hashing/encryption system not supported by that method, do not use this method.
803
 *
804
 * @param string $password Password to hash
805
 * @return string Hashed password
806
 * @deprecated Since 2.4. Use Security::hash() directly or a password hasher object.
807
 */
808
	public static function password($password) {
809
		return Security::hash($password, null, true);
810
	}
811
 
812
/**
813
 * Check whether or not the current user has data in the session, and is considered logged in.
814
 *
815
 * @return bool true if the user is logged in, false otherwise
816
 * @deprecated Since 2.5. Use AuthComponent::user() directly.
817
 */
818
	public function loggedIn() {
819
		return (bool)$this->user();
820
	}
821
 
822
/**
823
 * Set a flash message. Uses the Session component, and values from AuthComponent::$flash.
824
 *
825
 * @param string $message The message to set.
826
 * @return void
827
 */
828
	public function flash($message) {
829
		if ($message === false) {
830
			return;
831
		}
832
		$this->Session->setFlash($message, $this->flash['element'], $this->flash['params'], $this->flash['key']);
833
	}
834
 
835
}