浏览代码

improve require for PasswordableBehavior

euromark 12 年之前
父节点
当前提交
ac68a31bce
共有 2 个文件被更改,包括 59 次插入21 次删除
  1. 27 16
      Model/Behavior/PasswordableBehavior.php
  2. 32 5
      Test/Case/Model/Behavior/PasswordableBehaviorTest.php

+ 27 - 16
Model/Behavior/PasswordableBehavior.php

@@ -13,7 +13,7 @@ if (!defined('PWD_MAX_LENGTH')) {
 }
 
 /**
- * A cakephp2 behavior to work with passwords the easy way
+ * A CakePHP2 behavior to work with passwords the easy way
  * - complete validation
  * - hashing of password
  * - requires fields (no tempering even without security component)
@@ -47,19 +47,20 @@ class PasswordableBehavior extends ModelBehavior {
 	 */
 	protected $_defaults = array(
 		'field' => 'password',
-		'confirm' => true, # set to false if in admin view and no confirmation (pwd_repeat) is required
-		'allowEmpty' => false, # if password must be provided or be changed (set to true for update sites)
-		'current' => false, # expect the current password for security purposes
+		'confirm' => true, // Set to false if in admin view and no confirmation (pwd_repeat) is required
+		'require' => true, // If a password change is required (set to false for edit forms, leave it true for pure password update forms)
+		'allowEmpty' => false, // Deprecated, do NOT use anymore! Use require instead!
+		'current' => false, // Expect the current password for security purposes
 		'formField' => 'pwd',
 		'formFieldRepeat' => 'pwd_repeat',
 		'formFieldCurrent' => 'pwd_current',
-		'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),
-		'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,
+		'userModel' => null, // Defaults to User
+		'hashType' => null, // only for authType Form [cake2.3]
+		'hashSalt' => true, // only for authType Form [cake2.3]
+		'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,
 		'minLength' => PWD_MIN_LENGTH,
 		'maxLength' => PWD_MAX_LENGTH
 	);
@@ -243,11 +244,23 @@ class PasswordableBehavior extends ModelBehavior {
 		}
 		$this->settings[$Model->alias] = Set::merge($defaults, $config);
 
+		// BC comp
+		if ($this->settings[$Model->alias]['allowEmpty']) {
+			$this->settings[$Model->alias]['require'] = false;
+		}
+
 		$formField = $this->settings[$Model->alias]['formField'];
 		$formFieldRepeat = $this->settings[$Model->alias]['formFieldRepeat'];
 		$formFieldCurrent = $this->settings[$Model->alias]['formFieldCurrent'];
 
 		$rules = $this->_validationRules;
+		foreach ($rules as $key => $rule) {
+			foreach ($rule as $rK => $rR) {
+				$rR['allowEmpty'] = !$this->settings[$Model->alias]['require'];
+
+				$rules[$key][$rK] = $rR;
+			}
+		}
 
 		# add the validation rules if not already attached
 		if (!isset($Model->validate[$formField])) {
@@ -266,7 +279,7 @@ class PasswordableBehavior extends ModelBehavior {
 				$Model->validator()->add($formField, 'validateNotSame', array(
 					'rule' => array('validateNotSame', $formField, $formFieldCurrent),
 					'message' => 'valErrPwdSameAsBefore',
-					'allowEmpty' => $this->settings[$Model->alias]['allowEmpty'],
+					'allowEmpty' => !$this->settings[$Model->alias]['require'],
 					'last' => true,
 				));
 			}
@@ -276,7 +289,7 @@ class PasswordableBehavior extends ModelBehavior {
 				$Model->validator()->add($formField, 'validateNotSame', array(
 					'rule' => array('validateNotSameHash', $formField),
 					'message' => 'valErrPwdSameAsBefore',
-					'allowEmpty' => $this->settings[$Model->alias]['allowEmpty'],
+					'allowEmpty' => !$this->settings[$Model->alias]['require'],
 					'last' => true,
 				));
 			}
@@ -306,7 +319,7 @@ class PasswordableBehavior extends ModelBehavior {
 		}
 
 		# check if we need to trigger any validation rules
-		if ($this->settings[$Model->alias]['allowEmpty']) {
+		if (!$this->settings[$Model->alias]['require']) {
 			$current = !empty($Model->data[$Model->alias][$formFieldCurrent]);
 			$new = !empty($Model->data[$Model->alias][$formField]) || !empty($Model->data[$Model->alias][$formFieldRepeat]);
 			if (!$new && !$current) {
@@ -339,7 +352,6 @@ class PasswordableBehavior extends ModelBehavior {
 		return true;
 	}
 
-
 	/**
 	 * Hashing the password and whitelisting
 	 *
@@ -372,7 +384,6 @@ class PasswordableBehavior extends ModelBehavior {
 				$Model->whitelist = array_merge($Model->whitelist, array($field));
 			}
 		}
-
 		return true;
 	}
 

+ 32 - 5
Test/Case/Model/Behavior/PasswordableBehaviorTest.php

@@ -119,9 +119,9 @@ class PasswordableBehaviorTest extends CakeTestCase {
 	}
 
 	/**
-	 * validation and update process gets skipped if no values are entered
+	 * Trigger validation and update process if no values are entered but are required
 	 */
-	public function testValidateEmpty() {
+	public function testValidateRequired() {
 		$this->User->Behaviors->load('Tools.Passwordable');
 		$this->User->create();
 		$data = array(
@@ -130,18 +130,45 @@ class PasswordableBehaviorTest extends CakeTestCase {
 		);
 		$this->User->set($data);
 		$is = $this->User->save();
-		//debug($this->User->validationErrors);
 		$this->assertFalse($is);
 		$this->assertEquals(array('pwd', 'pwd_repeat'), array_keys($this->User->validationErrors));
 	}
 
 	/**
+	 * validation and update process gets skipped if no values are entered
+	 */
+	public function testValidateNotRequired() {
+		$this->User->Behaviors->load('Tools.Passwordable', array('require' => false));
+		$this->User->create();
+		$data = array(
+			'name' => 'foo', // we need at least one field besides the password on CREATE
+			'pwd' => '',
+			'pwd_repeat' => ''
+		);
+		$this->User->set($data);
+		$is = $this->User->save();
+		$this->assertTrue((bool)$is);
+		$this->assertEquals(array('name', 'id'), array_keys($is['ToolsUser']));
+
+		$id = $this->User->id;
+		$data = array(
+			'id' => $id,
+			'pwd' => '',
+			'pwd_repeat' => ''
+		);
+		$this->User->set($data);
+		$is = $this->User->save();
+		$this->assertTrue((bool)$is);
+		$this->assertEquals(array('id'), array_keys($is['ToolsUser']));
+	}
+
+	/**
 	 * PasswordableBehaviorTest::testValidateEmptyWithCurrentPassword()
 	 *
 	 * @return void
 	 */
 	public function testValidateEmptyWithCurrentPassword() {
-		$this->User->Behaviors->load('Tools.Passwordable', array('current'=>true));
+		$this->User->Behaviors->load('Tools.Passwordable', array('current' => true));
 		$this->User->create();
 		$data = array(
 			'id' => '123',
@@ -158,7 +185,7 @@ class PasswordableBehaviorTest extends CakeTestCase {
 		$this->tearDown();
 		$this->setUp();
 
-		$this->User->Behaviors->load('Tools.Passwordable', array('allowEmpty'=>true, 'current'=>true));
+		$this->User->Behaviors->load('Tools.Passwordable', array('require' => false, 'current'=>true));
 		$this->User->create();
 		$data = array(
 			'name' => 'foo',