mirror of
https://github.com/kamilwylegala/cakephp2-php8.git
synced 2025-01-18 02:26:17 +00:00
Authentication and Authorization objects are integrated with AuthComponent. Minimal App changes are needed as legacy settings are forwarded.
This commit is contained in:
parent
ced832ba62
commit
3f9c83c43d
2 changed files with 158 additions and 112 deletions
|
@ -48,20 +48,36 @@ class AuthComponent extends Component {
|
|||
public $components = array('Session', 'RequestHandler');
|
||||
|
||||
/**
|
||||
* A reference to the object used for authentication
|
||||
* An array of authentication objects to use for authenticating users. You can configure
|
||||
* multiple adapters and they will be checked sequentially when users are identified.
|
||||
*
|
||||
* @var object
|
||||
* @link http://book.cakephp.org/view/1278/authenticate
|
||||
*/
|
||||
public $authenticate = null;
|
||||
public $authenticate = array('Form');
|
||||
|
||||
/**
|
||||
* 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)
|
||||
* Objects that will be used for authentication checks.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
protected $_authenticateObjects = array();
|
||||
|
||||
/**
|
||||
* A hash mapping legacy properties => to settings passed into Authenticate objects.
|
||||
*
|
||||
* @var string
|
||||
* @deprecated Will be removed in 2.1+
|
||||
*/
|
||||
protected $_authenticateLegacyMap = array(
|
||||
'userModel' => 'userModel',
|
||||
'userScope' => 'scope',
|
||||
'fields' => 'fields'
|
||||
);
|
||||
|
||||
/**
|
||||
* An array of authorization objects to use for authorizing users. You can configure
|
||||
* multiple adapters and they will be checked sequentially when authorization checks are done.
|
||||
*
|
||||
* @var mixed
|
||||
* @link http://book.cakephp.org/view/1275/authorize
|
||||
|
@ -363,15 +379,7 @@ class AuthComponent extends Component {
|
|||
!empty($request->data[$model->alias][$this->fields['password']]);
|
||||
|
||||
if ($isValid) {
|
||||
$username = $request->data[$model->alias][$this->fields['username']];
|
||||
$password = $request->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->login()) {
|
||||
if ($this->autoRedirect) {
|
||||
$controller->redirect($this->redirect(), null, true);
|
||||
}
|
||||
|
@ -456,18 +464,24 @@ class AuthComponent extends Component {
|
|||
* Each adapter will be checked in sequence, if any of them return true, then the user will
|
||||
* be authorized for the request.
|
||||
*
|
||||
* @param mixed $user The user to check the authorization of, if empty the user in the session will be used.
|
||||
* @param mixed $user The user to check the authorization of. If empty the user in the session will be used.
|
||||
* @param CakeRequest $request The request to authenticate for. If empty, the current request will be used.
|
||||
* @return boolean True if $user is authorized, otherwise false
|
||||
*/
|
||||
public function isAuthorized($user = null) {
|
||||
public function isAuthorized($user = null, $request = null) {
|
||||
if (empty($user) && !$this->user()) {
|
||||
return false;
|
||||
} elseif (empty($user)) {
|
||||
$user = $this->user();
|
||||
}
|
||||
$this->loadAuthorizeObjects();
|
||||
if (empty($request)) {
|
||||
$request = $this->request;
|
||||
}
|
||||
if (empty($this->_authorizeObjects)) {
|
||||
$this->loadAuthorizeObjects();
|
||||
}
|
||||
foreach ($this->_authorizeObjects as $authorizer) {
|
||||
if ($authorizer->authorize($user, $this->request) === true) {
|
||||
if ($authorizer->authorize($user, $request) === true) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
@ -483,6 +497,7 @@ class AuthComponent extends Component {
|
|||
if (empty($this->authorize)) {
|
||||
return;
|
||||
}
|
||||
$this->_authorizeObjects = array();
|
||||
foreach (Set::normalize($this->authorize) as $class => $settings) {
|
||||
$className = $class . 'Authorize';
|
||||
if (!class_exists($className) && !App::import('Component', 'auth/' . $class . '_authorize')) {
|
||||
|
@ -596,15 +611,14 @@ class AuthComponent extends Component {
|
|||
* @return boolean True on login success, false on failure
|
||||
* @link http://book.cakephp.org/view/1261/login
|
||||
*/
|
||||
public function login($data = null) {
|
||||
public function login($request = null) {
|
||||
$this->__setDefaults();
|
||||
$this->_loggedIn = false;
|
||||
|
||||
if (empty($data)) {
|
||||
$data = $this->data;
|
||||
if (empty($request)) {
|
||||
$request = $this->request;
|
||||
}
|
||||
|
||||
if ($user = $this->identify($data)) {
|
||||
if ($user = $this->identify($request)) {
|
||||
$this->Session->write($this->sessionKey, $user);
|
||||
$this->_loggedIn = true;
|
||||
}
|
||||
|
@ -739,80 +753,51 @@ class AuthComponent extends Component {
|
|||
}
|
||||
|
||||
/**
|
||||
* Identifies a user based on specific criteria.
|
||||
* Use the configured authentication adapters, and attempt to identify the user
|
||||
* by credentials contained in $request.
|
||||
*
|
||||
* @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.
|
||||
* @param CakeRequest $request The request that contains authentication data.
|
||||
* @return array User record data, or false, if the user could not be identified.
|
||||
*/
|
||||
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;
|
||||
public function identify(CakeRequest $request) {
|
||||
if (empty($this->_authenticateObjects)) {
|
||||
$this->loadAuthenticateObjects();
|
||||
}
|
||||
$model = $this->getModel();
|
||||
if (empty($user)) {
|
||||
$user = $this->user();
|
||||
if (empty($user)) {
|
||||
return null;
|
||||
foreach ($this->_authenticateObjects as $auth) {
|
||||
$result = $auth->authenticate($request);
|
||||
if (!empty($result) && is_array($result)) {
|
||||
return $result;
|
||||
}
|
||||
} 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];
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
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('first', array(
|
||||
'conditions' => array_merge($find, $conditions),
|
||||
'recursive' => 0
|
||||
));
|
||||
if (empty($data) || empty($data[$model->alias])) {
|
||||
return null;
|
||||
}
|
||||
} elseif (!empty($user) && is_string($user)) {
|
||||
$data = $model->find('first', array(
|
||||
'conditions' => array_merge(array($model->escapeField() => $user), $conditions),
|
||||
));
|
||||
if (empty($data) || empty($data[$model->alias])) {
|
||||
return null;
|
||||
}
|
||||
/**
|
||||
* loads the configured authentication objects.
|
||||
*
|
||||
* @return mixed either null on empty authenticate value, or an array of loaded objects.
|
||||
*/
|
||||
public function loadAuthenticateObjects() {
|
||||
if (empty($this->authenticate)) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (!empty($data)) {
|
||||
if (!empty($data[$model->alias][$this->fields['password']])) {
|
||||
unset($data[$model->alias][$this->fields['password']]);
|
||||
$this->_authenticateObjects = array();
|
||||
foreach (Set::normalize($this->authenticate) as $class => $settings) {
|
||||
$className = $class . 'Authenticate';
|
||||
if (!class_exists($className) && !App::import('Component', 'auth/' . $class . '_authenticate')) {
|
||||
throw new CakeException(__('Authentication adapter "%s" was not found.', $class));
|
||||
}
|
||||
return $data[$model->alias];
|
||||
if (!method_exists($className, 'authenticate')) {
|
||||
throw new CakeException(__('Authentication objects must implement an authenticate method.'));
|
||||
}
|
||||
foreach ($this->_authenticateLegacyMap as $old => $new) {
|
||||
if (empty($settings[$new]) && !empty($this->{$old})) {
|
||||
$settings[$new] = $this->{$old};
|
||||
}
|
||||
}
|
||||
$this->_authenticateObjects[] = new $className($settings);
|
||||
}
|
||||
return null;
|
||||
return $this->_authenticateObjects;
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -582,13 +582,17 @@ class AuthTest extends CakeTestCase {
|
|||
$this->Controller->Auth->startup($this->Controller);
|
||||
$user = $this->Controller->Auth->user();
|
||||
$expected = array('AuthUser' => array(
|
||||
'id' => 1, 'username' => 'mariano', 'created' => '2007-03-17 01:16:23', 'updated' => date('Y-m-d H:i:s')
|
||||
'id' => 1,
|
||||
'username' => 'mariano',
|
||||
'created' => '2007-03-17 01:16:23',
|
||||
'updated' => date('Y-m-d H:i:s')
|
||||
));
|
||||
$this->assertEqual($user, $expected);
|
||||
$this->Controller->Session->delete('Auth');
|
||||
|
||||
$this->Controller->request->data['AuthUser'] = array(
|
||||
'username' => 'blah', 'password' => ''
|
||||
'username' => 'blah',
|
||||
'password' => ''
|
||||
);
|
||||
|
||||
$this->Controller->Auth->startup($this->Controller);
|
||||
|
@ -598,7 +602,8 @@ class AuthTest extends CakeTestCase {
|
|||
$this->Controller->Session->delete('Auth');
|
||||
|
||||
$this->Controller->request->data['AuthUser'] = array(
|
||||
'username' => 'now() or 1=1 --', 'password' => ''
|
||||
'username' => 'now() or 1=1 --',
|
||||
'password' => ''
|
||||
);
|
||||
|
||||
$this->Controller->Auth->startup($this->Controller);
|
||||
|
@ -608,7 +613,8 @@ class AuthTest extends CakeTestCase {
|
|||
$this->Controller->Session->delete('Auth');
|
||||
|
||||
$this->Controller->request->data['AuthUser'] = array(
|
||||
'username' => 'now() or 1=1 #something', 'password' => ''
|
||||
'username' => 'now() or 1=1 #something',
|
||||
'password' => ''
|
||||
);
|
||||
|
||||
$this->Controller->Auth->startup($this->Controller);
|
||||
|
@ -617,14 +623,6 @@ class AuthTest extends CakeTestCase {
|
|||
$this->assertNull($user);
|
||||
$this->Controller->Session->delete('Auth');
|
||||
|
||||
$this->Controller->Auth->userModel = 'UuidUser';
|
||||
$this->Controller->Auth->login('47c36f9c-bc00-4d17-9626-4e183ca6822b');
|
||||
|
||||
$user = $this->Controller->Auth->user();
|
||||
$expected = array('UuidUser' => array(
|
||||
'id' => '47c36f9c-bc00-4d17-9626-4e183ca6822b', 'title' => 'Unique record 1', 'count' => 2, 'created' => '2008-03-13 01:16:23', 'updated' => '2008-03-13 01:18:31'
|
||||
));
|
||||
$this->assertEqual($user, $expected);
|
||||
$this->Controller->Session->delete('Auth');
|
||||
}
|
||||
|
||||
|
@ -850,22 +848,80 @@ class AuthTest extends CakeTestCase {
|
|||
'AuthMockThree'
|
||||
);
|
||||
$mocks = $this->Controller->Auth->loadAuthorizeObjects();
|
||||
$request = $this->Controller->request;
|
||||
|
||||
$this->assertEquals(3, count($mocks));
|
||||
$mocks[0]->expects($this->once())
|
||||
->method('authorize')
|
||||
->with(array('User'))
|
||||
->with(array('User'), $request)
|
||||
->will($this->returnValue(false));
|
||||
|
||||
|
||||
$mocks[1]->expects($this->once())
|
||||
->method('authorize')
|
||||
->with(array('User'))
|
||||
->with(array('User'), $request)
|
||||
->will($this->returnValue(true));
|
||||
|
||||
|
||||
$mocks[2]->expects($this->never())
|
||||
->method('authorize');
|
||||
|
||||
$this->assertTrue($this->Controller->Auth->isAuthorized(array('User')));
|
||||
|
||||
$this->assertTrue($this->Controller->Auth->isAuthorized(array('User'), $request));
|
||||
}
|
||||
|
||||
/**
|
||||
* test that loadAuthorize resets the loaded objects each time.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
function testLoadAuthorizeResets() {
|
||||
$this->Controller->Auth->authorize = array(
|
||||
'Controller'
|
||||
);
|
||||
$result = $this->Controller->Auth->loadAuthorizeObjects();
|
||||
$this->assertEquals(1, count($result));
|
||||
|
||||
$result = $this->Controller->Auth->loadAuthorizeObjects();
|
||||
$this->assertEquals(1, count($result));
|
||||
}
|
||||
|
||||
/**
|
||||
* @expectedException CakeException
|
||||
* @return void
|
||||
*/
|
||||
function testLoadAuthenticateNoFile() {
|
||||
$this->Controller->Auth->authenticate = 'Missing';
|
||||
$this->Controller->Auth->identify($this->Controller->request);
|
||||
}
|
||||
|
||||
/**
|
||||
* test that loadAuthorize resets the loaded objects each time.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
function testLoadAuthenticateResets() {
|
||||
$this->Controller->Auth->authenticate = array(
|
||||
'Form'
|
||||
);
|
||||
$result = $this->Controller->Auth->loadAuthenticateObjects();
|
||||
$this->assertEquals(1, count($result));
|
||||
|
||||
$result = $this->Controller->Auth->loadAuthenticateObjects();
|
||||
$this->assertEquals(1, count($result));
|
||||
}
|
||||
|
||||
/**
|
||||
* test that loadAuthenticate merges in legacy authentication settings.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
function testLoadAuthenticateSettingsPass() {
|
||||
$this->Controller->Auth->userModel = 'AuthUser';
|
||||
$this->Controller->Auth->userScope = array('AuthUser.active' => 1);
|
||||
$this->Controller->Auth->fields = array('username' => 'user', 'password' => 'passwd');
|
||||
|
||||
$this->Controller->Auth->authenticate = array('Form');
|
||||
$objects = $this->Controller->Auth->loadAuthenticateObjects();
|
||||
$result = $objects[0];
|
||||
$this->assertEquals($result->settings['userModel'], 'AuthUser');
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -1463,7 +1519,8 @@ class AuthTest extends CakeTestCase {
|
|||
$authUser = $PluginModel->find();
|
||||
|
||||
$this->Controller->request->data['TestPluginAuthUser'] = array(
|
||||
'username' => $authUser['TestPluginAuthUser']['username'], 'password' => 'cake'
|
||||
'username' => $authUser['TestPluginAuthUser']['username'],
|
||||
'password' => 'cake'
|
||||
);
|
||||
|
||||
$this->Controller->request->addParams(Router::parse('auth_test/login'));
|
||||
|
@ -1476,8 +1533,12 @@ class AuthTest extends CakeTestCase {
|
|||
|
||||
$this->Controller->Auth->startup($this->Controller);
|
||||
$user = $this->Controller->Auth->user();
|
||||
$expected = array('TestPluginAuthUser' => array(
|
||||
'id' => 1, 'username' => 'gwoo', 'created' => '2007-03-17 01:16:23', 'updated' => date('Y-m-d H:i:s')
|
||||
$expected = array(
|
||||
'TestPluginAuthUser' => array(
|
||||
'id' => 1,
|
||||
'username' => 'gwoo',
|
||||
'created' => '2007-03-17 01:16:23',
|
||||
'updated' => date('Y-m-d H:i:s')
|
||||
));
|
||||
$this->assertEqual($user, $expected);
|
||||
$sessionKey = $this->Controller->Auth->sessionKey;
|
||||
|
|
Loading…
Add table
Reference in a new issue