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
 


Reply via email to