ソースを参照

Allow PasswordableBehavior to use diffent auth and hash types

euromark 12 年 前
コミット
ae51654523

+ 26 - 9
Lib/Utility/NumberLib.php

@@ -2,6 +2,11 @@
 App::uses('CakeNumber', 'Utility');
 App::uses('CakeNumber', 'Utility');
 
 
 /**
 /**
+ * Extend CakeNumber with a few important improvements:
+ * - config setting for format()
+ * - spacer char for currency (initially from https://github.com/cakephp/cakephp/pull/1148)
+ * - signed values possible
+ *
  * 2011-03-07 ms
  * 2011-03-07 ms
  */
  */
 class NumberLib extends CakeNumber {
 class NumberLib extends CakeNumber {
@@ -61,7 +66,7 @@ class NumberLib extends CakeNumber {
 	}
 	}
 
 
 	/**
 	/**
-	 * Convinience method to display the default currency
+	 * Convenience method to display the default currency
 	 *
 	 *
 	 * @return string
 	 * @return string
 	 * 2011-10-05 ms
 	 * 2011-10-05 ms
@@ -137,25 +142,37 @@ class NumberLib extends CakeNumber {
 		if ($currency === null) {
 		if ($currency === null) {
 			$currency = self::$_currency;
 			$currency = self::$_currency;
 		}
 		}
-		$options = array(
-			'wholeSymbol' => self::$_symbolRight, 'wholePosition' => 'after',
+		$defaults = array();
+		if ($currency !== 'EUR' && isset(self::$_currencies[$currency])) {
+			$defaults = self::$_currencies[$currency];
+		} elseif ($currency !== 'EUR' && is_string($currency)) {
+			$defaults['wholeSymbol'] = $currency;
+			$defaults['wholePosition'] = 'before';
+			$defaults['spacer'] = true;
+		}
+		$defaults += array(
+			'wholeSymbol' => '€', 'wholePosition' => 'after',
 			'negative' => '-', 'positive'=> '+', 'escape' => true,
 			'negative' => '-', 'positive'=> '+', 'escape' => true,
-			'decimals' => self::$_decimals, 'thousands' => self::$_thousands,
+			'decimals' => ',', 'thousands' => '.',
+			'spacer' => $currency === 'EUR' ? true : false
 		);
 		);
-		$options = array_merge($options, $formatOptions);
+		$options = array_merge($defaults, $formatOptions);
+
+		if (!empty($options['spacer'])) {
+			$spacer = is_string($options['spacer']) ? $options['spacer'] : ' ';
 
 
-		if (!empty($options['wholeSymbol'])) {
 			if ($options['wholePosition'] === 'after') {
 			if ($options['wholePosition'] === 'after') {
-				$options['wholeSymbol'] = ' ' . self::$_symbolRight;
+				$options['wholeSymbol'] = $spacer . $options['wholeSymbol'];
 			} elseif ($options['wholePosition'] === 'before') {
 			} elseif ($options['wholePosition'] === 'before') {
-				$options['wholeSymbol'] = self::$_symbolLeft . ' ';
+				$options['wholeSymbol'] .= $spacer;
 			}
 			}
 		}
 		}
+
 		$sign = '';
 		$sign = '';
 		if ($number > 0 && !empty($options['signed'])) {
 		if ($number > 0 && !empty($options['signed'])) {
 			$sign = $options['positive'];
 			$sign = $options['positive'];
 		}
 		}
-		return $sign . parent::currency($number, $currency, $options);
+		return $sign . parent::currency($number, null, $options);
 	}
 	}
 
 
 	/**
 	/**

+ 2 - 1
Lib/Utility/TextLib.php

@@ -2,7 +2,8 @@
 App::uses('String', 'Utility');
 App::uses('String', 'Utility');
 
 
 /**
 /**
- * TODO: extend the core String class some day?
+ * Extend String.
+ * //TODO: cleanup
  *
  *
  * 2010-08-31 ms
  * 2010-08-31 ms
  */
  */

+ 3 - 0
Lib/Utility/TimeLib.php

@@ -2,6 +2,9 @@
 App::uses('CakeTime', 'Utility');
 App::uses('CakeTime', 'Utility');
 
 
 /**
 /**
+ * Extend CakeNumber with a few important improvements:
+ * - correct timezones for date only input and therefore unchanged day here
+ *
  * 2012-04-06 ms
  * 2012-04-06 ms
  */
  */
 class TimeLib extends CakeTime {
 class TimeLib extends CakeTime {

+ 36 - 9
Model/Behavior/PasswordableBehavior.php

@@ -29,11 +29,12 @@ if (!defined('PWD_MAX_LENGTH')) {
  * now also is capable of:
  * now also is capable of:
  * - require current password prior to altering it (current=>true)
  * - require current password prior to altering it (current=>true)
  * - don't allow the same password it was before (allowSame=>false)
  * - don't allow the same password it was before (allowSame=>false)
+ * - supporting different auth types and password hashing algorythms
  *
  *
  * TODO: allowEmpty and nonEmptyToEmpty - maybe with checkbox "set_new_pwd"
  * TODO: allowEmpty and nonEmptyToEmpty - maybe with checkbox "set_new_pwd"
  * feel free to help me out
  * feel free to help me out
  *
  *
- * @version 1.6 (renamed from ChangePassword to Passwordable)
+ * @version 1.7 (Now 2.4 ready - with passwordHasher support)
  * @author Mark Scherer
  * @author Mark Scherer
  * @link http://www.dereuromark.de/2011/08/25/working-with-passwords-in-cakephp
  * @link http://www.dereuromark.de/2011/08/25/working-with-passwords-in-cakephp
  * @license MIT
  * @license MIT
@@ -52,9 +53,12 @@ class PasswordableBehavior extends ModelBehavior {
 		'formField' => 'pwd',
 		'formField' => 'pwd',
 		'formFieldRepeat' => 'pwd_repeat',
 		'formFieldRepeat' => 'pwd_repeat',
 		'formFieldCurrent' => 'pwd_current',
 		'formFieldCurrent' => 'pwd_current',
-		'hashType' => null,
-		'hashSalt' => true,
+		'userModel' => null,
+		'hashType' => null, # only for authType Form [cake2.3]
+		'hashSalt' => true, # only for authType Form [cake2.3]
 		'auth' => null, # which component (defaults to AuthComponent),
 		'auth' => null, # which component (defaults to AuthComponent),
+		'authType' => 'Form', # which type of authenticate (Form, Blowfish, ...) [cake2.4]
+		'passwordHasher' => null, # if a custom pwd hasher is been used [cake2.4]
 		'allowSame' => true, # dont allow the old password on change,
 		'allowSame' => true, # dont allow the old password on change,
 		'minLength' => PWD_MIN_LENGTH,
 		'minLength' => PWD_MIN_LENGTH,
 		'maxLength' => PWD_MAX_LENGTH
 		'maxLength' => PWD_MAX_LENGTH
@@ -103,7 +107,18 @@ class PasswordableBehavior extends ModelBehavior {
 	);
 	);
 
 
 	/**
 	/**
-	 * if not implemented in AppModel
+	 * If not implemented in AppModel
+	 *
+	 * Note: requires the used Auth component to be App::uses() loaded.
+	 * It also reqires the same Auth setup as in your AppController's beforeFilter().
+	 * So if you set up any special passwordHasher or auth type, you need to provide those
+	 * with the settings passed to the behavior:
+	 *
+	 * 'authType' => 'Blowfish', 'passwordHasher' => array(
+	 *     'className' => 'Simple',
+	 *     'hashType' => 'sha256'
+ 	 * )
+	 *
 	 * @throws CakeException
 	 * @throws CakeException
 	 * @return bool $success
 	 * @return bool $success
 	 * 2011-07-22 ms
 	 * 2011-07-22 ms
@@ -139,13 +154,18 @@ class PasswordableBehavior extends ModelBehavior {
 		$this->Auth = new $authClass(new ComponentCollection());
 		$this->Auth = new $authClass(new ComponentCollection());
 
 
 		# easiest authenticate method via form and (id + pwd)
 		# easiest authenticate method via form and (id + pwd)
+		$authConfig = array(
+			'fields' => array('username' => 'id', 'password' => $this->settings[$Model->alias]['field']),
+			'userModel' => $this->settings[$Model->alias]['userModel'] ? $this->settings[$Model->alias]['userModel'] : $Model->alias
+		);
+		if (!empty($this->settings[$Model->alias]['passwordHasher'])) {
+			$authConfig['passwordHasher'] = $this->settings[$Model->alias]['passwordHasher'];
+		}
 		$this->Auth->authenticate = array(
 		$this->Auth->authenticate = array(
-			'Form' => array(
-				'fields' => array('username' => 'id', 'password' => $this->settings[$Model->alias]['field'])
-			)
+			$this->settings[$Model->alias]['authType'] => $authConfig
 		);
 		);
 		$request = Router::getRequest();
 		$request = Router::getRequest();
-		$request->data['User'] = array('id' => $uid, 'password' => $pwd);
+		$request->data[$Model->alias] = array('id' => $uid, 'password' => $pwd);
 		$response = new CakeResponse();
 		$response = new CakeResponse();
 		return (bool)$this->Auth->identify($request, $response);
 		return (bool)$this->Auth->identify($request, $response);
 	}
 	}
@@ -185,7 +205,10 @@ class PasswordableBehavior extends ModelBehavior {
 		$field = $this->settings[$Model->alias]['field'];
 		$field = $this->settings[$Model->alias]['field'];
 		$type = $this->settings[$Model->alias]['hashType'];
 		$type = $this->settings[$Model->alias]['hashType'];
 		$salt = $this->settings[$Model->alias]['hashSalt'];
 		$salt = $this->settings[$Model->alias]['hashSalt'];
-
+		if ($this->settings[$Model->alias]['authType'] === 'Blowfish') {
+			$type = 'blowfish';
+			$salt = false;
+		}
 		if (!isset($Model->data[$Model->alias][$Model->primaryKey])) {
 		if (!isset($Model->data[$Model->alias][$Model->primaryKey])) {
 			return true;
 			return true;
 		}
 		}
@@ -320,6 +343,10 @@ class PasswordableBehavior extends ModelBehavior {
 		$field = $this->settings[$Model->alias]['field'];
 		$field = $this->settings[$Model->alias]['field'];
 		$type = $this->settings[$Model->alias]['hashType'];
 		$type = $this->settings[$Model->alias]['hashType'];
 		$salt = $this->settings[$Model->alias]['hashSalt'];
 		$salt = $this->settings[$Model->alias]['hashSalt'];
+		if ($this->settings[$Model->alias]['authType'] === 'Blowfish') {
+			$type = 'blowfish';
+			$salt = false;
+		}
 
 
 		if (isset($Model->data[$Model->alias][$formField])) {
 		if (isset($Model->data[$Model->alias][$formField])) {
 			$Model->data[$Model->alias][$field] = Security::hash($Model->data[$Model->alias][$formField], $type, $salt);
 			$Model->data[$Model->alias][$field] = Security::hash($Model->data[$Model->alias][$formField], $type, $salt);

+ 2 - 2
Test/Case/Lib/CaptchaLibTest.php

@@ -12,13 +12,13 @@ class CaptchaLibTest extends MyCakeTestCase {
 	public function setUp() {
 	public function setUp() {
 		parent::setUp();
 		parent::setUp();
 
 
-		$this->Brita = new CaptchaLib();
+		$this->Captcha = new CaptchaLib();
 	}
 	}
 
 
 	public function tearDown() {
 	public function tearDown() {
 		parent::tearDown();
 		parent::tearDown();
 
 
-		unset($this->Brita);
+		unset($this->Captcha);
 	}
 	}
 
 
 	public function testBuildHash() {
 	public function testBuildHash() {

+ 19 - 10
Test/Case/Lib/Utility/NumberLibTest.php

@@ -193,18 +193,16 @@ class NumberLibTest extends MyCakeTestCase {
 	 * @return void
 	 * @return void
 	 */
 	 */
 	public function testCurrencySpacer() {
 	public function testCurrencySpacer() {
-		$this->skipIf(true, 'TODO');
-
-		$result = NumberLib::currency('4.111', 'EUR');
-		$expected = '€4,11';
+		$result = NumberLib::currency('4.111', 'GBP');
+		$expected = '£4.11';
 		$this->assertEquals($expected, $result);
 		$this->assertEquals($expected, $result);
 
 
-		$result = NumberLib::currency('4.111', 'EUR', array('spacer' => false));
-		$expected = '€4,11';
+		$result = NumberLib::currency('4.111', 'GBP', array('spacer' => false));
+		$expected = '£4.11';
 		$this->assertEquals($expected, $result);
 		$this->assertEquals($expected, $result);
 
 
-		$result = NumberLib::currency('4.111', 'EUR', array('spacer' => true));
-		$expected = '€ 4,11';
+		$result = NumberLib::currency('4.111', 'GBP', array('spacer' => true));
+		$expected = '£ 4.11';
 		$this->assertEquals($expected, $result);
 		$this->assertEquals($expected, $result);
 
 
 		$result = NumberLib::currency('-4.111', 'GBP', array('spacer' => false, 'negative' => '-'));
 		$result = NumberLib::currency('-4.111', 'GBP', array('spacer' => false, 'negative' => '-'));
@@ -215,8 +213,19 @@ class NumberLibTest extends MyCakeTestCase {
 		$expected = '-£ 4.11';
 		$expected = '-£ 4.11';
 		$this->assertEquals($expected, $result);
 		$this->assertEquals($expected, $result);
 
 
-		$result = NumberLib::currency('4.111', 'EUR', array('spacer' => ' ', 'escape' => false));
-		$expected = '€ 4,11';
+		$result = NumberLib::currency('4.111', 'GBP', array('spacer' => ' ', 'escape' => false));
+		$expected = '£ 4.11';
+		$this->assertEquals($expected, $result);
+	}
+
+	/**
+	 * NumberLibTest::testCurrencyUnknown()
+	 *
+	 * @return void
+	 */
+	public function testCurrencyUnknown() {
+		$result = NumberLib::currency('4.111', 'XYZ');
+		$expected = 'XYZ 4,11';
 		$this->assertEquals($expected, $result);
 		$this->assertEquals($expected, $result);
 	}
 	}
 
 

+ 172 - 23
Test/Case/Model/Behavior/PasswordableBehaviorTest.php

@@ -1,10 +1,12 @@
 <?php
 <?php
 App::uses('ComponentCollection', 'Controller');
 App::uses('ComponentCollection', 'Controller');
+App::uses('AuthComponent', 'Controller/Component');
+App::uses('SimplePasswordHasher', 'Controller/Component/Auth');
 
 
 class PasswordableBehaviorTest extends CakeTestCase {
 class PasswordableBehaviorTest extends CakeTestCase {
 
 
 	public $fixtures = array(
 	public $fixtures = array(
-		'core.user',
+		'plugin.tools.tools_user', 'plugin.tools.role',
 	);
 	);
 
 
 	/**
 	/**
@@ -15,7 +17,8 @@ class PasswordableBehaviorTest extends CakeTestCase {
 
 
 		Configure::write('Passwordable.auth', 'AuthTest');
 		Configure::write('Passwordable.auth', 'AuthTest');
 
 
-		$this->User = ClassRegistry::init('User');
+		$this->User = ClassRegistry::init('ToolsUser');
+
 		if (isset($this->User->validate['pwd'])) {
 		if (isset($this->User->validate['pwd'])) {
 			unset($this->User->validate['pwd']);
 			unset($this->User->validate['pwd']);
 		}
 		}
@@ -28,6 +31,19 @@ class PasswordableBehaviorTest extends CakeTestCase {
 		if (isset($this->User->order)) {
 		if (isset($this->User->order)) {
 			unset($this->User->order);
 			unset($this->User->order);
 		}
 		}
+
+		$this->User->create();
+		$data = array(
+			'id' => '5',
+			'name' => 'admin',
+			'password' => Security::hash('some', null, true),
+			'role_id' => '1'
+		);
+		$this->User->set($data);
+		$res = $this->User->save();
+		$this->assertTrue((bool)$res);
+
+		Router::setRequestInfo(new CakeRequest(null, false));
 	}
 	}
 
 
 	/**
 	/**
@@ -40,7 +56,6 @@ class PasswordableBehaviorTest extends CakeTestCase {
 		ClassRegistry::flush();
 		ClassRegistry::flush();
 	}
 	}
 
 
-
 	public function testObject() {
 	public function testObject() {
 		$this->User->Behaviors->load('Tools.Passwordable', array());
 		$this->User->Behaviors->load('Tools.Passwordable', array());
 		$this->assertInstanceOf('PasswordableBehavior', $this->User->Behaviors->Passwordable);
 		$this->assertInstanceOf('PasswordableBehavior', $this->User->Behaviors->Passwordable);
@@ -120,11 +135,16 @@ class PasswordableBehaviorTest extends CakeTestCase {
 		$this->assertEquals(array('pwd', 'pwd_repeat'), array_keys($this->User->validationErrors));
 		$this->assertEquals(array('pwd', 'pwd_repeat'), array_keys($this->User->validationErrors));
 	}
 	}
 
 
+	/**
+	 * PasswordableBehaviorTest::testValidateEmptyWithCurrentPassword()
+	 *
+	 * @return void
+	 */
 	public function testValidateEmptyWithCurrentPassword() {
 	public function testValidateEmptyWithCurrentPassword() {
 		$this->User->Behaviors->load('Tools.Passwordable', array('current'=>true));
 		$this->User->Behaviors->load('Tools.Passwordable', array('current'=>true));
 		$this->User->create();
 		$this->User->create();
 		$data = array(
 		$data = array(
-			'id' => 123,
+			'id' => '123',
 			'pwd' => '',
 			'pwd' => '',
 			'pwd_repeat' => '',
 			'pwd_repeat' => '',
 			'pwd_current' => '123',
 			'pwd_current' => '123',
@@ -141,7 +161,7 @@ class PasswordableBehaviorTest extends CakeTestCase {
 		$this->User->Behaviors->load('Tools.Passwordable', array('allowEmpty'=>true, 'current'=>true));
 		$this->User->Behaviors->load('Tools.Passwordable', array('allowEmpty'=>true, 'current'=>true));
 		$this->User->create();
 		$this->User->create();
 		$data = array(
 		$data = array(
-			'user' => 'foo',
+			'name' => 'foo',
 			'pwd' => '',
 			'pwd' => '',
 			'pwd_repeat' => '',
 			'pwd_repeat' => '',
 			'pwd_current' => '',
 			'pwd_current' => '',
@@ -168,7 +188,6 @@ class PasswordableBehaviorTest extends CakeTestCase {
 		//debug($this->User->data);
 		//debug($this->User->data);
 		$is = $this->User->save();
 		$is = $this->User->save();
 		$this->assertTrue(!empty($is));
 		$this->assertTrue(!empty($is));
-
 	}
 	}
 
 
 	/**
 	/**
@@ -180,11 +199,12 @@ class PasswordableBehaviorTest extends CakeTestCase {
 			'formFieldRepeat' => 'passw_repeat',
 			'formFieldRepeat' => 'passw_repeat',
 			'formFieldCurrent' => 'passw_current',
 			'formFieldCurrent' => 'passw_current',
 			'allowSame' => false,
 			'allowSame' => false,
-			'current' => true
+			'current' => true,
+			//'userModel' => 'ToolsUser'
 		));
 		));
 		$this->User->create();
 		$this->User->create();
 		$data = array(
 		$data = array(
-			'id' => 5,
+			'id' => '5',
 			'passw_current' => 'some',
 			'passw_current' => 'some',
 			'passw' => 'some',
 			'passw' => 'some',
 			'passw_repeat' => 'some'
 			'passw_repeat' => 'some'
@@ -196,7 +216,7 @@ class PasswordableBehaviorTest extends CakeTestCase {
 
 
 		$this->User->create();
 		$this->User->create();
 		$data = array(
 		$data = array(
-			'id' => 5,
+			'id' => '5',
 			'passw_current' => 'some',
 			'passw_current' => 'some',
 			'passw' => 'new',
 			'passw' => 'new',
 			'passw_repeat' => 'new'
 			'passw_repeat' => 'new'
@@ -224,7 +244,7 @@ class PasswordableBehaviorTest extends CakeTestCase {
 		$this->User->set($data);
 		$this->User->set($data);
 		$is = $this->User->save();
 		$is = $this->User->save();
 		$this->assertTrue((bool)$is);
 		$this->assertTrue((bool)$is);
-		$id = $is['User']['id'];
+		$id = $is[$this->User->alias]['id'];
 
 
 		$this->User->create();
 		$this->User->create();
 		$data = array(
 		$data = array(
@@ -253,12 +273,145 @@ class PasswordableBehaviorTest extends CakeTestCase {
 	public function testValidateCurrent() {
 	public function testValidateCurrent() {
 		$this->assertFalse($this->User->Behaviors->attached('Passwordable'));
 		$this->assertFalse($this->User->Behaviors->attached('Passwordable'));
 		$this->User->create();
 		$this->User->create();
-		$data = array('user'=>'xyz', 'password'=>Security::hash('some', null, true));
+		$data = array(
+			'name' => 'xyz',
+			'password' => Security::hash('some', null, true));
 		$res = $this->User->save($data);
 		$res = $this->User->save($data);
 		$this->assertTrue(!empty($res));
 		$this->assertTrue(!empty($res));
-		$uid = $this->User->id;
+		$uid = (String)$this->User->id;
 
 
-		$this->User->Behaviors->load('Tools.Passwordable', array('current'=>true));
+		$this->User->Behaviors->load('Tools.Passwordable', array('current' => true));
+		$this->User->create();
+		$data = array(
+			'id' => $uid,
+			'pwd' => '1234',
+			'pwd_repeat' => '123456',
+			//'pwd_current' => '',
+		);
+		$this->User->set($data);
+		$this->assertTrue($this->User->Behaviors->attached('Passwordable'));
+		$is = $this->User->save();
+		$this->assertFalse($is);
+
+		$this->User->create();
+		$data = array(
+			'id' => $uid,
+			'pwd_current' => 'somex',
+			'pwd' => '123456',
+			'pwd_repeat' => '123456'
+		);
+		$this->User->set($data);
+		$is = $this->User->save();
+		$this->assertFalse($is);
+
+		$this->User->create();
+		$data = array(
+			'id' => $uid,
+			'pwd_current' => 'some',
+			'pwd' => '123456',
+			'pwd_repeat' => '123456'
+		);
+		$this->User->set($data);
+		$is = $this->User->save();
+		$this->assertTrue(!empty($is));
+	}
+
+	/**
+	 * PasswordableBehaviorTest::testPasswordHasher()
+	 *
+	 * @return void
+	 */
+	public function testPasswordHasher() {
+		$this->User->Behaviors->load('Tools.Passwordable', array(
+			'formField' => 'pwd',
+			'formFieldRepeat' => 'pwd_repeat',
+			'allowSame' => false,
+			'current' => false,
+			'passwordHasher' => 'Complex',
+		));
+		$this->User->create();
+		$data = array(
+			'pwd' => 'some',
+			'pwd_repeat' => 'some'
+		);
+		$this->User->set($data);
+		$res = $this->User->save();
+		$this->assertTrue((bool)$res);
+		$uid = (String)$this->User->id;
+
+		$this->User->Behaviors->load('Tools.Passwordable', array('current' => true));
+		$this->User->create();
+		$data = array(
+			'id' => $uid,
+			'pwd' => '1234',
+			'pwd_repeat' => '123456',
+			//'pwd_current' => '',
+		);
+		$this->User->set($data);
+		$this->assertTrue($this->User->Behaviors->attached('Passwordable'));
+		$is = $this->User->save();
+		$this->assertFalse($is);
+
+		$this->User->create();
+		$data = array(
+			'id' => $uid,
+			'pwd_current' => 'somex',
+			'pwd' => '123456',
+			'pwd_repeat' => '123456'
+		);
+		$this->User->set($data);
+		$is = $this->User->save();
+		$this->assertFalse($is);
+
+		$this->User->create();
+		$data = array(
+			'id' => $uid,
+			'pwd_current' => 'some',
+			'pwd' => '123456',
+			'pwd_repeat' => '123456'
+		);
+		$this->User->set($data);
+		$is = $this->User->save();
+		$this->assertTrue(!empty($is));
+	}
+
+	/**
+	 * PasswordableBehaviorTest::testBlowfish()
+	 *
+	 * @return void
+	 */
+	public function testBlowfish() {
+		Configure::write('Security.salt', 'Cf1f11ePArKlBJomM0F6aJ');
+		/*
+		$this->assertFalse($this->User->Behaviors->attached('Passwordable'));
+		$this->User->create();
+		$data = array(
+			'name' => 'xyz',
+			'password' => Security::hash('some', 'blowfish'));
+		$res = $this->User->save($data);
+		$this->assertTrue(!empty($res));
+		$uid = (String)$this->User->id;
+		*/
+
+		$this->User->Behaviors->load('Tools.Passwordable', array(
+			'formField' => 'pwd',
+			'formFieldRepeat' => 'pwd_repeat',
+			'allowSame' => false,
+			'current' => false,
+			//'userModel' => 'ToolsUser',
+			'authType' => 'Blowfish',
+		));
+		$this->User->create();
+		$data = array(
+			'pwd' => 'some',
+			'pwd_repeat' => 'some'
+		);
+		$this->User->set($data);
+		$res = $this->User->save();
+		$this->assertTrue((bool)$res);
+		$uid = (String)$this->User->id;
+
+		$this->User->Behaviors->load('Tools.Passwordable', array('current' => true));
 		$this->User->create();
 		$this->User->create();
 		$data = array(
 		$data = array(
 			'id' => $uid,
 			'id' => $uid,
@@ -297,18 +450,14 @@ class PasswordableBehaviorTest extends CakeTestCase {
 }
 }
 
 
 /**
 /**
- * FAKER!
  * 2011-11-03 ms
  * 2011-11-03 ms
  */
  */
-class AuthTestComponent {
+class AuthTestComponent extends AuthComponent {
+}
 
 
-	public function identify($request, $response) {
-		$user = $request->data['User'];
+class ToolsUser extends CakeTestModel {
+}
 
 
-		if ($user['id'] == '5' && $user['password'] === 'some') {
-			return true;
-		}
-		return false;
-	}
+class ComplexPasswordHasher extends SimplePasswordHasher {
 
 
-}
+}