Skip to content
This repository
Fetching contributors…

Octocat-spinner-32-eaf2f5

Cannot retrieve contributors at this time

file 929 lines (852 sloc) 26.468 kb
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549 550 551 552 553 554 555 556 557 558 559 560 561 562 563 564 565 566 567 568 569 570 571 572 573 574 575 576 577 578 579 580 581 582 583 584 585 586 587 588 589 590 591 592 593 594 595 596 597 598 599 600 601 602 603 604 605 606 607 608 609 610 611 612 613 614 615 616 617 618 619 620 621 622 623 624 625 626 627 628 629 630 631 632 633 634 635 636 637 638 639 640 641 642 643 644 645 646 647 648 649 650 651 652 653 654 655 656 657 658 659 660 661 662 663 664 665 666 667 668 669 670 671 672 673 674 675 676 677 678 679 680 681 682 683 684 685 686 687 688 689 690 691 692 693 694 695 696 697 698 699 700 701 702 703 704 705 706 707 708 709 710 711 712 713 714 715 716 717 718 719 720 721 722 723 724 725 726 727 728 729 730 731 732 733 734 735 736 737 738 739 740 741 742 743 744 745 746 747 748 749 750 751 752 753 754 755 756 757 758 759 760 761 762 763 764 765 766 767 768 769 770 771 772 773 774 775 776 777 778 779 780 781 782 783 784 785 786 787 788 789 790 791 792 793 794 795 796 797 798 799 800 801 802 803 804 805 806 807 808 809 810 811 812 813 814 815 816 817 818 819 820 821 822 823 824 825 826 827 828 829 830 831 832 833 834 835 836 837 838 839 840 841 842 843 844 845 846 847 848 849 850 851 852 853 854 855 856 857 858 859 860 861 862 863 864 865 866 867 868 869 870 871 872 873 874 875 876 877 878 879 880 881 882 883 884 885 886 887 888 889 890 891 892 893 894 895 896 897 898 899 900 901 902 903 904 905 906 907 908 909 910 911 912 913 914 915 916 917 918 919 920 921 922 923 924 925 926 927 928 929
<?php
/**
* Authentication component
*
* Manages user logins and permissions.
*
* PHP versions 4 and 5
*
* CakePHP(tm) : Rapid Development Framework (http://www.cakephp.org)
* Copyright 2005-2009, Cake Software Foundation, Inc. (http://www.cakefoundation.org)
*
* Licensed under The MIT License
* Redistributions of files must retain the above copyright notice.
*
* @filesource
* @copyright Copyright 2005-2009, Cake Software Foundation, Inc. (http://www.cakefoundation.org)
* @link http://www.cakefoundation.org/projects/info/cakephp CakePHP(tm) Project
* @package cake
* @subpackage cake.cake.libs.controller.components
* @since CakePHP(tm) v 0.10.0.1076
* @license http://www.opensource.org/licenses/mit-license.php The MIT License
*/

App::import('Core', array('Router', 'Security'), false);

/**
* Authentication control component class
*
* Binds access control with user authentication and session management.
*
* @package cake
* @subpackage cake.cake.libs.controller.components
*/
class AuthComponent extends Object {

/**
* Maintains current user login state.
*
* @var boolean
* @access private
*/
var $_loggedIn = false;

/**
* Other components utilized by AuthComponent
*
* @var array
* @access public
*/
var $components = array('Session', 'RequestHandler');

/**
* A reference to the object used for authentication
*
* @var object
* @access public
*/
var $authenticate = null;

/**
* The name of the component to use for Authorization or set this to
* 'controller' will validate against Controller::isAuthorized()
* 'actions' will validate Controller::action against an AclComponent::check()
* 'crud' will validate mapActions against an AclComponent::check()
* array('model'=> 'name'); will validate mapActions against model $name::isAuthorized(user, controller, mapAction)
* 'object' will validate Controller::action against object::isAuthorized(user, controller, action)
*
* @var mixed
* @access public
*/
var $authorize = false;

/**
* The name of an optional view element to render when an Ajax request is made
* with an invalid or expired session
*
* @var string
* @access public
*/
var $ajaxLogin = null;

/**
* The name of the layout element used on Session::setFlash
*
* @var string
* @access public
*/
var $flashLayout = 'default';

/**
* The name of the model that represents users which will be authenticated. Defaults to 'User'.
*
* @var string
* @access public
*/
var $userModel = 'User';

/**
* Additional query conditions to use when looking up and authenticating users,
* i.e. array('User.is_active' => 1).
*
* @var array
* @access public
*/
var $userScope = array();

/**
* Allows you to specify non-default login name and password fields used in
* $userModel, i.e. array('username' => 'login_name', 'password' => 'passwd').
*
* @var array
* @access public
*/
var $fields = array('username' => 'username', 'password' => 'password');

/**
* The session key name where the record of the current user is stored. If
* unspecified, it will be "Auth.{$userModel name}".
*
* @var string
* @access public
*/
var $sessionKey = null;

/**
* If using action-based access control, this defines how the paths to action
* ACO nodes is computed. If, for example, all controller nodes are nested
* under an ACO node named 'Controllers', $actionPath should be set to
* "Controllers/".
*
* @var string
* @access public
*/
var $actionPath = null;

/**
* A URL (defined as a string or array) to the controller action that handles
* logins.
*
* @var mixed
* @access public
*/
var $loginAction = null;

/**
* Normally, if a user is redirected to the $loginAction page, the location they
* were redirected from will be stored in the session so that they can be
* redirected back after a successful login. If this session value is not
* set, the user will be redirected to the page specified in $loginRedirect.
*
* @var mixed
* @access public
*/
var $loginRedirect = null;

/**
* The the default action to redirect to after the user is logged out. While AuthComponent does
* not handle post-logout redirection, a redirect URL will be returned from AuthComponent::logout().
* Defaults to AuthComponent::$loginAction.
*
* @var mixed
* @access public
* @see AuthComponent::$loginAction
* @see AuthComponent::logout()
*/
var $logoutRedirect = null;

/**
* The name of model or model object, or any other object has an isAuthorized method.
*
* @var string
* @access public
*/
var $object = null;

/**
* Error to display when user login fails. For security purposes, only one error is used for all
* login failures, so as not to expose information on why the login failed.
*
* @var string
* @access public
*/
var $loginError = null;

/**
* Error to display when user attempts to access an object or action to which they do not have
* acccess.
*
* @var string
* @access public
*/
var $authError = null;

/**
* Determines whether AuthComponent will automatically redirect and exit if login is successful.
*
* @var boolean
* @access public
*/
var $autoRedirect = true;

/**
* Controller actions for which user validation is not required.
*
* @var array
* @access public
* @see AuthComponent::allow()
*/
var $allowedActions = array();

/**
* Maps actions to CRUD operations. Used for controller-based validation ($validate = 'controller').
*
* @var array
* @access public
* @see AuthComponent::mapActions()
*/
var $actionMap = array(
'index' => 'read',
'add' => 'create',
'edit' => 'update',
'view' => 'read',
'remove' => 'delete'
);

/**
* Form data from Controller::$data
*
* @var array
* @access public
*/
var $data = array();

/**
* Parameter data from Controller::$params
*
* @var array
* @access public
*/
var $params = array();

/**
* Method list for bound controller
*
* @var array
* @access protected
*/
var $_methods = array();

/**
* Initializes AuthComponent for use in the controller
*
* @param object $controller A reference to the instantiating controller object
* @return void
* @access public
*/
function initialize(&$controller) {
$this->params = $controller->params;
$crud = array('create', 'read', 'update', 'delete');
$this->actionMap = array_merge($this->actionMap, array_combine($crud, $crud));
$this->_methods = $controller->methods;

$admin = Configure::read('Routing.admin');
if (!empty($admin)) {
$this->actionMap = array_merge($this->actionMap, array(
$admin . '_index' => 'read',
$admin . '_add' => 'create',
$admin . '_edit' => 'update',
$admin . '_view' => 'read',
$admin . '_remove' => 'delete',
$admin . '_create' => 'create',
$admin . '_read' => 'read',
$admin . '_update' => 'update',
$admin . '_delete' => 'delete'
));
}
if (Configure::read() > 0) {
App::import('Debugger');
Debugger::checkSessionKey();
}
}

/**
* Main execution method. Handles redirecting of invalid users, and processing
* of login form data.
*
* @param object $controller A reference to the instantiating controller object
* @return boolean
* @access public
*/
function startup(&$controller) {
$methods = array_flip($controller->methods);
$action = strtolower($controller->params['action']);
$allowedActions = array_map('strtolower', $this->allowedActions);

$isErrorOrTests = (
strtolower($controller->name) == 'cakeerror' ||
(strtolower($controller->name) == 'tests' && Configure::read() > 0)
);
if ($isErrorOrTests) {
return true;
}

$isMissingAction = (
$controller->scaffold === false &&
!isset($methods[$action])
);

if ($isMissingAction) {
return true;
}

if (!$this->__setDefaults()) {
return false;
}

$this->data = $controller->data = $this->hashPasswords($controller->data);
$url = '';

if (isset($controller->params['url']['url'])) {
$url = $controller->params['url']['url'];
}
$url = Router::normalize($url);
$loginAction = Router::normalize($this->loginAction);

$isAllowed = (
$this->allowedActions == array('*') ||
in_array($action, $allowedActions)
);

if ($loginAction != $url && $isAllowed) {
return true;
}

if ($loginAction == $url) {
$model =& $this->getModel();
if (empty($controller->data) || !isset($controller->data[$model->alias])) {
if (!$this->Session->check('Auth.redirect') && env('HTTP_REFERER')) {
$this->Session->write('Auth.redirect', $controller->referer(null, true));
}
return false;
}

$isValid = !empty($controller->data[$model->alias][$this->fields['username']]) &&
!empty($controller->data[$model->alias][$this->fields['password']]);

if ($isValid) {
$username = $controller->data[$model->alias][$this->fields['username']];
$password = $controller->data[$model->alias][$this->fields['password']];

$data = array(
$model->alias . '.' . $this->fields['username'] => $username,
$model->alias . '.' . $this->fields['password'] => $password
);

if ($this->login($data)) {
if ($this->autoRedirect) {
$controller->redirect($this->redirect(), null, true);
}
return true;
}
}

$this->Session->setFlash($this->loginError, $this->flashLayout, array(), 'auth');
$controller->data[$model->alias][$this->fields['password']] = null;
return false;
} else {
if (!$this->user()) {
if (!$this->RequestHandler->isAjax()) {
$this->Session->setFlash($this->authError, $this->flashLayout, array(), 'auth');
if (!empty($controller->params['url']) && count($controller->params['url']) >= 2) {
$query = $controller->params['url'];
unset($query['url'], $query['ext']);
$url .= Router::queryString($query, array());
}
$this->Session->write('Auth.redirect', $url);
$controller->redirect($loginAction);
return false;
} elseif (!empty($this->ajaxLogin)) {
$controller->viewPath = 'elements';
echo $controller->render($this->ajaxLogin, $this->RequestHandler->ajaxLayout);
$this->_stop();
return false;
} else {
$controller->redirect(null, 403);
}
}
}

if (!$this->authorize) {
return true;
}

extract($this->__authType());
switch ($type) {
case 'controller':
$this->object =& $controller;
break;
case 'crud':
case 'actions':
if (isset($controller->Acl)) {
$this->Acl =& $controller->Acl;
} else {
$err = 'Could not find AclComponent. Please include Acl in ';
$err .= 'Controller::$components.';
trigger_error(__($err, true), E_USER_WARNING);
}
break;
case 'model':
if (!isset($object)) {
$hasModel = (
isset($controller->{$controller->modelClass}) &&
is_object($controller->{$controller->modelClass})
);
$isUses = (
!empty($controller->uses) && isset($controller->{$controller->uses[0]}) &&
is_object($controller->{$controller->uses[0]})
);

if ($hasModel) {
$object = $controller->modelClass;
} elseif ($isUses) {
$object = $controller->uses[0];
}
}
$type = array('model' => $object);
break;
}

if ($this->isAuthorized($type)) {
return true;
}

$this->Session->setFlash($this->authError, $this->flashLayout, array(), 'auth');
$controller->redirect($controller->referer(), null, true);
return false;
}

/**
* Attempts to introspect the correct values for object properties including
* $userModel and $sessionKey.
*
* @param object $controller A reference to the instantiating controller object
* @return boolean
* @access private
*/
function __setDefaults() {
if (empty($this->userModel)) {
trigger_error(__("Could not find \$userModel. Please set AuthComponent::\$userModel in beforeFilter().", true), E_USER_WARNING);
return false;
}
$defaults = array(
'loginAction' => Router::normalize(array(
'controller'=> Inflector::underscore(Inflector::pluralize($this->userModel)),
'action' => 'login'
)),
'sessionKey' => 'Auth.' . $this->userModel,
'logoutRedirect' => $this->loginAction,
'loginError' => __('Login failed. Invalid username or password.', true),
'authError' => __('You are not authorized to access that location.', true)
);
foreach ($defaults as $key => $value) {
if (empty($this->{$key})) {
$this->{$key} = $value;
}
}
return true;
}

/**
* Determines whether the given user is authorized to perform an action. The type of
* authorization used is based on the value of AuthComponent::$authorize or the
* passed $type param.
*
* Types:
* 'controller' will validate against Controller::isAuthorized() if controller instance is
* passed in $object
* 'actions' will validate Controller::action against an AclComponent::check()
* 'crud' will validate mapActions against an AclComponent::check()
* array('model'=> 'name'); will validate mapActions against model
* $name::isAuthorized(user, controller, mapAction)
* 'object' will validate Controller::action against
* object::isAuthorized(user, controller, action)
*
* @param string $type Type of authorization
* @param mixed $object object, model object, or model name
* @param mixed $user The user to check the authorization of
* @return boolean True if $user is authorized, otherwise false
* @access public
*/
function isAuthorized($type = null, $object = null, $user = null) {
if (empty($user) && !$this->user()) {
return false;
} elseif (empty($user)) {
$user = $this->user();
}

extract($this->__authType($type));

if (!$object) {
$object = $this->object;
}

$valid = false;
switch ($type) {
case 'controller':
$valid = $object->isAuthorized();
break;
case 'actions':
$valid = $this->Acl->check($user, $this->action());
break;
case 'crud':
$this->mapActions();
if (!isset($this->actionMap[$this->params['action']])) {
$err = 'Auth::startup() - Attempted access of un-mapped action "%1$s" in';
$err .= ' controller "%2$s"';
trigger_error(
sprintf(__($err, true), $this->params['action'], $this->params['controller']),
E_USER_WARNING
);
} else {
$valid = $this->Acl->check(
$user,
$this->action(':controller'),
$this->actionMap[$this->params['action']]
);
}
break;
case 'model':
$this->mapActions();
$action = $this->params['action'];
if (isset($this->actionMap[$action])) {
$action = $this->actionMap[$action];
}
if (is_string($object)) {
$object = $this->getModel($object);
}
case 'object':
if (!isset($action)) {
$action = $this->action(':action');
}
if (empty($object)) {
trigger_error(sprintf(__('Could not find %s. Set AuthComponent::$object in beforeFilter() or pass a valid object', true), get_class($object)), E_USER_WARNING);
return;
}
if (method_exists($object, 'isAuthorized')) {
$valid = $object->isAuthorized($user, $this->action(':controller'), $action);
} elseif ($object) {
trigger_error(sprintf(__('%s::isAuthorized() is not defined.', true), get_class($object)), E_USER_WARNING);
}
break;
case null:
case false:
return true;
break;
default:
trigger_error(__('Auth::isAuthorized() - $authorize is set to an incorrect value. Allowed settings are: "actions", "crud", "model" or null.', true), E_USER_WARNING);
break;
}
return $valid;
}

/**
* Get authorization type
*
* @param string $auth Type of authorization
* @return array Associative array with: type, object
* @access private
*/
function __authType($auth = null) {
if ($auth == null) {
$auth = $this->authorize;
}
$object = null;
if (is_array($auth)) {
$type = key($auth);
$object = $auth[$type];
} else {
$type = $auth;
return compact('type');
}
return compact('type', 'object');
}

/**
* Takes a list of actions in the current controller for which authentication is not required, or
* no parameters to allow all actions.
*
* @param mixed $action Controller action name or array of actions
* @param string $action Controller action name
* @param string ... etc.
* @return void
* @access public
*/
function allow() {
$args = func_get_args();
if (empty($args) || $args == array('*')) {
$this->allowedActions = $this->_methods;
} else {
if (isset($args[0]) && is_array($args[0])) {
$args = $args[0];
}
$this->allowedActions = array_merge($this->allowedActions, array_map('strtolower', $args));
}
}

/**
* Removes items from the list of allowed actions.
*
* @param mixed $action Controller action name or array of actions
* @param string $action Controller action name
* @param string ... etc.
* @return void
* @see AuthComponent::allow()
* @access public
*/
function deny() {
$args = func_get_args();
if (isset($args[0]) && is_array($args[0])) {
$args = $args[0];
}
foreach ($args as $arg) {
$i = array_search(strtolower($arg), $this->allowedActions);
if (is_int($i)) {
unset($this->allowedActions[$i]);
}
}
$this->allowedActions = array_values($this->allowedActions);
}

/**
* Maps action names to CRUD operations. Used for controller-based authentication.
*
* @param array $map Actions to map
* @return void
* @access public
*/
function mapActions($map = array()) {
$crud = array('create', 'read', 'update', 'delete');
foreach ($map as $action => $type) {
if (in_array($action, $crud) && is_array($type)) {
foreach ($type as $typedAction) {
$this->actionMap[$typedAction] = $action;
}
} else {
$this->actionMap[$action] = $type;
}
}
}

/**
* Manually log-in a user with the given parameter data. The $data provided can be any data
* structure used to identify a user in AuthComponent::identify(). If $data is empty or not
* specified, POST data from Controller::$data will be used automatically.
*
* After (if) login is successful, the user record is written to the session key specified in
* AuthComponent::$sessionKey.
*
* @param mixed $data User object
* @return boolean True on login success, false on failure
* @access public
*/
function login($data = null) {
$this->__setDefaults();
$this->_loggedIn = false;

if (empty($data)) {
$data = $this->data;
}

if ($user = $this->identify($data)) {
$this->Session->write($this->sessionKey, $user);
$this->_loggedIn = true;
}
return $this->_loggedIn;
}

/**
* Logs a user out, and returns the login action to redirect to.
*
* @param mixed $url Optional URL to redirect the user to after logout
* @return string AuthComponent::$loginAction
* @see AuthComponent::$loginAction
* @access public
*/
function logout() {
$this->__setDefaults();
$this->Session->delete($this->sessionKey);
$this->Session->delete('Auth.redirect');
$this->_loggedIn = false;
return Router::normalize($this->logoutRedirect);
}

/**
* Get the current user from the session.
*
* @param string $key field to retrive. Leave null to get entire User record
* @return mixed User record. or null if no user is logged in.
* @access public
*/
function user($key = null) {
$this->__setDefaults();
if (!$this->Session->check($this->sessionKey)) {
return null;
}

if ($key == null) {
$model =& $this->getModel();
return array($model->alias => $this->Session->read($this->sessionKey));
} else {
$user = $this->Session->read($this->sessionKey);
if (isset($user[$key])) {
return $user[$key];
}
return null;
}
}

/**
* If no parameter is passed, gets the authentication redirect URL.
*
* @param mixed $url Optional URL to write as the login redirect URL.
* @return string Redirect URL
* @access public
*/
function redirect($url = null) {
if (!is_null($url)) {
$redir = $url;
$this->Session->write('Auth.redirect', $redir);
} elseif ($this->Session->check('Auth.redirect')) {
$redir = $this->Session->read('Auth.redirect');
$this->Session->delete('Auth.redirect');

if (Router::normalize($redir) == Router::normalize($this->loginAction)) {
$redir = $this->loginRedirect;
}
} else {
$redir = $this->loginRedirect;
}
return Router::normalize($redir);
}

/**
* Validates a user against an abstract object.
*
* @param mixed $object The object to validate the user against.
* @param mixed $user Optional. The identity of the user to be validated.
* Uses the current user session if none specified. For
* valid forms of identifying users, see
* AuthComponent::identify().
* @param string $action Optional. The action to validate against.
* @see AuthComponent::identify()
* @return boolean True if the user validates, false otherwise.
* @access public
*/
function validate($object, $user = null, $action = null) {
if (empty($user)) {
$user = $this->user();
}
if (empty($user)) {
return false;
}
return $this->Acl->check($user, $object, $action);
}

/**
* Returns the path to the ACO node bound to a controller/action.
*
* @param string $action Optional. The controller/action path to validate the
* user against. The current request action is used if
* none is specified.
* @return boolean ACO node path
* @access public
*/
function action($action = ':plugin/:controller/:action') {
$plugin = empty($this->params['plugin']) ? null : Inflector::camelize($this->params['plugin']) . '/';
return str_replace(
array(':controller', ':action', ':plugin/'),
array(Inflector::camelize($this->params['controller']), $this->params['action'], $plugin),
$this->actionPath . $action
);
}

/**
* Returns a reference to the model object specified, and attempts
* to load it if it is not found.
*
* @param string $name Model name (defaults to AuthComponent::$userModel)
* @return object A reference to a model object
* @access public
*/
function &getModel($name = null) {
$model = null;
if (!$name) {
$name = $this->userModel;
}

if (PHP5) {
$model = ClassRegistry::init($name);
} else {
$model =& ClassRegistry::init($name);
}

if (empty($model)) {
trigger_error(__('Auth::getModel() - Model is not set or could not be found', true), E_USER_WARNING);
return null;
}

return $model;
}

/**
* Identifies a user based on specific criteria.
*
* @param mixed $user Optional. The identity of the user to be validated.
* Uses the current user session if none specified.
* @param array $conditions Optional. Additional conditions to a find.
* @return array User record data, or null, if the user could not be identified.
* @access public
*/
function identify($user = null, $conditions = null) {
if ($conditions === false) {
$conditions = null;
} elseif (is_array($conditions)) {
$conditions = array_merge((array)$this->userScope, $conditions);
} else {
$conditions = $this->userScope;
}
$model =& $this->getModel();
if (empty($user)) {
$user = $this->user();
if (empty($user)) {
return null;
}
} elseif (is_object($user) && is_a($user, 'Model')) {
if (!$user->exists()) {
return null;
}
$user = $user->read();
$user = $user[$model->alias];
} elseif (is_array($user) && isset($user[$model->alias])) {
$user = $user[$model->alias];
}

if (is_array($user) && (isset($user[$this->fields['username']]) || isset($user[$model->alias . '.' . $this->fields['username']]))) {
if (isset($user[$this->fields['username']]) && !empty($user[$this->fields['username']]) && !empty($user[$this->fields['password']])) {
if (trim($user[$this->fields['username']]) == '=' || trim($user[$this->fields['password']]) == '=') {
return false;
}
$find = array(
$model->alias.'.'.$this->fields['username'] => $user[$this->fields['username']],
$model->alias.'.'.$this->fields['password'] => $user[$this->fields['password']]
);
} elseif (isset($user[$model->alias . '.' . $this->fields['username']]) && !empty($user[$model->alias . '.' . $this->fields['username']])) {
if (trim($user[$model->alias . '.' . $this->fields['username']]) == '=' || trim($user[$model->alias . '.' . $this->fields['password']]) == '=') {
return false;
}
$find = array(
$model->alias.'.'.$this->fields['username'] => $user[$model->alias . '.' . $this->fields['username']],
$model->alias.'.'.$this->fields['password'] => $user[$model->alias . '.' . $this->fields['password']]
);
} else {
return false;
}
$data = $model->find(array_merge($find, $conditions), null, null, 0);
if (empty($data) || empty($data[$model->alias])) {
return null;
}
} elseif (!empty($user) && is_string($user)) {
$data = $model->find(array_merge(array($model->escapeField() => $user), $conditions));
if (empty($data) || empty($data[$model->alias])) {
return null;
}
}

if (!empty($data)) {
if (!empty($data[$model->alias][$this->fields['password']])) {
unset($data[$model->alias][$this->fields['password']]);
}
return $data[$model->alias];
}
return null;
}

/**
* Hash any passwords found in $data using $userModel and $fields['password']
*
* @param array $data Set of data to look for passwords
* @return array Data with passwords hashed
* @access public
*/
function hashPasswords($data) {
if (is_object($this->authenticate) && method_exists($this->authenticate, 'hashPasswords')) {
return $this->authenticate->hashPasswords($data);
}

$model =& $this->getModel();
if (is_array($data) && isset($data[$model->alias])) {
if (isset($data[$model->alias][$this->fields['username']]) && isset($data[$model->alias][$this->fields['password']])) {
$data[$model->alias][$this->fields['password']] = $this->password($data[$model->alias][$this->fields['password']]);
}
}
return $data;
}

/**
* Hash a password with the application's salt value (as defined with Configure::write('Security.salt');
*
* @param string $password Password to hash
* @return string Hashed password
* @access public
*/
function password($password) {
return Security::hash($password, null, true);
}

/**
* Component shutdown. If user is logged in, wipe out redirect.
*
* @param object $controller Instantiating controller
* @access public
*/
function shutdown(&$controller) {
if ($this->_loggedIn) {
$this->Session->delete('Auth.redirect');
}
}
}
?>
Something went wrong with that request. Please try again.