[KEYCLOAK-19006] User Profile: Patched handling of the "whitespace-only"

texts in pattern and length validators
This commit is contained in:
Vlastimil Elias 2021-08-09 17:03:30 +02:00 committed by Pedro Igor
parent 269b661b8a
commit afa6e31d36
3 changed files with 34 additions and 17 deletions

View file

@ -16,8 +16,6 @@
*/
package org.keycloak.validate;
import org.keycloak.utils.StringUtil;
/**
* Base class for String value format validators. Functionality covered in this base class:
* <ul>
@ -45,7 +43,7 @@ public abstract class AbstractStringValidator extends AbstractSimpleValidator {
@Override
protected boolean skipValidation(Object value, ValidatorConfig config) {
if (isIgnoreEmptyValuesConfigured(config) && (value == null || value instanceof String)) {
return value == null || StringUtil.isBlank(value.toString());
return value == null || "".equals(value.toString());
}
return false;
}

View file

@ -68,6 +68,12 @@ public class LengthValidator extends AbstractStringValidator implements Configur
property.setHelpText("The maximum length");
property.setType(ProviderConfigProperty.STRING_TYPE);
configProperties.add(property);
property = new ProviderConfigProperty();
property.setName(KEY_TRIM_DISABLED);
property.setLabel("Trimming disabled");
property.setHelpText("Disable trimming of the String value before the length check");
property.setType(ProviderConfigProperty.BOOLEAN_TYPE);
configProperties.add(property);
}
@Override

View file

@ -34,18 +34,28 @@ public class BuiltinValidatorsTest {
Assert.assertFalse(validator.validate(" ", "name", configFromMap(ImmutableMap.of(LengthValidator.KEY_MIN, 1))).isValid());
Assert.assertTrue(validator.validate(" ", "name", configFromMap(ImmutableMap.of(LengthValidator.KEY_MAX, 10))).isValid());
// empty value ignoration configured
Assert.assertTrue(validator.validate(null, "name", valConfigIgnoreEmptyValues).isValid());
Assert.assertTrue(validator.validate("", "name", valConfigIgnoreEmptyValues).isValid());
Assert.assertTrue(validator.validate(" ", "name", valConfigIgnoreEmptyValues).isValid());
//KEYCLOAK-19006 reproducer
Assert.assertFalse(validator.validate(" ", "name", ValidatorConfig.builder().config(LengthValidator.KEY_MAX, 4).config(AbstractSimpleValidator.IGNORE_EMPTY_VALUE, true).config(LengthValidator.KEY_TRIM_DISABLED, true).build()).isValid());
// min validation only
Assert.assertTrue(validator.validate("tester", "name", configFromMap(ImmutableMap.of(LengthValidator.KEY_MIN, 1))).isValid());
Assert.assertFalse(validator.validate("tester", "name", configFromMap(ImmutableMap.of(LengthValidator.KEY_MIN, 7))).isValid());
Assert.assertTrue(validator.validate("t", "name", ValidatorConfig.builder().config(LengthValidator.KEY_MIN, 1).build()).isValid());
Assert.assertFalse(validator.validate("tester", "name", ValidatorConfig.builder().config(LengthValidator.KEY_MIN, 7).build()).isValid());
//min value validation with "empty value ignoration" configured
Assert.assertTrue(validator.validate(null, "name", ValidatorConfig.builder().config(LengthValidator.KEY_MIN, 1).config(AbstractSimpleValidator.IGNORE_EMPTY_VALUE, true).build()).isValid());
Assert.assertTrue(validator.validate("", "name", ValidatorConfig.builder().config(LengthValidator.KEY_MIN, 1).config(AbstractSimpleValidator.IGNORE_EMPTY_VALUE, true).build()).isValid());
Assert.assertFalse(validator.validate(" ", "name", ValidatorConfig.builder().config(LengthValidator.KEY_MIN, 1).config(AbstractSimpleValidator.IGNORE_EMPTY_VALUE, true).build()).isValid());
Assert.assertTrue(validator.validate("t", "name", ValidatorConfig.builder().config(LengthValidator.KEY_MIN, 1).config(AbstractSimpleValidator.IGNORE_EMPTY_VALUE, true).build()).isValid());
Assert.assertFalse(validator.validate("tester", "name", ValidatorConfig.builder().config(LengthValidator.KEY_MIN, 7).config(AbstractSimpleValidator.IGNORE_EMPTY_VALUE, true).build()).isValid());
// max validation only
Assert.assertTrue(validator.validate("tester", "name", configFromMap(ImmutableMap.of(LengthValidator.KEY_MAX, 8))).isValid());
Assert.assertFalse(validator.validate("tester", "name", configFromMap(ImmutableMap.of(LengthValidator.KEY_MAX, 4))).isValid());
Assert.assertTrue(validator.validate("tester", "name", ValidatorConfig.builder().config(LengthValidator.KEY_MAX, 8).build()).isValid());
Assert.assertFalse(validator.validate("tester", "name", ValidatorConfig.builder().config(LengthValidator.KEY_MAX, 4).build()).isValid());
//max value validation with "empty value ignoration" configured
Assert.assertTrue(validator.validate(null, "name", ValidatorConfig.builder().config(LengthValidator.KEY_MAX, 8).config(AbstractSimpleValidator.IGNORE_EMPTY_VALUE, true).build()).isValid());
Assert.assertTrue(validator.validate("tester", "name", ValidatorConfig.builder().config(LengthValidator.KEY_MAX, 8).config(AbstractSimpleValidator.IGNORE_EMPTY_VALUE, true).build()).isValid());
Assert.assertFalse(validator.validate("tester", "name", ValidatorConfig.builder().config(LengthValidator.KEY_MAX, 4).config(AbstractSimpleValidator.IGNORE_EMPTY_VALUE, true).build()).isValid());
// both validations together
ValidatorConfig config1 = configFromMap(ImmutableMap.of(LengthValidator.KEY_MIN, 3, LengthValidator.KEY_MAX, 4));
@ -57,9 +67,12 @@ public class BuiltinValidatorsTest {
// test value trimming performed by default
Assert.assertFalse("trim not performed", validator.validate("t ", "name", configFromMap(ImmutableMap.of(LengthValidator.KEY_MIN, 2))).isValid());
Assert.assertFalse("trim not performed", validator.validate(" t", "name", configFromMap(ImmutableMap.of(LengthValidator.KEY_MIN, 2))).isValid());
Assert.assertTrue("trim not performed", validator.validate("tr ", "name", configFromMap(ImmutableMap.of(LengthValidator.KEY_MAX, 2))).isValid());
Assert.assertTrue("trim not performed", validator.validate(" tr", "name", configFromMap(ImmutableMap.of(LengthValidator.KEY_MAX, 2))).isValid());
// test value trimming disabled in config
Assert.assertTrue("trim disabled but performed", validator.validate("t ", "name", configFromMap(ImmutableMap.of(LengthValidator.KEY_MIN, 2, LengthValidator.KEY_TRIM_DISABLED, true))).isValid());
Assert.assertTrue("trim disabled but performed", validator.validate("tr ", "name", configFromMap(ImmutableMap.of(LengthValidator.KEY_MIN, 3, LengthValidator.KEY_TRIM_DISABLED, true))).isValid());
Assert.assertFalse("trim disabled but performed", validator.validate("trr ", "name", configFromMap(ImmutableMap.of(LengthValidator.KEY_MAX, 3, LengthValidator.KEY_TRIM_DISABLED, true))).isValid());
//test correct error message selection
Assert.assertEquals(LengthValidator.MESSAGE_INVALID_LENGTH_TOO_SHORT,validator.validate("", "name", ValidatorConfig.builder().config(LengthValidator.KEY_MIN, 1).build()).getErrors().iterator().next().getMessage());
@ -112,12 +125,12 @@ public class BuiltinValidatorsTest {
Assert.assertFalse(validator.validate(null, "email").isValid());
Assert.assertFalse(validator.validate("", "email").isValid());
Assert.assertFalse(validator.validate(" ", "email").isValid());
// empty value ignoration configured
Assert.assertTrue(validator.validate(null, "emptyString", valConfigIgnoreEmptyValues).isValid());
Assert.assertTrue(validator.validate("", "emptyString", valConfigIgnoreEmptyValues).isValid());
Assert.assertTrue(validator.validate(" ", "blankString", valConfigIgnoreEmptyValues).isValid());
Assert.assertFalse(validator.validate(" ", "blankString", valConfigIgnoreEmptyValues).isValid());
Assert.assertTrue(validator.validate("admin@example.org", "email").isValid());
Assert.assertTrue(validator.validate("admin+sds@example.org", "email").isValid());
@ -422,7 +435,7 @@ public class BuiltinValidatorsTest {
// empty value ignoration configured
Assert.assertTrue(validator.validate(null, "value", valConfigIgnoreEmptyValues).isValid());
Assert.assertTrue(validator.validate("", "value", valConfigIgnoreEmptyValues).isValid());
Assert.assertTrue(validator.validate(" ", "value", valConfigIgnoreEmptyValues).isValid());
Assert.assertFalse(validator.validate(" ", "value", ValidatorConfig.builder().config(PatternValidator.CFG_PATTERN, "^[^\\s]$").config(valConfigIgnoreEmptyValues).build()).isValid());
}