diff --git a/cake/libs/controller/components/auth/form_authenticate.php b/cake/libs/controller/components/auth/form_authenticate.php new file mode 100644 index 000000000..324bff557 --- /dev/null +++ b/cake/libs/controller/components/auth/form_authenticate.php @@ -0,0 +1,70 @@ + 1).` + * + * @var array + */ + public $settings = array( + 'fields' => array( + 'username' => 'username', + 'password' => 'password' + ), + 'userModel' => 'User', + 'scope' => array() + ); + +/** + * Constructor + * + * @param array $settings Array of settings to use. + */ + public function __construct($settings) { + $this->settings = Set::merge($this->settings, $settings); + } + +/** + * Authenticates the identity contained in a request. Will use the `settings.userModel`, and `settings.fields` + * to find POST data that is used to find a matching record in the `settings.userModel`. Will return false if + * there is no post data, either username or password is missing, of if the scope conditions have not been met. + * + * @param CakeRequest $request The request that contains login information. + * @return mixed. False on login failure. An array of User data on success. + */ + public function authenticate(CakeRequest $request) { + $userModel = $this->settings['userModel']; + $fields = $this->settings['fields']; + if (empty($request->data[$userModel])) { + return false; + } + if ( + empty($request->data[$userModel][$fields['username']]) || + empty($request->data[$userModel][$fields['password']]) + ) { + return false; + } + $conditions = array( + $userModel . '.' . $fields['username'] => $request->data[$userModel][$fields['username']], + $userModel . '.' . $fields['password'] => $request->data[$userModel][$fields['password']], + ); + if (!empty($this->settings['scope'])) { + $conditions = array_merge($conditions, $this->settings['scope']); + } + $result = ClassRegistry::init($userModel)->find('first', array( + 'conditions' => $conditions, + 'recursive' => 0 + )); + if (empty($result) || empty($result[$userModel])) { + return false; + } + unset($result[$userModel][$fields['password']]); + return $result[$userModel]; + } +} \ No newline at end of file diff --git a/cake/tests/cases/libs/controller/components/auth/form_authenticate.test.php b/cake/tests/cases/libs/controller/components/auth/form_authenticate.test.php new file mode 100644 index 000000000..940c973e0 --- /dev/null +++ b/cake/tests/cases/libs/controller/components/auth/form_authenticate.test.php @@ -0,0 +1,133 @@ +auth = new FormAuthenticate(array( + 'fields' => array('username' => 'user', 'password' => 'password'), + 'userModel' => 'User' + )); + $this->password = Security::hash('password', null, true); + ClassRegistry::init('User')->updateAll(array('password' => '"' . $this->password . '"')); + } + +/** + * test applying settings in the constructor + * + * @return void + */ + function testConstructor() { + $object = new FormAuthenticate(array( + 'userModel' => 'AuthUser', + 'fields' => array('username' => 'user', 'password' => 'password') + )); + $this->assertEquals('AuthUser', $object->settings['userModel']); + $this->assertEquals(array('username' => 'user', 'password' => 'password'), $object->settings['fields']); + } + +/** + * test the authenticate method + * + * @return void + */ + function testAuthenticateNoData() { + $request = new CakeRequest('posts/index', false); + $request->data = array(); + $this->assertFalse($this->auth->authenticate($request)); + } + +/** + * test the authenticate method + * + * @return void + */ + function testAuthenticateNoUsername() { + $request = new CakeRequest('posts/index', false); + $request->data = array('User' => array('password' => 'foobar')); + $this->assertFalse($this->auth->authenticate($request)); + } + +/** + * test the authenticate method + * + * @return void + */ + function testAuthenticateNoPassword() { + $request = new CakeRequest('posts/index', false); + $request->data = array('User' => array('user' => 'mariano')); + $this->assertFalse($this->auth->authenticate($request)); + } + +/** + * test the authenticate method + * + * @return void + */ + function testAuthenticateInjection() { + $request = new CakeRequest('posts/index', false); + $request->data = array( + 'User' => array( + 'user' => '> 1', + 'password' => "' OR 1 = 1" + )); + $this->assertFalse($this->auth->authenticate($request)); + } + +/** + * test authenticate sucesss + * + * @return void + */ + function testAuthenticateSuccess() { + $request = new CakeRequest('posts/index', false); + $request->data = array('User' => array( + 'user' => 'mariano', + 'password' => $this->password + )); + $result = $this->auth->authenticate($request); + $expected = array( + 'id' => 1, + 'user' => 'mariano', + 'created' => '2007-03-17 01:16:23', + 'updated' => '2007-03-17 01:18:31' + ); + $this->assertEquals($expected, $result); + } + +/** + * test scope failure. + * + * @return void + */ + function testAuthenticateScopeFail() { + $this->auth->settings['scope'] = array('user' => 'nate'); + $request = new CakeRequest('posts/index', false); + $request->data = array('User' => array( + 'user' => 'mariano', + 'password' => $this->password + )); + + $this->assertFalse($this->auth->authenticate($request)); + } + +} \ No newline at end of file