vt-middleware / passay

Password policy enforcement for Java.
http://www.passay.org
Other
275 stars 63 forks source link

i18n-internationalization Passay password validation with db message source #119

Closed iGaurav4 closed 4 years ago

iGaurav4 commented 4 years ago

I am using DBMessageSource as messagesource for message translation. It's working for validation and API response messages, but i am getting NPE for password validation messages.

Here's code for DBMessageSource:-

public class DBMessageSource extends AbstractMessageSource {

@Autowired private LanguageRepository languageRepository;

@Override protected MessageFormat resolveCode(String key, Locale locale) { log.debug("key :{}", key); log.debug("locale :{}", locale); final String DEFAULT_LOCALE = "en"; LocaleMessages localeMessages = languageRepository.findByMessageKeyAndLanguageLocale(key, locale.getLanguage()); if (localeMessages == null){ localeMessages = languageRepository.findByMessageKeyAndLanguageLocale(key, DEFAULT_LOCALE); } if(localeMessages == null){ return null; } MessageFormat messageFormat = new MessageFormat(localeMessages.getMessageValue() , locale); return messageFormat; } }

And the password validator code :-

public class PasswordConstraintValidator implements ConstraintValidator<ValidPassword, String> {

@Autowired DBMessageSource messageSource;

@Override public boolean isValid(String password, ConstraintValidatorContext context) { MessageResolver messageResolver = new SpringMessageResolver(messageSource); PasswordValidator validator = new PasswordValidator( messageResolver, Arrays.asList( // at least 6 characters new LengthRule(6, 32), // at least one upper-case character new CharacterRule(EnglishCharacterData.UpperCase, 1), // at least one lower-case character new CharacterRule(EnglishCharacterData.LowerCase, 1), // at least one digit character new CharacterRule(EnglishCharacterData.Digit, 1), // at least one symbol (special character) new CharacterRule(EnglishCharacterData.Special, 1), //no whitespace new WhitespaceRule()));

RuleResult result = validator.validate(new PasswordData(password));
if (result.isValid()) {
    return true;
}
List<String> messages = validator.getMessages(result);
String messageTemplate = messages.stream().collect(Collectors.joining(","));
context.buildConstraintViolationWithTemplate(messageTemplate).addConstraintViolation()
        .disableDefaultConstraintViolation();

return false;

} }

2020-07-24 23:42:56.025 ERROR 109748 --- [nio-8443-exec-9] o.a.c.c.C.[.[.[/].[dispatcherServlet] : Servlet.service() for servlet [dispatcherServlet] in context with path [] threw exception [Request processing failed; nested exception is javax.validation.ValidationException: HV000028: Unexpected exception during isValid call.] with root cause

java.lang.NullPointerException: null at org.springframework.context.support.MessageSourceAccessor.getMessage(MessageSourceAccessor.java:157) ~[spring-context-5.0.5.RELEASE.jar:5.0.5.RELEASE] at org.passay.spring.SpringMessageResolver.resolve(SpringMessageResolver.java:56) ~[passay-1.6.0.jar:na] at java.util.stream.ReferencePipeline$3$1.accept(ReferencePipeline.java:193) ~[na:1.8.0_252] at java.util.ArrayList$ArrayListSpliterator.forEachRemaining(ArrayList.java:1382) ~[na:1.8.0_252] at java.util.stream.AbstractPipeline.copyInto(AbstractPipeline.java:482) ~[na:1.8.0_252] at java.util.stream.AbstractPipeline.wrapAndCopyInto(AbstractPipeline.java:472) ~[na:1.8.0_252] at java.util.stream.ReduceOps$ReduceOp.evaluateSequential(ReduceOps.java:708) ~[na:1.8.0_252] at java.util.stream.AbstractPipeline.evaluate(AbstractPipeline.java:234) ~[na:1.8.0_252] at java.util.stream.ReferencePipeline.collect(ReferencePipeline.java:566) ~[na:1.8.0_252] at org.passay.PasswordValidator.getMessages(PasswordValidator.java:157) ~[passay-1.6.0.jar:na] at usermanagement.validation.PasswordConstraintValidator.isValid(PasswordConstraintValidator.java:56) ~[classes/:na] at usermanagement.validation.PasswordConstraintValidator.isValid(PasswordConstraintValidator.java:28) ~[classes/:na] at

iGaurav4 commented 4 years ago

https://stackoverflow.com/questions/63080104/i18n-internationalization-passay-password-validation-with-db-message-source

dfish3r commented 4 years ago

From the stacktrace it looks like the auto wiring isn't occurring for DBMessageSource and you're passing null to the SpringMessageResolver.

dfish3r commented 4 years ago

No response from reporter. Feel free to reopen if you have more to report.

iGaurav4 commented 4 years ago

@dfish3r Still need your help I checked several times, message source was getting called. I am getting the validation message in messageTemplate. But the issue seems like isValid being called again. Check the debug image.

image

dfish3r commented 4 years ago

There's not enough context here for me to know what is going on. If you have a repository you can point me at with a failing unit test I can take a look.

iGaurav4 commented 4 years ago

@dfish3r Please access https://github.com/iGaurav4/usermanagement for the code extract.

dfish3r commented 4 years ago

Conversation moved to the pull request.