Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions api/src/main/resources/messages.properties
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,11 @@ adminui.noname=No Name
adminui.field.too.long=The value you entered is too long
adminui.field.exceeded.maxChars=A maximum of {0} character(s) is allowed
adminui.field.require.minChars=At least {0} character(s) are required
adminui.field.require.pattern.begin=This password must have:
adminui.field.require.pattern.reqUpperAndLowerCase=both upper and lowercase characters
adminui.field.require.pattern.reqDigit=at least one digit
adminui.field.require.pattern.reqNonDigit=at least one non digit
adminui.field.require.pattern.reqRegex=match this Regex pattern: {0}
adminui.retire=Retire {0}?
adminui.purge=Delete {0} Forever?
adminui.requiredField.label=required
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
/**
* This Source Code Form is subject to the terms of the Mozilla Public License,
* v. 2.0. If a copy of the MPL was not distributed with this file, You can
* obtain one at http://mozilla.org/MPL/2.0/. OpenMRS is also distributed under
* the terms of the Healthcare Disclaimer located at http://openmrs.org/license.
*
* Copyright (C) OpenMRS Inc. OpenMRS is a registered trademark and the OpenMRS
* graphic logo is a trademark of OpenMRS Inc.
*/
package org.openmrs.module.adminui.page.controller;

import org.apache.commons.lang.StringUtils;
import org.openmrs.api.AdministrationService;
import org.openmrs.api.context.Context;
import org.openmrs.messagesource.MessageSourceService;
import org.openmrs.ui.framework.page.PageModel;
import org.openmrs.util.OpenmrsConstants;

public final class PasswordValidation {
private PasswordValidation() {

}

public static void addPasswordValidationAttributes(PageModel model, AdministrationService adminService, MessageSourceService mss) {
String passwordMinLength = adminService.getGlobalProperty(OpenmrsConstants.GP_PASSWORD_MINIMUM_LENGTH, "8");
boolean passwordReqUpperAndLowerCase = "true".equals(adminService.getGlobalProperty(OpenmrsConstants.GP_PASSWORD_REQUIRES_UPPER_AND_LOWER_CASE, "true"));
boolean passwordReqDigit = "true".equals(adminService.getGlobalProperty(OpenmrsConstants.GP_PASSWORD_REQUIRES_DIGIT, "true"));
boolean passwordReqNonDigit = "true".equals(adminService.getGlobalProperty(OpenmrsConstants.GP_PASSWORD_REQUIRES_NON_DIGIT, "true"));
String passwordReqRegex = adminService.getGlobalProperty(OpenmrsConstants.GP_PASSWORD_CUSTOM_REGEX, "");

String pattern = "";
String patternErrorMessage = "";

if (passwordReqUpperAndLowerCase || passwordReqDigit || passwordReqNonDigit || StringUtils.isNotEmpty(passwordReqRegex)) {
pattern += "/^";
patternErrorMessage += mss.getMessage("adminui.field.require.pattern.begin");
if (passwordReqUpperAndLowerCase) {
pattern += "(?=.*?[A-Z])(?=.*?[a-z])";
patternErrorMessage += ' ' + mss.getMessage("adminui.field.require.pattern.reqUpperAndLowerCase") + ',';
}
if (passwordReqDigit) {
pattern += "(?=.*\\d)";
patternErrorMessage += ' ' + mss.getMessage("adminui.field.require.pattern.reqDigit") + ',';
}
if (passwordReqNonDigit) {
pattern += "(?=.*[^\\d])";
patternErrorMessage += ' ' + mss.getMessage("adminui.field.require.pattern.reqNonDigit") + ',';
}
if (StringUtils.isNotEmpty(passwordReqRegex)) {
pattern += "(?=";
pattern += passwordReqRegex;
pattern += ')';
patternErrorMessage += ' ' + mss.getMessage("adminui.field.require.pattern.reqRegex", new Object[]{passwordReqRegex}, Context.getLocale()) + ',';
}
pattern += "[\\w|\\W]*$/";
patternErrorMessage = patternErrorMessage.substring(0, patternErrorMessage.length() - 1);
}

model.addAttribute("passwordMinLength", passwordMinLength);
model.addAttribute("pattern", pattern);
model.addAttribute("patternErrorMessage", patternErrorMessage);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@
import org.openmrs.api.context.Context;
import org.openmrs.api.db.DAOException;
import org.openmrs.messagesource.MessageSourceService;
import org.openmrs.module.adminui.page.controller.PasswordValidation;
import org.openmrs.module.uicommons.UiCommonsConstants;
import org.openmrs.module.uicommons.util.InfoErrorMessageUtil;
import org.openmrs.ui.framework.annotation.SpringBean;
Expand All @@ -48,13 +49,14 @@ public String overridePostChangePassword() {
return "forward:/adminui/myaccount/changePassword.page";
}

public void get(PageModel model, @SpringBean("adminService") AdministrationService adminService) {
setModelAttributes(model, adminService);
public void get(PageModel model,
@SpringBean("adminService") AdministrationService adminService,
@SpringBean("messageSourceService") MessageSourceService mss) {
setModelAttributes(model, adminService, mss);
}

public void setModelAttributes(PageModel model, AdministrationService adminService) {
model.addAttribute("passwordMinLength",
adminService.getGlobalProperty(OpenmrsConstants.GP_PASSWORD_MINIMUM_LENGTH, "8"));
public void setModelAttributes(PageModel model, AdministrationService adminService, MessageSourceService mss) {
PasswordValidation.addPasswordValidationAttributes(model, adminService, mss);
}

public String post(PageModel model, @SpringBean("userService") UserService userService,
Expand All @@ -77,7 +79,7 @@ public String post(PageModel model, @SpringBean("userService") UserService userS
if (errorMessage == null) {
try {
OpenmrsUtil.validatePassword(user.getUsername(), newPassword, user.getSystemId());

String nextPage = "redirect:/index.htm";
try {
userService.changePassword(oldPassword, newPassword);
Expand Down Expand Up @@ -132,7 +134,7 @@ public String post(PageModel model, @SpringBean("userService") UserService userS

request.getSession().setAttribute(UiCommonsConstants.SESSION_ATTRIBUTE_ERROR_MESSAGE, errorMessage);

setModelAttributes(model, adminService);
setModelAttributes(model, adminService, mss);

return "myaccount/changePassword";
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@
import org.openmrs.module.adminui.account.Account;
import org.openmrs.module.adminui.account.AccountService;
import org.openmrs.module.adminui.account.AdminUiAccountValidator;
import org.openmrs.module.adminui.page.controller.PasswordValidation;
import org.openmrs.module.appframework.domain.Extension;
import org.openmrs.module.appframework.service.AppFrameworkService;
import org.openmrs.module.providermanagement.Provider;
Expand Down Expand Up @@ -88,12 +89,13 @@ public Account getAccount(@RequestParam(value = "personId", required = false) Pe
public void get(PageModel model, @MethodParam("getAccount") Account account,
@SpringBean("adminAccountService") AccountService accountService,
@SpringBean("adminService") AdministrationService administrationService,
@SpringBean("messageSourceService") MessageSourceService mss,
@SpringBean("providerManagementService") ProviderManagementService providerManagementService,
UiUtils uu,
@SpringBean("appFrameworkService") AppFrameworkService appFrameworkService)
throws IOException {

setModelAttributes(model, account, null, accountService, administrationService, providerManagementService, uu, appFrameworkService);
setModelAttributes(model, account, null, accountService, administrationService, mss, providerManagementService, uu, appFrameworkService);
if (account.getPerson().getPersonId() == null) {
setJsonFormData(model, account, null);
}
Expand All @@ -115,6 +117,7 @@ public String post(PageModel model, @MethodParam("getAccount") @BindParams Accou
@SpringBean("messageSourceService") MessageSourceService messageSourceService,
@SpringBean("adminAccountService") AccountService accountService,
@SpringBean("adminService") AdministrationService administrationService,
@SpringBean("messageSourceService") MessageSourceService mss,
@SpringBean("adminUiAccountValidator") AdminUiAccountValidator accountValidator,
@SpringBean("providerManagementService") ProviderManagementService providerManagementService,
@SpringBean("appFrameworkService") AppFrameworkService appFrameworkService,
Expand Down Expand Up @@ -211,7 +214,7 @@ public String post(PageModel model, @MethodParam("getAccount") @BindParams Accou
}
}

setModelAttributes(model, account, otherAccountData, accountService, administrationService,
setModelAttributes(model, account, otherAccountData, accountService, administrationService, mss,
providerManagementService, uu, appFrameworkService);

sendErrorMessage(errors, model, messageSourceService, request);
Expand All @@ -226,8 +229,8 @@ public String post(PageModel model, @MethodParam("getAccount") @BindParams Accou

public void setModelAttributes(PageModel model, Account account, OtherAccountData otherAccountData,
AccountService accountService, AdministrationService administrationService,
ProviderManagementService providerManagementService, UiUtils uu,
AppFrameworkService appFrameworkService) throws IOException {
MessageSourceService mss, ProviderManagementService providerManagementService,
UiUtils uu, AppFrameworkService appFrameworkService) throws IOException {

model.addAttribute("account", account);
Boolean forcePasswordChange = null;
Expand Down Expand Up @@ -284,8 +287,7 @@ public void setModelAttributes(PageModel model, Account account, OtherAccountDat
propertyMaxLengthMap.put("username", administrationService.getMaximumPropertyLength(User.class, "username"));
propertyMaxLengthMap.put("password", administrationService.getMaximumPropertyLength(User.class, "password"));
model.addAttribute("propertyMaxLengthMap", propertyMaxLengthMap);
model.addAttribute("passwordMinLength",
administrationService.getGlobalProperty(OpenmrsConstants.GP_PASSWORD_MINIMUM_LENGTH, "8"));
PasswordValidation.addPasswordValidationAttributes(model, administrationService, mss);

ObjectMapper mapper = new ObjectMapper();
SimpleObject so = new SimpleObject();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,10 @@
passwordAttributes[requiredAttribute] = requiredAttributeValue;
}

if (pattern) {
passwordAttributes.put("ng-pattern", pattern);
}

def otherPasswordAttributes= ["ng-model": "uuidUserMap['"+userUuid+"'].password"]
otherPasswordAttributes.putAll(passwordAttributes)
%>
Expand Down Expand Up @@ -104,8 +108,13 @@
${ui.message("adminui.field.required")}
</span>
<span ng-show="${formName}['password${userUuid}'].\$error.minlength">
${ui.message("adminui.field.require.minChars", passwordMinLength)}
${ui.message("adminui.field.require.minChars", passwordMinLength)}<br>
</span>
<% if (pattern) { %>
<span ng-show="${formName}['password${userUuid}'].\$error.pattern">
${patternErrorMessage}
</span>
<% } %>
</span>
</td>
<td valign="top">
Expand Down Expand Up @@ -159,4 +168,4 @@
</tr>
<% } %>
<% } %>
</table>
</table>
14 changes: 12 additions & 2 deletions omod/src/main/webapp/pages/myaccount/changePassword.gsp
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,11 @@

ui.includeCss("adminui", "adminui.css")

def passwordAttributes = ["ng-model": "newPassword", required:"", "ng-minlength": passwordMinLength]

if (pattern) {
passwordAttributes.put("ng-pattern", pattern)
}
%>

<script type="text/javascript">
Expand Down Expand Up @@ -45,16 +50,21 @@
id: "newPassword",
label: ui.message("adminui.account.newPassword")+"<span class='adminui-text-red'>*</span>",
formFieldName: "newPassword",
otherAttributes: ["ng-model": "newPassword", required:"", "ng-minlength": passwordMinLength]
otherAttributes: passwordAttributes
]) }
<span class="field-error" ng-show="changePasswordForm.newPassword.\$dirty
&& changePasswordForm.newPassword.\$invalid">
<span ng-show="changePasswordForm.newPassword.\$error.required">
${ui.message("adminui.field.required")}
</span>
<span ng-show="changePasswordForm.newPassword.\$error.minlength">
${ui.message("adminui.field.require.minChars", passwordMinLength)}
${ui.message("adminui.field.require.minChars", passwordMinLength)}<br>
</span>
<% if (pattern) { %>
<span ng-show="changePasswordForm.newPassword.\$error.pattern">
${patternErrorMessage}
</span>
<% } %>
</span>

${ ui.includeFragment("uicommons", "field/passwordField", [
Expand Down