From 662bd53e917b0ad8166df587627bf654989014b5 Mon Sep 17 00:00:00 2001 From: Roland Gruber Date: Sun, 25 May 2014 17:29:19 +0000 Subject: [PATCH] added graphical hint if password does not match policy --- lam/HISTORY | 1 + lam/lib/html.inc | 19 ++++++++++- lam/lib/modules.inc | 2 +- lam/lib/modules/posixAccount.inc | 2 +- lam/lib/modules/sambaSamAccount.inc | 2 +- lam/lib/modules/windowsUser.inc | 2 +- lam/templates/lib/500_lam.js | 50 +++++++++++++++++++++++++++-- lam/templates/misc/ajax.php | 18 +++++++++-- 8 files changed, 87 insertions(+), 9 deletions(-) diff --git a/lam/HISTORY b/lam/HISTORY index c4f16804..03b3ae9b 100644 --- a/lam/HISTORY +++ b/lam/HISTORY @@ -2,6 +2,7 @@ June 2014 4.6 - Unix groups: allow to disable membership management - Extended LAM's internal password policies - Lamdaemon: move home directory on server if changed + - Password policy check during typing - LAM Pro: -> Password self reset and user self registration support to set a header text -> Sudo roles: support latest schema diff --git a/lam/lib/html.inc b/lam/lib/html.inc index c60403e3..19849bf1 100644 --- a/lam/lib/html.inc +++ b/lam/lib/html.inc @@ -420,6 +420,8 @@ class htmlInputField extends htmlElement { protected $onKeyPress = null; /** password field */ protected $isPassword = false; + /** check password strength */ + protected $checkPasswordStrength = false; /** enabled or disabled */ protected $isEnabled = true; /** indicates that the value should be saved in obfuscated form */ @@ -588,6 +590,19 @@ class htmlInputField extends htmlElement { '; } + if ($this->checkPasswordStrength) { + $ajaxPath = "../templates/misc/ajax.php"; + if (is_file("../../templates/misc/ajax.php")) { + $ajaxPath = "../../templates/misc/ajax.php"; + } + elseif (is_file("../../../templates/misc/ajax.php")) { + $ajaxPath = "../../../templates/misc/ajax.php"; + } + echo ' + '; + } if ($this->transient) { return array(); } @@ -621,9 +636,11 @@ class htmlInputField extends htmlElement { * Specifies if this is a password field. * * @param boolean $isPassword password field + * @param boolean $checkStrength check if matches password policy (default: false) */ - public function setIsPassword($isPassword) { + public function setIsPassword($isPassword, $checkStrength = false) { $this->isPassword = $isPassword; + $this->checkPasswordStrength = $checkStrength; } /** diff --git a/lam/lib/modules.inc b/lam/lib/modules.inc index 598601a0..50d298e9 100644 --- a/lam/lib/modules.inc +++ b/lam/lib/modules.inc @@ -1042,7 +1042,7 @@ class accountContainer { // password fields $container->addElement(new htmlOutputText(_('Password'))); $pwdInput1 = new htmlInputField('newPassword1'); - $pwdInput1->setIsPassword(true); + $pwdInput1->setIsPassword(true, true); $container->addElement($pwdInput1); $container->addElement(new htmlHelpLink('404'), true); $container->addElement(new htmlOutputText(_('Repeat password'))); diff --git a/lam/lib/modules/posixAccount.inc b/lam/lib/modules/posixAccount.inc index f25ea901..df991c19 100644 --- a/lam/lib/modules/posixAccount.inc +++ b/lam/lib/modules/posixAccount.inc @@ -2528,7 +2528,7 @@ class posixAccount extends baseModule implements passwordService { $pwdTable = new htmlTable(); $pwdTable->colspan = 3; $pwd1 = new htmlTableExtendedInputField($this->getSelfServiceLabel('password', _('New password')), 'posixAccount_password'); - $pwd1->setIsPassword(true); + $pwd1->setIsPassword(true, true); $pwdTable->addElement($pwd1, true); $pwd2 = new htmlTableExtendedInputField(_('Reenter password'), 'posixAccount_password2'); $pwd2->setIsPassword(true); diff --git a/lam/lib/modules/sambaSamAccount.inc b/lam/lib/modules/sambaSamAccount.inc index c90a3368..7968bb6a 100644 --- a/lam/lib/modules/sambaSamAccount.inc +++ b/lam/lib/modules/sambaSamAccount.inc @@ -2263,7 +2263,7 @@ class sambaSamAccount extends baseModule implements passwordService { $pwdTable = new htmlTable(); $pwdTable->colspan = 3; $pwd1 = new htmlTableExtendedInputField($this->getSelfServiceLabel('password', _('New password')), 'sambaSamAccount_password'); - $pwd1->setIsPassword(true); + $pwd1->setIsPassword(true, true); $pwdTable->addElement($pwd1, true); $pwd2 = new htmlTableExtendedInputField(_('Reenter password'), 'sambaSamAccount_password2'); $pwd2->setIsPassword(true); diff --git a/lam/lib/modules/windowsUser.inc b/lam/lib/modules/windowsUser.inc index a51f84fa..96f8fdfc 100644 --- a/lam/lib/modules/windowsUser.inc +++ b/lam/lib/modules/windowsUser.inc @@ -1709,7 +1709,7 @@ class windowsUser extends baseModule implements passwordService { $pwdTable = new htmlTable(); $pwdTable->colspan = 3; $pwd1 = new htmlTableExtendedInputField($this->getSelfServiceLabel('unicodePwd', _('New password')), 'windowsUser_unicodePwd'); - $pwd1->setIsPassword(true); + $pwd1->setIsPassword(true, true); $pwdTable->addElement($pwd1, true); $pwd2 = new htmlTableExtendedInputField(_('Reenter password'), 'windowsUser_unicodePwd2'); $pwd2->setIsPassword(true); diff --git a/lam/templates/lib/500_lam.js b/lam/templates/lib/500_lam.js index 8461fc3a..18fb637d 100644 --- a/lam/templates/lib/500_lam.js +++ b/lam/templates/lib/500_lam.js @@ -523,6 +523,52 @@ function checkFieldsHaveSameValues(fieldID, fieldIDReference) { } } } - jQuery(field).keyup(check); - jQuery(fieldRef).keyup(check); + jQuery(field).keyup(check); + jQuery(fieldRef).keyup(check); } + +/** + * Checks if the value of the given password field matches LAM's password policy. + * Field is marked red if fail and green if ok. + * + * @param fieldID ID of field to check + */ +function checkPasswordStrength(fieldID, ajaxURL) { + var field = jQuery('#' + fieldID); + var check = + function() { + var value = field.val(); + var pwdJSON = { + "password": value + }; + // make AJAX call + jQuery.post(ajaxURL + "?function=passwordStrengthCheck", {jsonInput: pwdJSON}, function(data) {checkPasswordStrengthHandleReply(data, fieldID);}, 'json'); + }; + jQuery(field).keyup(check); +} + +/** + * Manages the server reply to a password strength check request. + * + * @param data JSON reply + * @param fieldID input field ID + */ +function checkPasswordStrengthHandleReply(data, fieldID) { + var field = jQuery('#' + fieldID); + if (data.result == true) { + field.removeClass('markFail'); + field.addClass('markOk'); + field.prop('title', ''); + } + else if (field.val() == '') { + field.removeClass('markFail'); + field.removeClass('markOk'); + } + else { + field.addClass('markFail'); + field.removeClass('markOk'); + field.prop('title', data.result); + } +} + + diff --git a/lam/templates/misc/ajax.php b/lam/templates/misc/ajax.php index 7f4790cf..bd19ee0b 100644 --- a/lam/templates/misc/ajax.php +++ b/lam/templates/misc/ajax.php @@ -3,7 +3,7 @@ $Id$ This code is part of LDAP Account Manager (http://www.ldap-account-manager.org/) - Copyright (C) 2011 - 2013 Roland Gruber + Copyright (C) 2011 - 2014 Roland Gruber This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -38,7 +38,7 @@ if (isset($_GET['selfservice'])) { } // return standard JSON response if session expired -if (startSecureSession(false) === false) { +if (startSecureSession(false, true) === false) { echo json_encode(array( 'sessionExpired' => "true" )); @@ -81,6 +81,9 @@ class lamAjax { if ($function == 'passwordChange') { lamAjax::managePasswordChange($jsonInput); } + elseif ($function == 'passwordStrengthCheck') { + lamAjax::checkPasswordStrength($jsonInput); + } } /** @@ -93,6 +96,17 @@ class lamAjax { echo json_encode($return); } + /** + * Checks if a password is accepted by LAM's password policy. + * + * @param array $input input parameters + */ + public static function checkPasswordStrength($input) { + $password = $input['password']; + $result = checkPasswordStrength($password, null, null); + echo json_encode(array("result" => $result)); + } + }