Move some UserProfile and Validation classes into keycloak-server-spi
closes #24387
This commit is contained in:
parent
75440abb5f
commit
6f992915d7
27 changed files with 396 additions and 351 deletions
|
@ -1,240 +0,0 @@
|
|||
/*
|
||||
* Copyright 2021 Red Hat, Inc. and/or its affiliates
|
||||
* and other contributors as indicated by the @author tags.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.keycloak.validate;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import org.keycloak.models.KeycloakSession;
|
||||
import org.keycloak.models.KeycloakSessionFactory;
|
||||
import org.keycloak.validate.validators.LocalDateValidator;
|
||||
import org.keycloak.validate.validators.EmailValidator;
|
||||
import org.keycloak.validate.validators.IntegerValidator;
|
||||
import org.keycloak.validate.validators.LengthValidator;
|
||||
import org.keycloak.validate.validators.NotBlankValidator;
|
||||
import org.keycloak.validate.validators.NotEmptyValidator;
|
||||
import org.keycloak.validate.validators.OptionsValidator;
|
||||
import org.keycloak.validate.validators.DoubleValidator;
|
||||
import org.keycloak.validate.validators.PatternValidator;
|
||||
import org.keycloak.validate.validators.UriValidator;
|
||||
import org.keycloak.validate.validators.ValidatorConfigValidator;
|
||||
|
||||
/**
|
||||
* Facade for Validation functions with support for {@link Validator} implementation lookup by id.
|
||||
*/
|
||||
public class Validators {
|
||||
|
||||
/**
|
||||
* Holds a mapping of internal {@link SimpleValidator} to allow look-up via provider id.
|
||||
*/
|
||||
private static final Map<String, SimpleValidator> INTERNAL_VALIDATORS;
|
||||
|
||||
static {
|
||||
List<SimpleValidator> list = Arrays.asList(
|
||||
LengthValidator.INSTANCE,
|
||||
NotEmptyValidator.INSTANCE,
|
||||
UriValidator.INSTANCE,
|
||||
EmailValidator.INSTANCE,
|
||||
NotBlankValidator.INSTANCE,
|
||||
PatternValidator.INSTANCE,
|
||||
DoubleValidator.INSTANCE,
|
||||
IntegerValidator.INSTANCE,
|
||||
ValidatorConfigValidator.INSTANCE,
|
||||
OptionsValidator.INSTANCE
|
||||
);
|
||||
|
||||
INTERNAL_VALIDATORS = list.stream().collect(Collectors.toMap(SimpleValidator::getId, v -> v));
|
||||
}
|
||||
|
||||
/**
|
||||
* Holds the {@link KeycloakSession}.
|
||||
*/
|
||||
private final KeycloakSession session;
|
||||
|
||||
/**
|
||||
* Creates a new {@link Validators} instance with the given {@link KeycloakSession}.
|
||||
*
|
||||
* @param session
|
||||
*/
|
||||
public Validators(KeycloakSession session) {
|
||||
this.session = session;
|
||||
}
|
||||
|
||||
/**
|
||||
* Look-up for a built-in or registered {@link Validator} with the given provider {@code id}.
|
||||
*
|
||||
* @param id
|
||||
* @return
|
||||
* @see #validator(KeycloakSession, String)
|
||||
*/
|
||||
public Validator validator(String id) {
|
||||
return validator(session, id);
|
||||
}
|
||||
|
||||
/**
|
||||
* Look-up for a built-in or registered {@link ValidatorFactory} with the given provider {@code id}.
|
||||
*
|
||||
* @param id
|
||||
* @return
|
||||
* @see #validatorFactory(KeycloakSession, String)
|
||||
*/
|
||||
public ValidatorFactory validatorFactory(String id) {
|
||||
return validatorFactory(session, id);
|
||||
}
|
||||
|
||||
/**
|
||||
* Validates the {@link ValidatorConfig} of {@link Validator} referenced by the given provider {@code id}.
|
||||
*
|
||||
* @param id
|
||||
* @param config
|
||||
* @return
|
||||
* @see #validateConfig(KeycloakSession, String, ValidatorConfig)
|
||||
*/
|
||||
public ValidationResult validateConfig(String id, ValidatorConfig config) {
|
||||
return validateConfig(session, id, config);
|
||||
}
|
||||
|
||||
/* static import friendly accessor methods for built-in validators */
|
||||
|
||||
public static Validator getInternalValidatorById(String id) {
|
||||
return INTERNAL_VALIDATORS.get(id);
|
||||
}
|
||||
|
||||
public static ValidatorFactory getInternalValidatorFactoryById(String id) {
|
||||
return INTERNAL_VALIDATORS.get(id);
|
||||
}
|
||||
|
||||
public static Map<String, Validator> getInternalValidators() {
|
||||
return Collections.unmodifiableMap(INTERNAL_VALIDATORS);
|
||||
}
|
||||
|
||||
public static NotBlankValidator notBlankValidator() {
|
||||
return NotBlankValidator.INSTANCE;
|
||||
}
|
||||
|
||||
public static NotEmptyValidator notEmptyValidator() {
|
||||
return NotEmptyValidator.INSTANCE;
|
||||
}
|
||||
|
||||
public static LengthValidator lengthValidator() {
|
||||
return LengthValidator.INSTANCE;
|
||||
}
|
||||
|
||||
public static UriValidator uriValidator() {
|
||||
return UriValidator.INSTANCE;
|
||||
}
|
||||
|
||||
public static EmailValidator emailValidator() {
|
||||
return EmailValidator.INSTANCE;
|
||||
}
|
||||
|
||||
public static PatternValidator patternValidator() {
|
||||
return PatternValidator.INSTANCE;
|
||||
}
|
||||
|
||||
public static DoubleValidator doubleValidator() {
|
||||
return DoubleValidator.INSTANCE;
|
||||
}
|
||||
|
||||
public static IntegerValidator integerValidator() {
|
||||
return IntegerValidator.INSTANCE;
|
||||
}
|
||||
|
||||
public static LocalDateValidator dateValidator() {
|
||||
return LocalDateValidator.INSTANCE;
|
||||
}
|
||||
|
||||
public static OptionsValidator optionsValidator() {
|
||||
return OptionsValidator.INSTANCE;
|
||||
}
|
||||
|
||||
public static ValidatorConfigValidator validatorConfigValidator() {
|
||||
return ValidatorConfigValidator.INSTANCE;
|
||||
}
|
||||
|
||||
/**
|
||||
* Look-up up for a built-in or registered {@link Validator} with the given validatorId.
|
||||
*
|
||||
* @param session the {@link KeycloakSession}
|
||||
* @param id the id of the validator
|
||||
* @return the {@link Validator} or {@literal null}
|
||||
*/
|
||||
public static Validator validator(KeycloakSession session, String id) {
|
||||
|
||||
// Fast-path for internal Validators
|
||||
Validator validator = getInternalValidatorById(id);
|
||||
if (validator != null) {
|
||||
return validator;
|
||||
}
|
||||
|
||||
if (session == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
// Lookup validator in registry
|
||||
return session.getProvider(Validator.class, id);
|
||||
}
|
||||
|
||||
/**
|
||||
* Look-up for a built-in or registered {@link ValidatorFactory} with the given validatorId.
|
||||
* <p>
|
||||
* This is intended for users who want to dynamically create new {@link Validator} instances, validate
|
||||
* {@link ValidatorConfig} configurations or create default configurations for a {@link Validator}.
|
||||
*
|
||||
* @param session the {@link KeycloakSession}
|
||||
* @param id the id of the validator
|
||||
* @return the {@link Validator} or {@literal null}
|
||||
*/
|
||||
public static ValidatorFactory validatorFactory(KeycloakSession session, String id) {
|
||||
|
||||
// Fast-path for internal Validators
|
||||
ValidatorFactory factory = getInternalValidatorFactoryById(id);
|
||||
if (factory != null) {
|
||||
return factory;
|
||||
}
|
||||
|
||||
if (session == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
// Lookup factory in registry
|
||||
KeycloakSessionFactory sessionFactory = session.getKeycloakSessionFactory();
|
||||
return (ValidatorFactory) sessionFactory.getProviderFactory(Validator.class, id);
|
||||
}
|
||||
|
||||
/**
|
||||
* Validates the {@link ValidatorConfig} of {@link Validator} referenced by the given provider {@code id}.
|
||||
*
|
||||
* @param session
|
||||
* @param id of the validator
|
||||
* @param config to be validated
|
||||
* @return
|
||||
*/
|
||||
public static ValidationResult validateConfig(KeycloakSession session, String id, ValidatorConfig config) {
|
||||
|
||||
ValidatorFactory validatorFactory = validatorFactory(session, id);
|
||||
if (validatorFactory != null) {
|
||||
return validatorFactory.validateConfig(session, config);
|
||||
}
|
||||
|
||||
// We could not find a ValidationFactory to validate that config, so we assume the config is valid.
|
||||
return ValidationResult.OK;
|
||||
}
|
||||
}
|
|
@ -57,7 +57,7 @@ public class ValidatorConfigValidator implements SimpleValidator {
|
|||
|
||||
public static final ValidatorConfigValidator INSTANCE = new ValidatorConfigValidator();
|
||||
|
||||
private ValidatorConfigValidator() {
|
||||
public ValidatorConfigValidator() {
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -7,4 +7,5 @@ org.keycloak.validate.validators.PatternValidator
|
|||
org.keycloak.validate.validators.DoubleValidator
|
||||
org.keycloak.validate.validators.IntegerValidator
|
||||
org.keycloak.validate.validators.LocalDateValidator
|
||||
org.keycloak.validate.validators.OptionsValidator
|
||||
org.keycloak.validate.validators.OptionsValidator
|
||||
org.keycloak.validate.validators.ValidatorConfigValidator
|
||||
|
|
|
@ -1,18 +1,20 @@
|
|||
/*
|
||||
* Copyright 2021 Red Hat, Inc. and/or its affiliates
|
||||
* and other contributors as indicated by the @author tags.
|
||||
* Copyright 2023 Red Hat, Inc. and/or its affiliates
|
||||
* and other contributors as indicated by the @author tags.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
*
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.keycloak.validate;
|
||||
|
||||
|
@ -40,17 +42,6 @@ public interface Validator extends Provider {
|
|||
return validate(input, "input", new ValidationContext(), ValidatorConfig.EMPTY);
|
||||
}
|
||||
|
||||
/**
|
||||
* Validates the given {@code input} with an additional {@code config}.
|
||||
*
|
||||
* @param input the value to validate
|
||||
* @param config parameterization for the current validation
|
||||
* @return the validation context with the outcome of the validation
|
||||
*/
|
||||
default ValidationContext validate(Object input, ValidatorConfig config) {
|
||||
return validate(input, "input", new ValidationContext(), config);
|
||||
}
|
||||
|
||||
/**
|
||||
* Validates the given {@code input}.
|
||||
*
|
131
server-spi/src/main/java/org/keycloak/validate/Validators.java
Normal file
131
server-spi/src/main/java/org/keycloak/validate/Validators.java
Normal file
|
@ -0,0 +1,131 @@
|
|||
/*
|
||||
* Copyright 2023 Red Hat, Inc. and/or its affiliates
|
||||
* and other contributors as indicated by the @author tags.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
*
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*
|
||||
*/
|
||||
package org.keycloak.validate;
|
||||
|
||||
import org.keycloak.models.KeycloakSession;
|
||||
import org.keycloak.models.KeycloakSessionFactory;
|
||||
|
||||
/**
|
||||
* Facade for Validation functions with support for {@link Validator} implementation lookup by id.
|
||||
*/
|
||||
public class Validators {
|
||||
|
||||
/**
|
||||
* Holds the {@link KeycloakSession}.
|
||||
*/
|
||||
private final KeycloakSession session;
|
||||
|
||||
/**
|
||||
* Creates a new {@link Validators} instance with the given {@link KeycloakSession}.
|
||||
*
|
||||
* @param session
|
||||
*/
|
||||
public Validators(KeycloakSession session) {
|
||||
this.session = session;
|
||||
}
|
||||
|
||||
/**
|
||||
* Look-up for a built-in or registered {@link Validator} with the given provider {@code id}.
|
||||
*
|
||||
* @param id
|
||||
* @return
|
||||
* @see #validator(KeycloakSession, String)
|
||||
*/
|
||||
public Validator validator(String id) {
|
||||
return validator(session, id);
|
||||
}
|
||||
|
||||
/**
|
||||
* Look-up for a built-in or registered {@link ValidatorFactory} with the given provider {@code id}.
|
||||
*
|
||||
* @param id
|
||||
* @return
|
||||
* @see #validatorFactory(KeycloakSession, String)
|
||||
*/
|
||||
public ValidatorFactory validatorFactory(String id) {
|
||||
return validatorFactory(session, id);
|
||||
}
|
||||
|
||||
/**
|
||||
* Validates the {@link ValidatorConfig} of {@link Validator} referenced by the given provider {@code id}.
|
||||
*
|
||||
* @param id
|
||||
* @param config
|
||||
* @return
|
||||
* @see #validateConfig(KeycloakSession, String, ValidatorConfig)
|
||||
*/
|
||||
public ValidationResult validateConfig(String id, ValidatorConfig config) {
|
||||
return validateConfig(session, id, config);
|
||||
}
|
||||
|
||||
/**
|
||||
* Look-up up for a built-in or registered {@link Validator} with the given validatorId.
|
||||
*
|
||||
* @param session the {@link KeycloakSession}
|
||||
* @param id the id of the validator
|
||||
* @return the {@link Validator} or {@literal null}
|
||||
*/
|
||||
public static Validator validator(KeycloakSession session, String id) {
|
||||
if (session == null) {
|
||||
throw new IllegalArgumentException("KeycloakSession must be not null");
|
||||
}
|
||||
|
||||
// Lookup validator in registry
|
||||
return session.getProvider(Validator.class, id);
|
||||
}
|
||||
|
||||
/**
|
||||
* Look-up for a built-in or registered {@link ValidatorFactory} with the given validatorId.
|
||||
* <p>
|
||||
* This is intended for users who want to dynamically create new {@link Validator} instances, validate
|
||||
* {@link ValidatorConfig} configurations or create default configurations for a {@link Validator}.
|
||||
*
|
||||
* @param session the {@link KeycloakSession}
|
||||
* @param id the id of the validator
|
||||
* @return the {@link Validator} or {@literal null}
|
||||
*/
|
||||
public static ValidatorFactory validatorFactory(KeycloakSession session, String id) {
|
||||
if (session == null) {
|
||||
throw new IllegalArgumentException("KeycloakSession must be not null");
|
||||
}
|
||||
|
||||
// Lookup factory in registry
|
||||
KeycloakSessionFactory sessionFactory = session.getKeycloakSessionFactory();
|
||||
return (ValidatorFactory) sessionFactory.getProviderFactory(Validator.class, id);
|
||||
}
|
||||
|
||||
/**
|
||||
* Validates the {@link ValidatorConfig} of {@link Validator} referenced by the given provider {@code id}.
|
||||
*
|
||||
* @param session
|
||||
* @param id of the validator
|
||||
* @param config to be validated
|
||||
* @return
|
||||
*/
|
||||
public static ValidationResult validateConfig(KeycloakSession session, String id, ValidatorConfig config) {
|
||||
|
||||
ValidatorFactory validatorFactory = validatorFactory(session, id);
|
||||
if (validatorFactory != null) {
|
||||
return validatorFactory.validateConfig(session, config);
|
||||
}
|
||||
|
||||
// We could not find a ValidationFactory to validate that config, so we assume the config is valid.
|
||||
return ValidationResult.OK;
|
||||
}
|
||||
}
|
|
@ -17,23 +17,20 @@
|
|||
package org.keycloak.userprofile.validator;
|
||||
|
||||
import static org.keycloak.common.util.CollectionUtil.collectionEquals;
|
||||
import static org.keycloak.validate.Validators.notBlankValidator;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Objects;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import org.keycloak.common.util.CollectionUtil;
|
||||
import org.keycloak.models.RealmModel;
|
||||
import org.keycloak.models.UserModel;
|
||||
import org.keycloak.userprofile.AttributeContext;
|
||||
import org.keycloak.userprofile.AttributeValidatorMetadata;
|
||||
import org.keycloak.userprofile.UserProfileAttributeValidationContext;
|
||||
import org.keycloak.validate.SimpleValidator;
|
||||
import org.keycloak.validate.ValidationContext;
|
||||
import org.keycloak.validate.ValidationError;
|
||||
import org.keycloak.validate.ValidatorConfig;
|
||||
import org.keycloak.validate.Validators;
|
||||
import org.keycloak.validate.validators.NotBlankValidator;
|
||||
|
||||
/**
|
||||
* A validator that fails when the attribute is marked as read only and its value has changed.
|
||||
|
@ -65,7 +62,7 @@ public class ImmutableAttributeValidator implements SimpleValidator {
|
|||
List<String> values = (List<String>) input;
|
||||
|
||||
if (!collectionEquals(currentValue, values) && isReadOnly(attributeContext)) {
|
||||
if (currentValue.isEmpty() && !notBlankValidator().validate(values).isValid()) {
|
||||
if (currentValue.isEmpty() && !NotBlankValidator.INSTANCE.validate(values).isValid()) {
|
||||
return context;
|
||||
}
|
||||
|
||||
|
|
|
@ -1,4 +1,23 @@
|
|||
package org.keycloak.validate;
|
||||
/*
|
||||
* Copyright 2023 Red Hat, Inc. and/or its affiliates
|
||||
* and other contributors as indicated by the @author tags.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
*
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*
|
||||
*/
|
||||
|
||||
package org.keycloak.testsuite.validation;
|
||||
|
||||
import static org.keycloak.validate.ValidatorConfig.configFromMap;
|
||||
|
||||
|
@ -11,6 +30,17 @@ import java.util.regex.Pattern;
|
|||
|
||||
import org.junit.Assert;
|
||||
import org.junit.Test;
|
||||
import org.keycloak.models.KeycloakSession;
|
||||
import org.keycloak.representations.idm.RealmRepresentation;
|
||||
import org.keycloak.testsuite.AbstractKeycloakTest;
|
||||
import org.keycloak.testsuite.AbstractTestRealmKeycloakTest;
|
||||
import org.keycloak.testsuite.arquillian.annotation.ModelTest;
|
||||
import org.keycloak.validate.AbstractSimpleValidator;
|
||||
import org.keycloak.validate.ValidationContext;
|
||||
import org.keycloak.validate.ValidationError;
|
||||
import org.keycloak.validate.ValidationResult;
|
||||
import org.keycloak.validate.Validator;
|
||||
import org.keycloak.validate.ValidatorConfig;
|
||||
import org.keycloak.validate.validators.DoubleValidator;
|
||||
import org.keycloak.validate.validators.EmailValidator;
|
||||
import org.keycloak.validate.validators.IntegerValidator;
|
||||
|
@ -21,14 +51,18 @@ import org.keycloak.validate.validators.UriValidator;
|
|||
|
||||
import com.google.common.collect.ImmutableMap;
|
||||
|
||||
public class BuiltinValidatorsTest {
|
||||
public class BuiltinValidatorsTest extends AbstractKeycloakTest {
|
||||
|
||||
private static final ValidatorConfig valConfigIgnoreEmptyValues = ValidatorConfig.builder().config(AbstractSimpleValidator.IGNORE_EMPTY_VALUE, true).build();
|
||||
|
||||
@Override
|
||||
public void addTestRealms(List<RealmRepresentation> testRealms) {
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testLengthValidator() {
|
||||
|
||||
Validator validator = Validators.lengthValidator();
|
||||
Validator validator = SimpleValidators.lengthValidator();
|
||||
|
||||
// null and empty values handling
|
||||
Assert.assertFalse(validator.validate(null, "name", configFromMap(ImmutableMap.of(LengthValidator.KEY_MIN, 1))).isValid());
|
||||
|
@ -84,12 +118,13 @@ public class BuiltinValidatorsTest {
|
|||
}
|
||||
|
||||
@Test
|
||||
public void testLengthValidator_ConfigValidation() {
|
||||
@ModelTest
|
||||
public void testLengthValidator_ConfigValidation(KeycloakSession session) {
|
||||
|
||||
// invalid min and max config values
|
||||
ValidatorConfig config = new ValidatorConfig(ImmutableMap.of(LengthValidator.KEY_MIN, new Object(), LengthValidator.KEY_MAX, "invalid"));
|
||||
|
||||
ValidationResult result = Validators.validatorConfigValidator().validate(config, LengthValidator.ID).toResult();
|
||||
ValidationResult result = SimpleValidators.validatorConfigValidator().validate(config, LengthValidator.ID, new ValidationContext(session)).toResult();
|
||||
|
||||
Assert.assertFalse(result.isValid());
|
||||
ValidationError[] errors = result.getErrors().toArray(new ValidationError[0]);
|
||||
|
@ -105,25 +140,25 @@ public class BuiltinValidatorsTest {
|
|||
Assert.assertEquals(LengthValidator.KEY_MAX, error1.getInputHint());
|
||||
|
||||
// empty config
|
||||
result = Validators.validatorConfigValidator().validate(null, LengthValidator.ID).toResult();
|
||||
result = SimpleValidators.validatorConfigValidator().validate(null, LengthValidator.ID, new ValidationContext(session)).toResult();
|
||||
Assert.assertEquals(2, result.getErrors().size());
|
||||
result = Validators.validatorConfigValidator().validate(ValidatorConfig.EMPTY, LengthValidator.ID).toResult();
|
||||
result = SimpleValidators.validatorConfigValidator().validate(ValidatorConfig.EMPTY, LengthValidator.ID, new ValidationContext(session)).toResult();
|
||||
Assert.assertEquals(2, result.getErrors().size());
|
||||
|
||||
// correct config
|
||||
Assert.assertTrue(Validators.validatorConfigValidator().validate(new ValidatorConfig(ImmutableMap.of(LengthValidator.KEY_MIN, "10")), LengthValidator.ID).toResult().isValid());
|
||||
Assert.assertTrue(Validators.validatorConfigValidator().validate(new ValidatorConfig(ImmutableMap.of(LengthValidator.KEY_MAX, "10")), LengthValidator.ID).toResult().isValid());
|
||||
Assert.assertTrue(Validators.validatorConfigValidator().validate(new ValidatorConfig(ImmutableMap.of(LengthValidator.KEY_MIN, "10", LengthValidator.KEY_MAX, "10")), LengthValidator.ID).toResult().isValid());
|
||||
Assert.assertTrue(SimpleValidators.validatorConfigValidator().validate(new ValidatorConfig(ImmutableMap.of(LengthValidator.KEY_MIN, "10")), LengthValidator.ID, new ValidationContext(session)).toResult().isValid());
|
||||
Assert.assertTrue(SimpleValidators.validatorConfigValidator().validate(new ValidatorConfig(ImmutableMap.of(LengthValidator.KEY_MAX, "10")), LengthValidator.ID, new ValidationContext(session)).toResult().isValid());
|
||||
Assert.assertTrue(SimpleValidators.validatorConfigValidator().validate(new ValidatorConfig(ImmutableMap.of(LengthValidator.KEY_MIN, "10", LengthValidator.KEY_MAX, "10")), LengthValidator.ID, new ValidationContext(session)).toResult().isValid());
|
||||
|
||||
// max is smaller than min
|
||||
Assert.assertFalse(Validators.validatorConfigValidator().validate(new ValidatorConfig(ImmutableMap.of(LengthValidator.KEY_MIN, "10", LengthValidator.KEY_MAX, "9")), LengthValidator.ID).toResult().isValid());
|
||||
Assert.assertFalse(SimpleValidators.validatorConfigValidator().validate(new ValidatorConfig(ImmutableMap.of(LengthValidator.KEY_MIN, "10", LengthValidator.KEY_MAX, "9")), LengthValidator.ID, new ValidationContext(session)).toResult().isValid());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testEmailValidator() {
|
||||
// this also validates StringFormatValidatorBase for simple values
|
||||
|
||||
Validator validator = Validators.emailValidator();
|
||||
Validator validator = SimpleValidators.emailValidator();
|
||||
|
||||
Assert.assertFalse(validator.validate(null, "email").isValid());
|
||||
Assert.assertFalse(validator.validate("", "email").isValid());
|
||||
|
@ -156,7 +191,7 @@ public class BuiltinValidatorsTest {
|
|||
@Test
|
||||
public void testAbstractSimpleValidatorSupportForCollections() {
|
||||
|
||||
Validator validator = Validators.emailValidator();
|
||||
Validator validator = SimpleValidators.emailValidator();
|
||||
|
||||
List<String> valuesCollection = new ArrayList<>();
|
||||
|
||||
|
@ -180,7 +215,7 @@ public class BuiltinValidatorsTest {
|
|||
@Test
|
||||
public void testNotBlankValidator() {
|
||||
|
||||
Validator validator = Validators.notBlankValidator();
|
||||
Validator validator = SimpleValidators.notBlankValidator();
|
||||
|
||||
// simple String value
|
||||
Assert.assertTrue(validator.validate("tester", "username").isValid());
|
||||
|
@ -203,7 +238,7 @@ public class BuiltinValidatorsTest {
|
|||
@Test
|
||||
public void testNotEmptyValidator() {
|
||||
|
||||
Validator validator = Validators.notEmptyValidator();
|
||||
Validator validator = SimpleValidators.notEmptyValidator();
|
||||
|
||||
Assert.assertTrue(validator.validate("tester", "username").isValid());
|
||||
Assert.assertTrue(validator.validate(" ", "username").isValid());
|
||||
|
@ -221,7 +256,7 @@ public class BuiltinValidatorsTest {
|
|||
@Test
|
||||
public void testDoubleValidator() {
|
||||
|
||||
Validator validator = Validators.doubleValidator();
|
||||
Validator validator = SimpleValidators.doubleValidator();
|
||||
|
||||
// null value and empty String
|
||||
Assert.assertFalse(validator.validate(null, "null").isValid());
|
||||
|
@ -285,12 +320,13 @@ public class BuiltinValidatorsTest {
|
|||
}
|
||||
|
||||
@Test
|
||||
public void testDoubleValidator_ConfigValidation() {
|
||||
@ModelTest
|
||||
public void testDoubleValidator_ConfigValidation(KeycloakSession session) {
|
||||
|
||||
// invalid min and max config values
|
||||
ValidatorConfig config = new ValidatorConfig(ImmutableMap.of(DoubleValidator.KEY_MIN, new Object(), DoubleValidator.KEY_MAX, "invalid"));
|
||||
|
||||
ValidationResult result = Validators.validatorConfigValidator().validate(config, DoubleValidator.ID).toResult();
|
||||
ValidationResult result = SimpleValidators.validatorConfigValidator().validate(config, DoubleValidator.ID, new ValidationContext(session)).toResult();
|
||||
|
||||
Assert.assertFalse(result.isValid());
|
||||
ValidationError[] errors = result.getErrors().toArray(new ValidationError[0]);
|
||||
|
@ -306,23 +342,23 @@ public class BuiltinValidatorsTest {
|
|||
Assert.assertEquals(DoubleValidator.KEY_MAX, error1.getInputHint());
|
||||
|
||||
// empty config
|
||||
result = Validators.validatorConfigValidator().validate(null, DoubleValidator.ID).toResult();
|
||||
result = SimpleValidators.validatorConfigValidator().validate(null, DoubleValidator.ID, new ValidationContext(session)).toResult();
|
||||
Assert.assertEquals(0, result.getErrors().size());
|
||||
result = Validators.validatorConfigValidator().validate(ValidatorConfig.EMPTY, DoubleValidator.ID).toResult();
|
||||
result = SimpleValidators.validatorConfigValidator().validate(ValidatorConfig.EMPTY, DoubleValidator.ID, new ValidationContext(session)).toResult();
|
||||
Assert.assertEquals(0, result.getErrors().size());
|
||||
|
||||
// correct config
|
||||
Assert.assertTrue(Validators.validatorConfigValidator().validate(new ValidatorConfig(ImmutableMap.of(DoubleValidator.KEY_MIN, "10.1")), DoubleValidator.ID).toResult().isValid());
|
||||
Assert.assertTrue(Validators.validatorConfigValidator().validate(new ValidatorConfig(ImmutableMap.of(DoubleValidator.KEY_MAX, "10.1")), DoubleValidator.ID).toResult().isValid());
|
||||
Assert.assertTrue(Validators.validatorConfigValidator().validate(new ValidatorConfig(ImmutableMap.of(DoubleValidator.KEY_MIN, "10.1", DoubleValidator.KEY_MAX, "11")), DoubleValidator.ID).toResult().isValid());
|
||||
Assert.assertTrue(SimpleValidators.validatorConfigValidator().validate(new ValidatorConfig(ImmutableMap.of(DoubleValidator.KEY_MIN, "10.1")), DoubleValidator.ID, new ValidationContext(session)).toResult().isValid());
|
||||
Assert.assertTrue(SimpleValidators.validatorConfigValidator().validate(new ValidatorConfig(ImmutableMap.of(DoubleValidator.KEY_MAX, "10.1")), DoubleValidator.ID, new ValidationContext(session)).toResult().isValid());
|
||||
Assert.assertTrue(SimpleValidators.validatorConfigValidator().validate(new ValidatorConfig(ImmutableMap.of(DoubleValidator.KEY_MIN, "10.1", DoubleValidator.KEY_MAX, "11")), DoubleValidator.ID, new ValidationContext(session)).toResult().isValid());
|
||||
|
||||
// max is smaller than min
|
||||
Assert.assertFalse(Validators.validatorConfigValidator().validate(new ValidatorConfig(ImmutableMap.of(DoubleValidator.KEY_MIN, "10.1", DoubleValidator.KEY_MAX, "10.1")), DoubleValidator.ID).toResult().isValid());
|
||||
Assert.assertFalse(SimpleValidators.validatorConfigValidator().validate(new ValidatorConfig(ImmutableMap.of(DoubleValidator.KEY_MIN, "10.1", DoubleValidator.KEY_MAX, "10.1")), DoubleValidator.ID, new ValidationContext(session)).toResult().isValid());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testIntegerValidator() {
|
||||
Validator validator = Validators.integerValidator();
|
||||
Validator validator = SimpleValidators.integerValidator();
|
||||
|
||||
// null value and empty String
|
||||
Assert.assertFalse(validator.validate(null, "null").isValid());
|
||||
|
@ -387,12 +423,13 @@ public class BuiltinValidatorsTest {
|
|||
}
|
||||
|
||||
@Test
|
||||
public void testIntegerValidator_ConfigValidation() {
|
||||
@ModelTest
|
||||
public void testIntegerValidator_ConfigValidation(KeycloakSession session) {
|
||||
|
||||
// invalid min and max config values
|
||||
ValidatorConfig config = new ValidatorConfig(ImmutableMap.of(IntegerValidator.KEY_MIN, new Object(), IntegerValidator.KEY_MAX, "invalid"));
|
||||
|
||||
ValidationResult result = Validators.validatorConfigValidator().validate(config, IntegerValidator.ID).toResult();
|
||||
ValidationResult result = SimpleValidators.validatorConfigValidator().validate(config, IntegerValidator.ID, new ValidationContext(session)).toResult();
|
||||
|
||||
Assert.assertFalse(result.isValid());
|
||||
ValidationError[] errors = result.getErrors().toArray(new ValidationError[0]);
|
||||
|
@ -408,24 +445,24 @@ public class BuiltinValidatorsTest {
|
|||
Assert.assertEquals(IntegerValidator.KEY_MAX, error1.getInputHint());
|
||||
|
||||
// empty config
|
||||
result = Validators.validatorConfigValidator().validate(null, IntegerValidator.ID).toResult();
|
||||
result = SimpleValidators.validatorConfigValidator().validate(null, IntegerValidator.ID, new ValidationContext(session)).toResult();
|
||||
Assert.assertEquals(0, result.getErrors().size());
|
||||
result = Validators.validatorConfigValidator().validate(ValidatorConfig.EMPTY, IntegerValidator.ID).toResult();
|
||||
result = SimpleValidators.validatorConfigValidator().validate(ValidatorConfig.EMPTY, IntegerValidator.ID, new ValidationContext(session)).toResult();
|
||||
Assert.assertEquals(0, result.getErrors().size());
|
||||
|
||||
// correct config
|
||||
Assert.assertTrue(Validators.validatorConfigValidator().validate(new ValidatorConfig(ImmutableMap.of(IntegerValidator.KEY_MIN, "10")), IntegerValidator.ID).toResult().isValid());
|
||||
Assert.assertTrue(Validators.validatorConfigValidator().validate(new ValidatorConfig(ImmutableMap.of(IntegerValidator.KEY_MAX, "10")), IntegerValidator.ID).toResult().isValid());
|
||||
Assert.assertTrue(Validators.validatorConfigValidator().validate(new ValidatorConfig(ImmutableMap.of(IntegerValidator.KEY_MIN, "10", IntegerValidator.KEY_MAX, "11")), IntegerValidator.ID).toResult().isValid());
|
||||
Assert.assertTrue(SimpleValidators.validatorConfigValidator().validate(new ValidatorConfig(ImmutableMap.of(IntegerValidator.KEY_MIN, "10")), IntegerValidator.ID, new ValidationContext(session)).toResult().isValid());
|
||||
Assert.assertTrue(SimpleValidators.validatorConfigValidator().validate(new ValidatorConfig(ImmutableMap.of(IntegerValidator.KEY_MAX, "10")), IntegerValidator.ID, new ValidationContext(session)).toResult().isValid());
|
||||
Assert.assertTrue(SimpleValidators.validatorConfigValidator().validate(new ValidatorConfig(ImmutableMap.of(IntegerValidator.KEY_MIN, "10", IntegerValidator.KEY_MAX, "11")), IntegerValidator.ID, new ValidationContext(session)).toResult().isValid());
|
||||
|
||||
// max is smaller than min
|
||||
Assert.assertFalse(Validators.validatorConfigValidator().validate(new ValidatorConfig(ImmutableMap.of(IntegerValidator.KEY_MIN, "10", IntegerValidator.KEY_MAX, "10")), IntegerValidator.ID).toResult().isValid());
|
||||
Assert.assertFalse(SimpleValidators.validatorConfigValidator().validate(new ValidatorConfig(ImmutableMap.of(IntegerValidator.KEY_MIN, "10", IntegerValidator.KEY_MAX, "10")), IntegerValidator.ID, new ValidationContext(session)).toResult().isValid());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testPatternValidator() {
|
||||
|
||||
Validator validator = Validators.patternValidator();
|
||||
Validator validator = SimpleValidators.patternValidator();
|
||||
|
||||
// Pattern object in the configuration
|
||||
ValidatorConfig config = configFromMap(Collections.singletonMap(PatternValidator.CFG_PATTERN, Pattern.compile("^start-.*-end$")));
|
||||
|
@ -456,7 +493,7 @@ public class BuiltinValidatorsTest {
|
|||
@Test
|
||||
public void testUriValidator() throws Exception {
|
||||
|
||||
Validator validator = Validators.uriValidator();
|
||||
Validator validator = SimpleValidators.uriValidator();
|
||||
|
||||
Assert.assertTrue(validator.validate(null, "baseUrl").isValid());
|
||||
Assert.assertTrue(validator.validate("", "baseUrl").isValid());
|
||||
|
@ -472,14 +509,14 @@ public class BuiltinValidatorsTest {
|
|||
Assert.assertFalse(validator.validate("https://localhost:3000/#someFragment", "baseUrl", config).isValid());
|
||||
|
||||
// it is also possible to call dedicated validation methods on a built-in validator
|
||||
Assert.assertTrue(Validators.uriValidator().validateUri(new URI("https://customurl"), Collections.singleton("https"), true, true));
|
||||
Assert.assertTrue(SimpleValidators.uriValidator().validateUri(new URI("https://customurl"), Collections.singleton("https"), true, true));
|
||||
|
||||
Assert.assertFalse(Validators.uriValidator().validateUri(new URI("http://customurl"), Collections.singleton("https"), true, true));
|
||||
Assert.assertFalse(SimpleValidators.uriValidator().validateUri(new URI("http://customurl"), Collections.singleton("https"), true, true));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testOptionsValidator(){
|
||||
Validator validator = Validators.optionsValidator();
|
||||
Validator validator = SimpleValidators.optionsValidator();
|
||||
|
||||
// options not configured - always invalid
|
||||
Assert.assertFalse(validator.validate(null, "test", ValidatorConfig.builder().config(OptionsValidator.KEY_OPTIONS, null).build()).isValid());
|
||||
|
@ -517,16 +554,17 @@ public class BuiltinValidatorsTest {
|
|||
}
|
||||
|
||||
@Test
|
||||
public void testOptionsValidator_Config_Validation() {
|
||||
@ModelTest
|
||||
public void testOptionsValidator_Config_Validation(KeycloakSession session) {
|
||||
|
||||
ValidationResult result = Validators.validatorConfigValidator().validate(ValidatorConfig.builder().build(), OptionsValidator.ID).toResult();
|
||||
ValidationResult result = SimpleValidators.validatorConfigValidator().validate(ValidatorConfig.builder().build(), OptionsValidator.ID, new ValidationContext(session)).toResult();
|
||||
Assert.assertFalse(result.isValid());
|
||||
|
||||
// invalid type of the config value
|
||||
result = Validators.validatorConfigValidator().validate(ValidatorConfig.builder().config(OptionsValidator.KEY_OPTIONS, "a").build(), OptionsValidator.ID).toResult();
|
||||
result = SimpleValidators.validatorConfigValidator().validate(ValidatorConfig.builder().config(OptionsValidator.KEY_OPTIONS, "a").build(), OptionsValidator.ID, new ValidationContext(session)).toResult();
|
||||
Assert.assertFalse(result.isValid());
|
||||
|
||||
result = Validators.validatorConfigValidator().validate(ValidatorConfig.builder().config(OptionsValidator.KEY_OPTIONS, Arrays.asList("opt1")).build(), OptionsValidator.ID).toResult();
|
||||
result = SimpleValidators.validatorConfigValidator().validate(ValidatorConfig.builder().config(OptionsValidator.KEY_OPTIONS, Arrays.asList("opt1")).build(), OptionsValidator.ID, new ValidationContext(session)).toResult();
|
||||
Assert.assertTrue(result.isValid());
|
||||
|
||||
}
|
|
@ -0,0 +1,82 @@
|
|||
/*
|
||||
* Copyright 2023 Red Hat, Inc. and/or its affiliates
|
||||
* and other contributors as indicated by the @author tags.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
*
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*
|
||||
*/
|
||||
|
||||
package org.keycloak.testsuite.validation;
|
||||
|
||||
import org.keycloak.validate.validators.DoubleValidator;
|
||||
import org.keycloak.validate.validators.EmailValidator;
|
||||
import org.keycloak.validate.validators.IntegerValidator;
|
||||
import org.keycloak.validate.validators.LengthValidator;
|
||||
import org.keycloak.validate.validators.LocalDateValidator;
|
||||
import org.keycloak.validate.validators.NotBlankValidator;
|
||||
import org.keycloak.validate.validators.NotEmptyValidator;
|
||||
import org.keycloak.validate.validators.OptionsValidator;
|
||||
import org.keycloak.validate.validators.PatternValidator;
|
||||
import org.keycloak.validate.validators.UriValidator;
|
||||
import org.keycloak.validate.validators.ValidatorConfigValidator;
|
||||
|
||||
/**
|
||||
* @author <a href="mailto:mposolda@redhat.com">Marek Posolda</a>
|
||||
*/
|
||||
public class SimpleValidators {
|
||||
|
||||
public static NotBlankValidator notBlankValidator() {
|
||||
return NotBlankValidator.INSTANCE;
|
||||
}
|
||||
|
||||
public static NotEmptyValidator notEmptyValidator() {
|
||||
return NotEmptyValidator.INSTANCE;
|
||||
}
|
||||
|
||||
public static LengthValidator lengthValidator() {
|
||||
return LengthValidator.INSTANCE;
|
||||
}
|
||||
|
||||
public static UriValidator uriValidator() {
|
||||
return UriValidator.INSTANCE;
|
||||
}
|
||||
|
||||
public static EmailValidator emailValidator() {
|
||||
return EmailValidator.INSTANCE;
|
||||
}
|
||||
|
||||
public static PatternValidator patternValidator() {
|
||||
return PatternValidator.INSTANCE;
|
||||
}
|
||||
|
||||
public static DoubleValidator doubleValidator() {
|
||||
return DoubleValidator.INSTANCE;
|
||||
}
|
||||
|
||||
public static IntegerValidator integerValidator() {
|
||||
return IntegerValidator.INSTANCE;
|
||||
}
|
||||
|
||||
public static LocalDateValidator dateValidator() {
|
||||
return LocalDateValidator.INSTANCE;
|
||||
}
|
||||
|
||||
public static OptionsValidator optionsValidator() {
|
||||
return OptionsValidator.INSTANCE;
|
||||
}
|
||||
|
||||
public static ValidatorConfigValidator validatorConfigValidator() {
|
||||
return ValidatorConfigValidator.INSTANCE;
|
||||
}
|
||||
}
|
|
@ -51,21 +51,21 @@ public class ValidatorTest extends AbstractTestRealmKeycloakTest {
|
|||
}
|
||||
|
||||
private static void testDateValidator(KeycloakSession session) {
|
||||
assertTrue(Validators.dateValidator().validate(null, new ValidationContext(session)).isValid());
|
||||
assertTrue(Validators.dateValidator().validate("", new ValidationContext(session)).isValid());
|
||||
assertTrue(SimpleValidators.dateValidator().validate(null, new ValidationContext(session)).isValid());
|
||||
assertTrue(SimpleValidators.dateValidator().validate("", new ValidationContext(session)).isValid());
|
||||
|
||||
// defaults to Locale.ENGLISH as per default locale selector
|
||||
assertFalse(Validators.dateValidator().validate("13/12/2021", new ValidationContext(session)).isValid());
|
||||
assertFalse(Validators.dateValidator().validate("13/12/21", new ValidationContext(session)).isValid());
|
||||
assertTrue(Validators.dateValidator().validate("12/13/2021", new ValidationContext(session)).isValid());
|
||||
assertFalse(SimpleValidators.dateValidator().validate("13/12/2021", new ValidationContext(session)).isValid());
|
||||
assertFalse(SimpleValidators.dateValidator().validate("13/12/21", new ValidationContext(session)).isValid());
|
||||
assertTrue(SimpleValidators.dateValidator().validate("12/13/2021", new ValidationContext(session)).isValid());
|
||||
RealmModel realm = session.getContext().getRealm();
|
||||
|
||||
realm.setInternationalizationEnabled(true);
|
||||
realm.setDefaultLocale(Locale.FRANCE.getLanguage());
|
||||
|
||||
assertTrue(Validators.dateValidator().validate("13/12/21", new ValidationContext(session)).isValid());
|
||||
assertTrue(Validators.dateValidator().validate("13/12/2021", new ValidationContext(session)).isValid());
|
||||
assertFalse(Validators.dateValidator().validate("12/13/2021", new ValidationContext(session)).isValid());
|
||||
assertTrue(SimpleValidators.dateValidator().validate("13/12/21", new ValidationContext(session)).isValid());
|
||||
assertTrue(SimpleValidators.dateValidator().validate("13/12/2021", new ValidationContext(session)).isValid());
|
||||
assertFalse(SimpleValidators.dateValidator().validate("12/13/2021", new ValidationContext(session)).isValid());
|
||||
|
||||
UserModel alice = session.users().getUserByUsername(realm, "alice");
|
||||
|
||||
|
@ -75,6 +75,6 @@ public class ValidatorTest extends AbstractTestRealmKeycloakTest {
|
|||
|
||||
context.getAttributes().put(UserModel.class.getName(), alice);
|
||||
|
||||
assertFalse(Validators.dateValidator().validate("13/12/2021", context).isValid());
|
||||
assertFalse(SimpleValidators.dateValidator().validate("13/12/2021", context).isValid());
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,4 +1,23 @@
|
|||
package org.keycloak.validate;
|
||||
/*
|
||||
* Copyright 2023 Red Hat, Inc. and/or its affiliates
|
||||
* and other contributors as indicated by the @author tags.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
*
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*
|
||||
*/
|
||||
|
||||
package org.keycloak.testsuite.validation;
|
||||
|
||||
import static org.keycloak.validate.ValidatorConfig.configFromMap;
|
||||
|
||||
|
@ -14,28 +33,41 @@ import java.util.concurrent.atomic.AtomicBoolean;
|
|||
import org.junit.Assert;
|
||||
import org.junit.Test;
|
||||
import org.keycloak.models.KeycloakSession;
|
||||
import org.keycloak.representations.idm.RealmRepresentation;
|
||||
import org.keycloak.testsuite.AbstractKeycloakTest;
|
||||
import org.keycloak.testsuite.arquillian.annotation.ModelTest;
|
||||
import org.keycloak.validate.SimpleValidator;
|
||||
import org.keycloak.validate.ValidationContext;
|
||||
import org.keycloak.validate.ValidationError;
|
||||
import org.keycloak.validate.ValidationResult;
|
||||
import org.keycloak.validate.Validator;
|
||||
import org.keycloak.validate.ValidatorConfig;
|
||||
import org.keycloak.validate.Validators;
|
||||
import org.keycloak.validate.validators.EmailValidator;
|
||||
import org.keycloak.validate.validators.LengthValidator;
|
||||
import org.keycloak.validate.validators.NotBlankValidator;
|
||||
import org.keycloak.validate.validators.ValidatorConfigValidator;
|
||||
|
||||
public class ValidatorTest {
|
||||
public class ValidatorsTest extends AbstractKeycloakTest {
|
||||
|
||||
KeycloakSession session = null;
|
||||
@Override
|
||||
public void addTestRealms(List<RealmRepresentation> testRealms) {
|
||||
}
|
||||
|
||||
@Test
|
||||
public void simpleValidation() {
|
||||
|
||||
Validator validator = Validators.notEmptyValidator();
|
||||
Validator validator = SimpleValidators.notEmptyValidator();
|
||||
|
||||
Assert.assertTrue(validator.validate("a").isValid());
|
||||
Assert.assertFalse(validator.validate("").isValid());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void simpleValidationWithContext() {
|
||||
@ModelTest
|
||||
public void simpleValidationWithContext(KeycloakSession session) {
|
||||
|
||||
Validator validator = Validators.lengthValidator();
|
||||
Validator validator = SimpleValidators.lengthValidator();
|
||||
|
||||
ValidationContext context = new ValidationContext(session);
|
||||
validator.validate("a", "username", context);
|
||||
|
@ -45,17 +77,19 @@ public class ValidatorTest {
|
|||
}
|
||||
|
||||
@Test
|
||||
public void simpleValidationFluent() {
|
||||
@ModelTest
|
||||
public void simpleValidationFluent(KeycloakSession session) {
|
||||
|
||||
ValidationContext context = new ValidationContext(session);
|
||||
|
||||
ValidationResult result = Validators.lengthValidator().validate("a", "username", context).toResult();
|
||||
ValidationResult result = SimpleValidators.lengthValidator().validate("a", "username", context).toResult();
|
||||
|
||||
Assert.assertTrue(result.isValid());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void simpleValidationLookup() {
|
||||
@ModelTest
|
||||
public void simpleValidationLookup(KeycloakSession session) {
|
||||
|
||||
// later: session.validators().validator(LengthValidator.ID);
|
||||
Validator validator = Validators.validator(session, LengthValidator.ID);
|
||||
|
@ -68,7 +102,8 @@ public class ValidatorTest {
|
|||
}
|
||||
|
||||
@Test
|
||||
public void simpleValidationError() {
|
||||
@ModelTest
|
||||
public void simpleValidationError(KeycloakSession session) {
|
||||
|
||||
Validator validator = LengthValidator.INSTANCE;
|
||||
|
||||
|
@ -104,20 +139,21 @@ public class ValidatorTest {
|
|||
public void acceptOnError() {
|
||||
|
||||
AtomicBoolean bool1 = new AtomicBoolean();
|
||||
Validators.notEmptyValidator().validate("a").toResult().ifNotValidAccept(r -> bool1.set(true));
|
||||
SimpleValidators.notEmptyValidator().validate("a").toResult().ifNotValidAccept(r -> bool1.set(true));
|
||||
Assert.assertFalse(bool1.get());
|
||||
|
||||
AtomicBoolean bool2 = new AtomicBoolean();
|
||||
Validators.notEmptyValidator().validate("").toResult().ifNotValidAccept(r -> bool2.set(true));
|
||||
SimpleValidators.notEmptyValidator().validate("").toResult().ifNotValidAccept(r -> bool2.set(true));
|
||||
Assert.assertTrue(bool2.get());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void forEachError() {
|
||||
@ModelTest
|
||||
public void forEachError(KeycloakSession session) {
|
||||
|
||||
List<String> errors = new ArrayList<>();
|
||||
MockAddress faultyAddress = new MockAddress("", "Saint-Maur-des-Fossés", null, "Germany");
|
||||
MockAddressValidator.INSTANCE.validate(faultyAddress, "address").toResult().forEachError(e -> {
|
||||
MockAddressValidator.INSTANCE.validate(faultyAddress, "address", new ValidationContext(session)).toResult().forEachError(e -> {
|
||||
errors.add(e.getMessage());
|
||||
});
|
||||
|
||||
|
@ -125,7 +161,8 @@ public class ValidatorTest {
|
|||
}
|
||||
|
||||
@Test
|
||||
public void formatError() {
|
||||
@ModelTest
|
||||
public void formatError(KeycloakSession session) {
|
||||
|
||||
Map<String, String> miniResourceBundle = new HashMap<>();
|
||||
miniResourceBundle.put("error-invalid-blank", "{0} is blank: <{1}>");
|
||||
|
@ -133,7 +170,7 @@ public class ValidatorTest {
|
|||
|
||||
List<String> errors = new ArrayList<>();
|
||||
MockAddress faultyAddress = new MockAddress("", "Saint-Maur-des-Fossés", null, "Germany");
|
||||
MockAddressValidator.INSTANCE.validate(faultyAddress, "address").toResult().forEachError(e -> {
|
||||
MockAddressValidator.INSTANCE.validate(faultyAddress, "address", new ValidationContext(session)).toResult().forEachError(e -> {
|
||||
errors.add(e.formatMessage((message, args) -> MessageFormat.format(miniResourceBundle.getOrDefault(message, message), args)));
|
||||
});
|
||||
|
||||
|
@ -141,15 +178,16 @@ public class ValidatorTest {
|
|||
}
|
||||
|
||||
@Test
|
||||
public void multipleValidations() {
|
||||
@ModelTest
|
||||
public void multipleValidations(KeycloakSession session) {
|
||||
|
||||
ValidationContext context = new ValidationContext(session);
|
||||
|
||||
String input = "aaa";
|
||||
String inputHint = "username";
|
||||
|
||||
Validators.lengthValidator().validate(input, inputHint, context);
|
||||
Validators.notEmptyValidator().validate(input, inputHint, context);
|
||||
SimpleValidators.lengthValidator().validate(input, inputHint, context);
|
||||
SimpleValidators.notEmptyValidator().validate(input, inputHint, context);
|
||||
|
||||
ValidationResult result = context.toResult();
|
||||
|
||||
|
@ -157,15 +195,16 @@ public class ValidatorTest {
|
|||
}
|
||||
|
||||
@Test
|
||||
public void multipleValidationsError() {
|
||||
@ModelTest
|
||||
public void multipleValidationsError(KeycloakSession session) {
|
||||
|
||||
ValidationContext context = new ValidationContext(session);
|
||||
|
||||
String input = " ";
|
||||
String inputHint = "username";
|
||||
|
||||
Validators.lengthValidator().validate(input, inputHint, context, configFromMap(Collections.singletonMap(LengthValidator.KEY_MIN, 1)));
|
||||
Validators.notBlankValidator().validate(input, inputHint, context);
|
||||
SimpleValidators.lengthValidator().validate(input, inputHint, context, configFromMap(Collections.singletonMap(LengthValidator.KEY_MIN, 1)));
|
||||
SimpleValidators.notBlankValidator().validate(input, inputHint, context);
|
||||
|
||||
ValidationResult result = context.toResult();
|
||||
|
||||
|
@ -184,7 +223,8 @@ public class ValidatorTest {
|
|||
}
|
||||
|
||||
@Test
|
||||
public void validateValidatorConfigSimple() {
|
||||
@ModelTest
|
||||
public void validateValidatorConfigSimple(KeycloakSession session) {
|
||||
|
||||
SimpleValidator validator = LengthValidator.INSTANCE;
|
||||
|
||||
|
@ -197,8 +237,9 @@ public class ValidatorTest {
|
|||
}
|
||||
|
||||
@Test
|
||||
public void validateEmailValidator() {
|
||||
SimpleValidator validator = Validators.emailValidator();
|
||||
@ModelTest
|
||||
public void validateEmailValidator(KeycloakSession session) {
|
||||
SimpleValidator validator = SimpleValidators.emailValidator();
|
||||
|
||||
Assert.assertTrue(validator.validateConfig(session, null).isValid());
|
||||
Assert.assertTrue(validator.validateConfig(session, ValidatorConfig.EMPTY).isValid());
|
||||
|
@ -215,7 +256,8 @@ public class ValidatorTest {
|
|||
}
|
||||
|
||||
@Test
|
||||
public void validateValidatorConfigMultipleOptions() {
|
||||
@ModelTest
|
||||
public void validateValidatorConfigMultipleOptions(KeycloakSession session) {
|
||||
|
||||
SimpleValidator validator = LengthValidator.INSTANCE;
|
||||
|
||||
|
@ -229,7 +271,8 @@ public class ValidatorTest {
|
|||
}
|
||||
|
||||
@Test
|
||||
public void validateValidatorConfigMultipleOptionsInvalidValues() {
|
||||
@ModelTest
|
||||
public void validateValidatorConfigMultipleOptionsInvalidValues(KeycloakSession session) {
|
||||
|
||||
SimpleValidator validator = LengthValidator.INSTANCE;
|
||||
|
||||
|
@ -253,7 +296,8 @@ public class ValidatorTest {
|
|||
}
|
||||
|
||||
@Test
|
||||
public void validateValidatorConfigViaValidatorFactory() {
|
||||
@ModelTest
|
||||
public void validateValidatorConfigViaValidatorFactory(KeycloakSession session) {
|
||||
|
||||
Map<String, Object> config = new HashMap<>();
|
||||
config.put("min", "a");
|
||||
|
@ -275,15 +319,16 @@ public class ValidatorTest {
|
|||
}
|
||||
|
||||
@Test
|
||||
public void nestedValidation() {
|
||||
@ModelTest
|
||||
public void nestedValidation(KeycloakSession session) {
|
||||
|
||||
Assert.assertTrue(MockAddressValidator.INSTANCE.validate(
|
||||
new MockAddress("4848 Arcu St.", "Saint-Maur-des-Fossés", "02206", "Germany")
|
||||
, "address").isValid());
|
||||
, "address", new ValidationContext(session)).isValid());
|
||||
|
||||
ValidationResult result = MockAddressValidator.INSTANCE.validate(
|
||||
new MockAddress("", "Saint-Maur-des-Fossés", null, "Germany")
|
||||
, "address").toResult();
|
||||
, "address", new ValidationContext(session)).toResult();
|
||||
Assert.assertFalse(result.isValid());
|
||||
Assert.assertEquals(2, result.getErrors().size());
|
||||
|
Loading…
Reference in a new issue