Search in sources :

Example 1 with ShortPasswordException

use of org.openmrs.api.ShortPasswordException in project openmrs-core by openmrs.

the class OpenmrsUtil method validatePassword.

/**
 * Utility to check the validity of a password for a certain {@link User}. Passwords must be
 * non-null. Their required strength is configured via global properties:
 * <table summary="Configuration props">
 * <tr>
 * <th>Description</th>
 * <th>Property</th>
 * <th>Default Value</th>
 * </tr>
 * <tr>
 * <th>Require that it not match the {@link User}'s username or system id
 * <th>{@link OpenmrsConstants#GP_PASSWORD_CANNOT_MATCH_USERNAME_OR_SYSTEMID}</th>
 * <th>true</th>
 * </tr>
 * <tr>
 * <th>Require a minimum length
 * <th>{@link OpenmrsConstants#GP_PASSWORD_MINIMUM_LENGTH}</th>
 * <th>8</th>
 * </tr>
 * <tr>
 * <th>Require both an upper and lower case character
 * <th>{@link OpenmrsConstants#GP_PASSWORD_REQUIRES_UPPER_AND_LOWER_CASE}</th>
 * <th>true</th>
 * </tr>
 * <tr>
 * <th>Require at least one numeric character
 * <th>{@link OpenmrsConstants#GP_PASSWORD_REQUIRES_DIGIT}</th>
 * <th>true</th>
 * </tr>
 * <tr>
 * <th>Require at least one non-numeric character
 * <th>{@link OpenmrsConstants#GP_PASSWORD_REQUIRES_NON_DIGIT}</th>
 * <th>true</th>
 * </tr>
 * <tr>
 * <th>Require a match on the specified regular expression
 * <th>{@link OpenmrsConstants#GP_PASSWORD_CUSTOM_REGEX}</th>
 * <th>null</th>
 * </tr>
 * </table>
 *
 * @param username user name of the user with password to validated
 * @param password string that will be validated
 * @param systemId system id of the user with password to be validated
 * @throws PasswordException
 * @since 1.5
 * @should fail with short password by default
 * @should fail with short password if not allowed
 * @should pass with short password if allowed
 * @should fail with digit only password by default
 * @should fail with digit only password if not allowed
 * @should pass with digit only password if allowed
 * @should fail with char only password by default
 * @should fail with char only password if not allowed
 * @should pass with char only password if allowed
 * @should fail without both upper and lower case password by default
 * @should fail without both upper and lower case password if not allowed
 * @should pass without both upper and lower case password if allowed
 * @should fail with password equals to user name by default
 * @should fail with password equals to user name if not allowed
 * @should pass with password equals to user name if allowed
 * @should fail with password equals to system id by default
 * @should fail with password equals to system id if not allowed
 * @should pass with password equals to system id if allowed
 * @should fail with password not matching configured regex
 * @should pass with password matching configured regex
 * @should allow password to contain non alphanumeric characters
 * @should allow password to contain white spaces
 * @should still work without an open session
 */
public static void validatePassword(String username, String password, String systemId) throws PasswordException {
    // default values for all of the global properties
    String userGp = "true";
    String lengthGp = "8";
    String caseGp = "true";
    String digitGp = "true";
    String nonDigitGp = "true";
    String regexGp = null;
    AdministrationService svc = null;
    try {
        svc = Context.getAdministrationService();
    } catch (APIException apiEx) {
        // if a service isn't available, fail quietly and just do the
        // defaults
        log.debug("Unable to get global properties", apiEx);
    }
    if (svc != null && Context.isSessionOpen()) {
        // (the session won't be open here to allow for the unit test to
        // fake not having the admin service available)
        userGp = svc.getGlobalProperty(OpenmrsConstants.GP_PASSWORD_CANNOT_MATCH_USERNAME_OR_SYSTEMID, userGp);
        lengthGp = svc.getGlobalProperty(OpenmrsConstants.GP_PASSWORD_MINIMUM_LENGTH, lengthGp);
        caseGp = svc.getGlobalProperty(OpenmrsConstants.GP_PASSWORD_REQUIRES_UPPER_AND_LOWER_CASE, caseGp);
        digitGp = svc.getGlobalProperty(OpenmrsConstants.GP_PASSWORD_REQUIRES_DIGIT, digitGp);
        nonDigitGp = svc.getGlobalProperty(OpenmrsConstants.GP_PASSWORD_REQUIRES_NON_DIGIT, nonDigitGp);
        regexGp = svc.getGlobalProperty(OpenmrsConstants.GP_PASSWORD_CUSTOM_REGEX, regexGp);
    }
    if (password == null) {
        throw new WeakPasswordException();
    }
    if ("true".equals(userGp) && (password.equals(username) || password.equals(systemId))) {
        throw new WeakPasswordException();
    }
    if (StringUtils.isNotEmpty(lengthGp)) {
        try {
            int minLength = Integer.parseInt(lengthGp);
            if (password.length() < minLength) {
                throw new ShortPasswordException(getMessage("error.password.length", lengthGp));
            }
        } catch (NumberFormatException nfe) {
            log.warn("Error in global property <" + OpenmrsConstants.GP_PASSWORD_MINIMUM_LENGTH + "> must be an Integer");
        }
    }
    if ("true".equals(caseGp) && !containsUpperAndLowerCase(password)) {
        throw new InvalidCharactersPasswordException(getMessage("error.password.requireMixedCase"));
    }
    if ("true".equals(digitGp) && !containsDigit(password)) {
        throw new InvalidCharactersPasswordException(getMessage("error.password.requireNumber"));
    }
    if ("true".equals(nonDigitGp) && containsOnlyDigits(password)) {
        throw new InvalidCharactersPasswordException(getMessage("error.password.requireLetter"));
    }
    if (StringUtils.isNotEmpty(regexGp)) {
        try {
            Pattern pattern = Pattern.compile(regexGp);
            Matcher matcher = pattern.matcher(password);
            if (!matcher.matches()) {
                throw new InvalidCharactersPasswordException(getMessage("error.password.different"));
            }
        } catch (PatternSyntaxException pse) {
            log.warn("Invalid regex of " + regexGp + " defined in global property <" + OpenmrsConstants.GP_PASSWORD_CUSTOM_REGEX + ">.");
        }
    }
}
Also used : Pattern(java.util.regex.Pattern) ShortPasswordException(org.openmrs.api.ShortPasswordException) APIException(org.openmrs.api.APIException) AdministrationService(org.openmrs.api.AdministrationService) Matcher(java.util.regex.Matcher) InvalidCharactersPasswordException(org.openmrs.api.InvalidCharactersPasswordException) WeakPasswordException(org.openmrs.api.WeakPasswordException) PatternSyntaxException(java.util.regex.PatternSyntaxException)

Aggregations

Matcher (java.util.regex.Matcher)1 Pattern (java.util.regex.Pattern)1 PatternSyntaxException (java.util.regex.PatternSyntaxException)1 APIException (org.openmrs.api.APIException)1 AdministrationService (org.openmrs.api.AdministrationService)1 InvalidCharactersPasswordException (org.openmrs.api.InvalidCharactersPasswordException)1 ShortPasswordException (org.openmrs.api.ShortPasswordException)1 WeakPasswordException (org.openmrs.api.WeakPasswordException)1