Author: jleroux Date: Sun Dec 9 14:59:52 2012 New Revision: 1418996 URL: http://svn.apache.org/viewvc?rev=1418996&view=rev Log: A slightly modified patch from Sumit Pandit for "Additional Validation for Password : Make password pattern driven" https://issues.apache.org/jira/browse/OFBIZ-4958
Provides an additional validation for password with following capability to the system: Admin can enable/disable pattern based password capability of system. Configuration will reside in security.property file. To enable : security.login.password.pattern.enable=true To disable: security.login.password.pattern.enable=false Admin is flexible to provide his pattern string by making pattern more/less restrictive as per system requirement. Configuration will reside in security.property file. Example: security.login.password.pattern=^.*(?=. {5,})(?=.[a-zA-Z])(?=.[!@#$%^&*]).*$ Admin can provide custom error message string which will display to end user if wrong password is entered. Configuration will reside in security.properity file. jleroux: I quickly handled the error message localisation for the OOTB case. It's more complicated when the pattern gets complex... Modified: ofbiz/trunk/framework/common/config/SecurityextUiLabels.xml ofbiz/trunk/framework/common/src/org/ofbiz/common/login/LoginServices.java ofbiz/trunk/framework/security/config/security.properties Modified: ofbiz/trunk/framework/common/config/SecurityextUiLabels.xml URL: http://svn.apache.org/viewvc/ofbiz/trunk/framework/common/config/SecurityextUiLabels.xml?rev=1418996&r1=1418995&r2=1418996&view=diff ============================================================================== --- ofbiz/trunk/framework/common/config/SecurityextUiLabels.xml (original) +++ ofbiz/trunk/framework/common/config/SecurityextUiLabels.xml Sun Dec 9 14:59:52 2012 @@ -752,6 +752,13 @@ <value xml:lang="en">Password Reminder (${userLoginId})".</value> <value xml:lang="fr">Rappel du mot de passe (${userLoginId})".</value> </property> + <property key="loginservices.password.pattern.errmsg"> + <value xml:lang="ar">ÙÙÙ Ø© Ø§ÙØ³Ø± ÙÙØ³Øª Ù Ø·Ø§Ø¨ÙØ© ÙÙÙÙ Ø·Ø ÙØ±Ø¬Ù Ø§ÙØ±Ø¬Ùع اÙÙÙ Ø· Ø§ÙØªØ§ÙÙ: ${passwordPatternMessage}</value> + <value xml:lang="en">The password does not match the pattern: ${passwordPatternMessage} </value> + <value xml:lang="fr">Le mot de passe ne correspond pas au modèle: ${passwordPatternMessage}.</value> + <value xml:lang="hi_IN">पासवरà¥à¤¡ पà¥à¤à¤°à¥à¤¨ मिलान नहà¥à¤ हà¥, à¤à¥à¤ªà¤¯à¤¾ निमà¥à¤¨à¤²à¤¿à¤à¤¿à¤¤ पà¥à¤à¤°à¥à¤¨ दà¥à¤à¥à¤: ${passwordPatternMessage}</value> + <value xml:lang="it">La password non è corrispondente al modello, fare riferimento seguente schema: ${passwordPatternMessage}.</value> + </property> <property key="loginservices.since_datetime"> <value xml:lang="de">(seit ${disabledDateTime})</value> <value xml:lang="en">since ${disabledDateTime}.</value> Modified: ofbiz/trunk/framework/common/src/org/ofbiz/common/login/LoginServices.java URL: http://svn.apache.org/viewvc/ofbiz/trunk/framework/common/src/org/ofbiz/common/login/LoginServices.java?rev=1418996&r1=1418995&r2=1418996&view=diff ============================================================================== --- ofbiz/trunk/framework/common/src/org/ofbiz/common/login/LoginServices.java (original) +++ ofbiz/trunk/framework/common/src/org/ofbiz/common/login/LoginServices.java Sun Dec 9 14:59:52 2012 @@ -23,6 +23,8 @@ import java.sql.Timestamp; import java.util.List; import java.util.Locale; import java.util.Map; +import java.util.regex.Matcher; +import java.util.regex.Pattern; import javax.transaction.Transaction; @@ -62,6 +64,8 @@ public class LoginServices { public static final String module = LoginServices.class.getName(); public static final String resource = "SecurityextUiLabels"; + public static boolean usePasswordPattern = "true".equals(UtilProperties.getPropertyValue("security.properties", "security.login.password.pattern.enable")); + public static String passwordPattern = UtilProperties.getPropertyValue("security.properties", "security.login.password.pattern"); /** Login service to authenticate username and password * @return Map of results including (userLogin) GenericValue object @@ -954,10 +958,27 @@ public class LoginServices { } if (newPassword != null) { - if (!(newPassword.length() >= minPasswordLength)) { - Map<String, String> messageMap = UtilMisc.toMap("minPasswordLength", Integer.toString(minPasswordLength)); - errMsg = UtilProperties.getMessage(resource,"loginservices.password_must_be_least_characters_long", messageMap, locale); - errorMessageList.add(errMsg); + // Matching password with pattern + if (usePasswordPattern) { + Pattern pattern = Pattern.compile(passwordPattern); + Matcher matcher = pattern.matcher(newPassword); + boolean matched = matcher.matches(); + if (!matched) { + // This is a mix to handle the OOTB pattern which is only a fixed length + Map<String, String> messageMap = UtilMisc.toMap("minPasswordLength", Integer.toString(minPasswordLength)); + String passwordPatternMessage = UtilProperties.getPropertyValue("security.properties", + "security.login.password.pattern.description", "loginservices.password_must_be_least_characters_long"); + errMsg = UtilProperties.getMessage(resource, passwordPatternMessage, messageMap, locale); + messageMap = UtilMisc.toMap("passwordPatternMessage", errMsg); + errMsg = UtilProperties.getMessage(resource,"loginservices.password.pattern.errmsg", messageMap, locale); + errorMessageList.add(errMsg); + } + } else { + if (!(newPassword.length() >= minPasswordLength)) { + Map<String, String> messageMap = UtilMisc.toMap("minPasswordLength", Integer.toString(minPasswordLength)); + errMsg = UtilProperties.getMessage(resource,"loginservices.password_must_be_least_characters_long", messageMap, locale); + errorMessageList.add(errMsg); + } } if (userLogin != null && newPassword.equalsIgnoreCase(userLogin.getString("userLoginId"))) { errMsg = UtilProperties.getMessage(resource,"loginservices.password_may_not_equal_username", locale); Modified: ofbiz/trunk/framework/security/config/security.properties URL: http://svn.apache.org/viewvc/ofbiz/trunk/framework/security/config/security.properties?rev=1418996&r1=1418995&r2=1418996&view=diff ============================================================================== --- ofbiz/trunk/framework/security/config/security.properties (original) +++ ofbiz/trunk/framework/security/config/security.properties Sun Dec 9 14:59:52 2012 @@ -26,6 +26,33 @@ security.context=default # -- define the password restrictions -- password.length.min=5 +### -- pattern based password OFBIZ-4958 +security.login.password.pattern.enable=true +security.login.password.pattern=^.*(?=.{5,}).*$ +# This is a mix to handle the localisation of the OOTB pattern which is only a fixed length +security.login.password.pattern.description=loginservices.password_must_be_least_characters_long +# -- For More restrictive pattern you can use the following, no localisation- +#security.login.password.pattern=^.*(?=.{5,})(?=.*[a-zA-Z])(?=.*[!@#$%^&*]).*$ +#security.login.password.pattern.description=Your password must be 5 characters long, Only contains alphanumeric(number optional) and at least one from following special characters: !@#$%^&*. +# Only contains alphanumeric and the following special characters: !@#$%^&* +# Contains at least 1 of the special characters in the list above +# The required special character can appear anywhere in the string (for example: !abc, a!bc, abc!) +# minimum length 5 digit. +# HELP +# Start of group +# ( +# (?=.*\d) # must contains one digit from 0-9 +# (?=.*[a-z]) # must contains one lowercase characters +# (?=.*[A-Z]) # must contains one uppercase characters +# (?=.*[!@#$%^&*]) # must contains one special symbols in the list "!@#$%^&*" +# . # match anything with previous condition checking +# {5,20} # length at least 5 characters and maximum of 20 +# {5,} # minimum length 5 chars and no linitation to max length. +# ) +# End of group +# For further password patterns look at +# http://docs.oracle.com/javase/1.4.2/docs/api/java/util/regex/Pattern.html#sum + # -- disable the account after this many logins -- max.failed.logins=3