|
Author: jleroux
Date: Sat Apr 6 04:54:14 2013 New Revision: 1465185 URL: http://svn.apache.org/r1465185 Log: A slightly modified patch from Sumit Pandit for "Enforce user to reset his password in a pre-defined regular interval of time." https://issues.apache.org/jira/browse/OFBIZ-5009 Reference requirement for the feature: http://markmail.org/message/sihxekwk6655t5gh#query:+page:1+mid:bcw2vva2hjxhsodq+state:results For a user account in system, we can set password age for an additional security. Proposed system will start suggesting to user to reset his password few days before password expiration. Then Once password expired, system will enforce him to reset his password before processing further. Following will be control points and would be part of system configuration- * *Control Points -* ** Admin can enable/disable the reset password functionality. *** -It will control by a flag in propriety file where admin can enable/disable it by setting true/false. ** Number of days in which password will expired. *** - It will defined in propriety file so that admin can control it. ** Number of days before when password expiration alert display at user's screen. *** - It will defined in propriety file so that admin can control it. * *How should it processed -* ** After user logged-in, display password expiration notification message to user if his password will expire in comming days. ** After user logged-in, display change password screen, when password is expired. i.e. The difference in days since last time password updated is exceed to number of days specified in system policies. Enforce user to reset his password. * *What will be the out-put -* ** Password is about to expire : : alert message after login. ** Password is expired : Password-Expired-Alert : alert message with reset password screen. Following is implementation plan - security.properties : Provide configuration for following control points : Enabling / Disabling of the functionality. Maximum number of days within user has to change the password. Number of days back to password expire date, when user start getting password expiration alerts. Data model Entity name : UserLoginPasswordHistory : Existing entity. Business logic Create UserLoginPasswordHistory record when a new user is created (if configured). Expire and then Create UserLoginPasswordHistory record when user update existing password. Everytime, when user login check for password expiration. If password expired then display change password screen to user. And if password not yet expired but it is close to expire display alert message to user about its expiration. jleroux: I just changed from if (reqToChangePwdInDays != 0) { tp if (reqToChangePwdInDays > 0) { Modified: ofbiz/trunk/applications/party/script/org/ofbiz/party/user/UserEvents.xml ofbiz/trunk/framework/common/config/SecurityextUiLabels.xml ofbiz/trunk/framework/common/src/org/ofbiz/common/login/LoginServices.java ofbiz/trunk/framework/webapp/src/org/ofbiz/webapp/control/LoginWorker.java Modified: ofbiz/trunk/applications/party/script/org/ofbiz/party/user/UserEvents.xml URL: http://svn.apache.org/viewvc/ofbiz/trunk/applications/party/script/org/ofbiz/party/user/UserEvents.xml?rev=1465185&r1=1465184&r2=1465185&view=diff ============================================================================== --- ofbiz/trunk/applications/party/script/org/ofbiz/party/user/UserEvents.xml (original) +++ ofbiz/trunk/applications/party/script/org/ofbiz/party/user/UserEvents.xml Sat Apr 6 04:54:14 2013 @@ -320,6 +320,20 @@ under the License. <set field="newUserLogin.partyId" from-field="tempMap.partyId"/> <create-value value-field="newUserLogin"/> <set-current-user-login value-field="newUserLogin"/> + + <!-- On successful user creation, create password history record if configured --> + <set field="delegator" from-field="parameters.delegator" type="Object"/> + <call-class-method method-name="getPropertyValue" class-name="org.ofbiz.base.util.UtilProperties" ret-field="autoPasswordChangeEnabled"> + <string value="security"/> + <string value="user.auto.change.password.enable"/> + </call-class-method> + <if-compare-field field="autoPasswordChangeEnabled" operator="equals" to-field="true"> + <call-class-method method-name="createUserLoginPasswordHistory" class-name="org.ofbiz.common.login.LoginServices"> + <field field="delegator" type="org.ofbiz.entity.Delegator"/> + <string value="${newUserLogin.userLoginId}"/> + <string value="${newUserLogin.currentPassword}"/> + </call-class-method> + </if-compare-field> </if-not-empty> <create-value value-field="partyDataSource"/> Modified: ofbiz/trunk/framework/common/config/SecurityextUiLabels.xml URL: http://svn.apache.org/viewvc/ofbiz/trunk/framework/common/config/SecurityextUiLabels.xml?rev=1465185&r1=1465184&r2=1465185&view=diff ============================================================================== --- ofbiz/trunk/framework/common/config/SecurityextUiLabels.xml (original) +++ ofbiz/trunk/framework/common/config/SecurityextUiLabels.xml Sat Apr 6 04:54:14 2013 @@ -166,6 +166,12 @@ <value xml:lang="zh">没æè®¾ç½®çµåé®ä»¶å°åï¼è¯·ä¸å®¢æ·æå¡èç³»ã</value> <value xml:lang="zh_TW">ç¡é»åéµä»¶, è«è客æé£çµ¡ã</value> </property> + <property key="loginevents.password_expiration_alert"> + <value xml:lang="en">Alert : Your password will expire on ${passwordExpirationDate}. Update password before it expired.</value> + </property> + <property key="loginevents.password_expired_message"> + <value xml:lang="en">Alert : Your password expired on ${passwordExpirationDate}. Update your password.</value> + </property> <property key="loginevents.password_hint_is"> <value xml:lang="de">Der Passwort-Hinweis ist: ${passwordHint}.</value> <value xml:lang="en">The Password Hint is: ${passwordHint}.</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=1465185&r1=1465184&r2=1465185&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 Sat Apr 6 04:54:14 2013 @@ -422,7 +422,7 @@ public class LoginServices { return result; } - private static void createUserLoginPasswordHistory(Delegator delegator,String userLoginId, String currentPassword) throws GenericEntityException{ + public static void createUserLoginPasswordHistory(Delegator delegator,String userLoginId, String currentPassword) throws GenericEntityException{ int passwordChangeHistoryLimit = 0; try { passwordChangeHistoryLimit = Integer.parseInt(UtilProperties.getPropertyValue("security.properties", "password.change.history.limit", "0")); Modified: ofbiz/trunk/framework/webapp/src/org/ofbiz/webapp/control/LoginWorker.java URL: http://svn.apache.org/viewvc/ofbiz/trunk/framework/webapp/src/org/ofbiz/webapp/control/LoginWorker.java?rev=1465185&r1=1465184&r2=1465185&view=diff ============================================================================== --- ofbiz/trunk/framework/webapp/src/org/ofbiz/webapp/control/LoginWorker.java (original) +++ ofbiz/trunk/framework/webapp/src/org/ofbiz/webapp/control/LoginWorker.java Sat Apr 6 04:54:14 2013 @@ -22,6 +22,7 @@ import static org.ofbiz.base.util.UtilGe import java.math.BigInteger; import java.security.cert.X509Certificate; +import java.sql.Timestamp; import java.util.List; import java.util.Map; import java.util.regex.Matcher; @@ -44,6 +45,7 @@ import org.ofbiz.base.util.GeneralExcept import org.ofbiz.base.util.KeyStoreUtil; import org.ofbiz.base.util.StringUtil; import org.ofbiz.base.util.StringUtil.StringWrapper; +import org.ofbiz.base.util.UtilDateTime; import org.ofbiz.base.util.UtilFormatOut; import org.ofbiz.base.util.UtilHttp; import org.ofbiz.base.util.UtilMisc; @@ -60,6 +62,7 @@ import org.ofbiz.entity.model.ModelEntit import org.ofbiz.entity.serialize.XmlSerializer; import org.ofbiz.entity.transaction.GenericTransactionException; import org.ofbiz.entity.transaction.TransactionUtil; +import org.ofbiz.entity.util.EntityUtil; import org.ofbiz.security.Security; import org.ofbiz.security.SecurityConfigurationException; import org.ofbiz.security.SecurityFactory; @@ -451,6 +454,12 @@ public class LoginWorker { if (userLogin != null && "Y".equals(userLogin.getString("requirePasswordChange"))) { return "requirePasswordChange"; } + String autoChangePassword = UtilProperties.getPropertyValue("security.properties", "user.auto.change.password.enable", "false"); + if ("true".equalsIgnoreCase(autoChangePassword)) { + if ("requirePasswordChange".equals(autoChangePassword(request, response))) { + return "requirePasswordChange"; + } + } // check on JavaScriptEnabled String javaScriptEnabled = "N"; @@ -1033,4 +1042,40 @@ public class LoginWorker { return "XMLHttpRequest".equals(request.getHeader("X-Requested-With")); } + public static String autoChangePassword(HttpServletRequest request, HttpServletResponse response) { + Delegator delegator = (Delegator) request.getAttribute("delegator"); + String userName = request.getParameter("USERNAME"); + Timestamp now = UtilDateTime.nowTimestamp(); + Integer reqToChangePwdInDays = Integer.valueOf(UtilProperties.getPropertyValue("security.properties", "user.change.password.days", "0")); + Integer passwordNoticePeriod = Integer.valueOf(UtilProperties.getPropertyValue("security.properties", "user.change.password.notification.days", "0")); + if (reqToChangePwdInDays > 0) { + List<GenericValue> passwordHistories = null; + try { + passwordHistories = delegator.findByAnd("UserLoginPasswordHistory", UtilMisc.toMap("userLoginId", userName)); + } catch (GenericEntityException e) { + Debug.logError(e, "Cannot get user's password history record: " + e.getMessage(), module); + } + if (UtilValidate.isNotEmpty(passwordHistories)) { + GenericValue passwordHistory = EntityUtil.getFirst(EntityUtil.filterByDate(passwordHistories)); + Timestamp passwordCreationDate = passwordHistory.getTimestamp("fromDate"); + Integer passwordValidDays = reqToChangePwdInDays - passwordNoticePeriod; // Notification starts after days. + Timestamp startNotificationFromDate = UtilDateTime.addDaysToTimestamp(passwordCreationDate, passwordValidDays); + Timestamp passwordExpirationDate = UtilDateTime.addDaysToTimestamp(passwordCreationDate, reqToChangePwdInDays); + if (now.after(startNotificationFromDate)) { + if (now.after(passwordExpirationDate)) { + Map<String, String> messageMap = UtilMisc.toMap("passwordExpirationDate", passwordExpirationDate.toString()); + String errMsg = UtilProperties.getMessage(resourceWebapp, "loginevents.password_expired_message", messageMap, UtilHttp.getLocale(request)); + request.setAttribute("_EVENT_MESSAGE_", errMsg); + return "requirePasswordChange"; + } else { + Map<String, String> messageMap = UtilMisc.toMap("passwordExpirationDate", passwordExpirationDate.toString()); + String errMsg = UtilProperties.getMessage(resourceWebapp, "loginevents.password_expiration_alert", messageMap, UtilHttp.getLocale(request)); + request.setAttribute("_EVENT_MESSAGE_", errMsg); + return "success"; + } + } + } + } + return "success"; + } } |
| Free forum by Nabble | Edit this page |
