Browse Source

change password behavior

m 14 years ago
parent
commit
95765ebd90
1 changed files with 176 additions and 0 deletions
  1. 176 0
      models/behaviors/change_password.php

+ 176 - 0
models/behaviors/change_password.php

@@ -0,0 +1,176 @@
+<?php
+
+/**
+ * Copyright 2011, Mark Scherer 
+ * 
+ * Licensed under The MIT License 
+ * Redistributions of files must retain the above copyright notice. 
+ * 
+ * @version    0.1 
+ * @license    http://www.opensource.org/licenses/mit-license.php The MIT License 
+ */
+
+if (!defined('PWD_MIN_LENGTH')) {
+	define('PWD_MIN_LENGTH', 3);
+}
+if (!defined('PWD_MAX_LENGTH')) {
+	define('PWD_MAX_LENGTH', 20);
+}
+
+/**
+ * A behavior to change passwords the easy way
+ * 
+ * usage:
+ * $this->User->actsAs('Tools.ChangePassword');
+ * as first line in any action where you want to allow the user to change his password
+ * also add the two form fields in the form (pwd, pwd_confirm)
+ * the rest is cake automagic :) 
+ * 
+ * TODO: form_field_current
+ * 
+ * 2011-07-04 ms
+ */
+class ChangePasswordBehavior extends ModelBehavior {
+
+	var $settings = array();
+
+	/**
+	 * @access protected
+	 */
+	var $_defaultSettings = array(
+		'field' => 'password',
+		'confirm' => true, # set to false if in admin view and no confirmation (pwd_repeat) is required
+		'allowEmpty' => false,
+		'current' => false, # expect the current password for security purposes
+		'form_field' => 'pwd',
+		'form_field_repeat' => 'pwd_repeat',
+		'form_field_current' => 'pwd_current',
+		'hashType' => null,
+		'hashSalt' => true
+		//'hash'
+	);
+	
+	var $_validationRules = array(
+		'pwd' => array(
+			'between' => array(
+				'rule' => array('between', PWD_MIN_LENGTH, PWD_MAX_LENGTH),
+				'message' => array('valErrBetweenCharacters %s %s', PWD_MIN_LENGTH, PWD_MAX_LENGTH),
+			)
+		),
+		'pwd_repeat' => array(
+			'between' => array(
+				'rule' => array('between', PWD_MIN_LENGTH, PWD_MAX_LENGTH),
+				'message' => array('valErrBetweenCharacters %s %s', PWD_MIN_LENGTH, PWD_MAX_LENGTH),
+			),
+			'validateIdentical' => array(
+				'rule' => array('validateIdentical', 'pwd'),
+				'message' => 'valErrPwdNotMatch',
+
+			),
+		),
+		'pwd_current' => array(
+			'notEmpty' => array(
+				'rule' => array('notEmpty'),
+				'message' => 'valErrProvideCurrentPwd',
+			),
+			'validateCurrentPwd' => array(
+				'rule' => 'validateCurrentPwd',
+				'message' => 'valErrCurrentPwdIncorrect',
+			)
+		),
+	);
+
+	/**
+	 * if not implemented in app_model
+	 * 2011-07-22 ms
+	 */	
+	public function validateCurrentPwd(Model $Model, $data) {
+		if (is_array($data)) {
+			$pwd = array_shift($data);
+		} else {
+			$pwd = $data;
+		}
+		
+		//TODO
+		return true;
+	}
+	
+	/**
+	 * if not implemented in app_model
+	 * 2011-07-22 ms
+	 */
+	public function validateIdentical(Model $Model, $data, $compareWith = null) {
+		if (is_array($data)) {
+			$value = array_shift($data);
+		} else {
+			$value = $data;
+		}
+		$compareValue = $Model->data[$Model->alias][$compareWith];
+		return ($compareValue === $value);
+	}
+	
+	/**
+	 * adding validation rules
+	 * 2011-07-22 ms
+	 */
+	public function setup(Model $Model, $config = array()) {
+		$this->settings[$Model->alias] = Set::merge($this->_defaultSettings, $config);
+		$formField = $this->settings[$Model->alias]['form_field'];
+		$formFieldRepeat = $this->settings[$Model->alias]['form_field_repeat'];
+		
+		# add the validation rules if not already attached
+		if (!isset($Model->validate[$formField])) {
+			$Model->validate[$formField] = $this->_validationRules[$formField];
+		}
+		if (!isset($Model->validate[$formFieldRepeat])) {
+			$Model->validate[$formFieldRepeat] = $this->_validationRules[$formFieldRepeat];
+			$Model->validate[$formFieldRepeat]['validateIdentical']['rule'][1] = $formField;			
+		}
+	}
+
+	/**
+	 * whitelisting
+	 * 2011-07-22 ms 
+	 */
+	function beforeValidate(Model $Model) {
+		# add fields to whitelist!
+		$whitelist = array($this->settings[$Model->alias]['form_field'], $this->settings[$Model->alias]['form_field_repeat']);
+		if ($this->settings[$Model->alias]['current']) {
+			$whitelist[] = $this->settings[$Model->alias]['form_field_current'];
+		}
+		if (!empty($Model->whitelist)) {
+			$Model->whitelist = am($Model->whitelist, $whitelist);
+		}
+		
+		return true;
+	}
+
+
+	/**
+	 * hashing the password now
+	 * 2011-07-22 ms 
+	 */
+	function beforeSave(Model $Model) {
+		$formField = $this->settings[$Model->alias]['form_field'];
+		$formFieldRepeat = $this->settings[$Model->alias]['form_field_repeat'];
+		
+		if (!empty($Model->data[$Model->alias][$formField])) {
+			$field = $this->settings[$Model->alias]['field']; 
+			$type = $this->settings[$Model->alias]['hashType'];
+			$salt = $this->settings[$Model->alias]['hashSalt'];
+			$Model->data[$Model->alias][$field] = Security::hash($Model->data[$Model->alias][$formField], $type, $salt);
+			unset($Model->data[$Model->alias][$formField]);
+			if ($this->settings[$Model->alias]['confirm']) {
+				unset($Model->data[$Model->alias][$formFieldRepeat]);
+			}
+			# update whitelist
+			if (!empty($Model->whitelist)) {
+				$Model->whitelist = am($Model->whitelist, array($field));
+			}
+		}
+
+		return true;
+	}
+
+	
+}