From 802a670cc51566151fb82d9787ab30124b577522 Mon Sep 17 00:00:00 2001 From: Markus Till Date: Thu, 1 Oct 2020 23:50:25 +0200 Subject: [PATCH] have a factory like approach for profile contexts --- .../userprofile/UserProfileContext.java | 3 +- .../userprofile/UserProfileProvider.java | 2 +- .../broker/IdpReviewProfileAuthenticator.java | 7 +-- .../forms/RegistrationProfile.java | 8 +--- .../forms/RegistrationUserCreation.java | 8 +--- .../requiredactions/UpdateProfile.java | 4 +- .../resources/account/AccountFormService.java | 4 +- .../resources/account/AccountRestService.java | 8 ++-- .../LegacyUserProfileProvider.java | 4 +- .../profile/DefaultUserProfileContext.java | 47 ++++++++++++------- .../validation/StaticValidators.java | 12 ++--- .../validation/ValidationChain.java | 7 +-- .../validation/ValidationChainTest.java | 11 ++--- 13 files changed, 61 insertions(+), 64 deletions(-) diff --git a/server-spi-private/src/main/java/org/keycloak/userprofile/UserProfileContext.java b/server-spi-private/src/main/java/org/keycloak/userprofile/UserProfileContext.java index 906bc18a63..c17e0bedeb 100644 --- a/server-spi-private/src/main/java/org/keycloak/userprofile/UserProfileContext.java +++ b/server-spi-private/src/main/java/org/keycloak/userprofile/UserProfileContext.java @@ -26,6 +26,5 @@ public interface UserProfileContext { boolean isCreate(); UserUpdateEvent getUpdateEvent(); - UserProfile getCurrent(); - UserProfile getUpdated(); + UserProfile getCurrentProfile(); } diff --git a/server-spi-private/src/main/java/org/keycloak/userprofile/UserProfileProvider.java b/server-spi-private/src/main/java/org/keycloak/userprofile/UserProfileProvider.java index 97e9226dbc..608f2e737c 100644 --- a/server-spi-private/src/main/java/org/keycloak/userprofile/UserProfileProvider.java +++ b/server-spi-private/src/main/java/org/keycloak/userprofile/UserProfileProvider.java @@ -25,6 +25,6 @@ import org.keycloak.userprofile.validation.UserProfileValidationResult; */ public interface UserProfileProvider extends Provider { - UserProfileValidationResult validate(UserProfileContext updateContext); + UserProfileValidationResult validate(UserProfileContext updateContext, UserProfile updatedProfile); } diff --git a/services/src/main/java/org/keycloak/authentication/authenticators/broker/IdpReviewProfileAuthenticator.java b/services/src/main/java/org/keycloak/authentication/authenticators/broker/IdpReviewProfileAuthenticator.java index 546de76344..6effc5f8e1 100755 --- a/services/src/main/java/org/keycloak/authentication/authenticators/broker/IdpReviewProfileAuthenticator.java +++ b/services/src/main/java/org/keycloak/authentication/authenticators/broker/IdpReviewProfileAuthenticator.java @@ -37,9 +37,8 @@ import org.keycloak.services.resources.AttributeFormDataProcessor; import org.keycloak.services.validation.Validation; import org.keycloak.userprofile.LegacyUserProfileProviderFactory; import org.keycloak.userprofile.UserProfileProvider; -import org.keycloak.userprofile.profile.representations.AttributeUserProfile; import org.keycloak.userprofile.profile.DefaultUserProfileContext; -import org.keycloak.userprofile.profile.representations.IdpUserProfile; +import org.keycloak.userprofile.profile.representations.AttributeUserProfile; import org.keycloak.userprofile.utils.UserProfileUpdateHelper; import org.keycloak.userprofile.validation.UserProfileValidationResult; import org.keycloak.userprofile.validation.UserUpdateEvent; @@ -112,9 +111,7 @@ public class IdpReviewProfileAuthenticator extends AbstractIdpAuthenticator { String oldEmail = userCtx.getEmail(); String newEmail = updatedProfile.getFirstAttribute(UserModel.EMAIL); - DefaultUserProfileContext updateContext = - new DefaultUserProfileContext(UserUpdateEvent.IdpReview, new IdpUserProfile(userCtx), updatedProfile); - UserProfileValidationResult result = profileProvider.validate(updateContext); + UserProfileValidationResult result = profileProvider.validate(DefaultUserProfileContext.forIdpReview(userCtx), updatedProfile); List errors = Validation.getFormErrorsFromValidation(result); if (errors != null && !errors.isEmpty()) { diff --git a/services/src/main/java/org/keycloak/authentication/forms/RegistrationProfile.java b/services/src/main/java/org/keycloak/authentication/forms/RegistrationProfile.java index e4626ad9b6..90a3be9ced 100755 --- a/services/src/main/java/org/keycloak/authentication/forms/RegistrationProfile.java +++ b/services/src/main/java/org/keycloak/authentication/forms/RegistrationProfile.java @@ -72,9 +72,8 @@ public class RegistrationProfile implements FormAction, FormActionFactory { UserProfileProvider userProfile = context.getSession().getProvider(UserProfileProvider.class, LegacyUserProfileProviderFactory.PROVIDER_ID); context.getEvent().detail(Details.REGISTER_METHOD, "form"); - DefaultUserProfileContext updateContext = new DefaultUserProfileContext(UserUpdateEvent.RegistrationProfile, updatedProfile); - UserProfileValidationResult result = userProfile.validate(updateContext); + UserProfileValidationResult result = userProfile.validate(DefaultUserProfileContext.forRegistrationProfile(), updatedProfile); List errors = Validation.getFormErrorsFromValidation(result); if (errors.size() > 0) { @@ -98,10 +97,7 @@ public class RegistrationProfile implements FormAction, FormActionFactory { public void success(FormContext context) { UserModel user = context.getUser(); AttributeUserProfile updatedProfile = AttributeFormDataProcessor.toUserProfile(context.getHttpRequest().getDecodedFormParameters()); - - DefaultUserProfileContext updateContext = - new DefaultUserProfileContext(UserUpdateEvent.RegistrationProfile, new UserModelUserProfile(user), updatedProfile); - UserProfileUpdateHelper.update(updateContext.getUpdateEvent(), context.getSession(), user, updatedProfile, false); + UserProfileUpdateHelper.update(UserUpdateEvent.RegistrationProfile, context.getSession(), user, updatedProfile, false); } @Override diff --git a/services/src/main/java/org/keycloak/authentication/forms/RegistrationUserCreation.java b/services/src/main/java/org/keycloak/authentication/forms/RegistrationUserCreation.java index d7bf934351..b974444f02 100755 --- a/services/src/main/java/org/keycloak/authentication/forms/RegistrationUserCreation.java +++ b/services/src/main/java/org/keycloak/authentication/forms/RegistrationUserCreation.java @@ -82,8 +82,7 @@ public class RegistrationUserCreation implements FormAction, FormActionFactory { UserProfileProvider profileProvider = context.getSession().getProvider(UserProfileProvider.class, LegacyUserProfileProviderFactory.PROVIDER_ID); context.getEvent().detail(Details.REGISTER_METHOD, "form"); - DefaultUserProfileContext updateContext = new DefaultUserProfileContext(UserUpdateEvent.RegistrationUserCreation, newProfile); - UserProfileValidationResult result = profileProvider.validate(updateContext); + UserProfileValidationResult result = profileProvider.validate(DefaultUserProfileContext.forRegistrationUserCreation(), newProfile); List errors = Validation.getFormErrorsFromValidation(result); if (context.getRealm().isRegistrationEmailAsUsername()) { @@ -128,10 +127,7 @@ public class RegistrationUserCreation implements FormAction, FormActionFactory { UserModel user = context.getSession().users().addUser(context.getRealm(), username); user.setEnabled(true); - - DefaultUserProfileContext updateContext = - new DefaultUserProfileContext(UserUpdateEvent.RegistrationUserCreation, new UserModelUserProfile(user), updatedProfile); - UserProfileUpdateHelper.update(updateContext.getUpdateEvent(), context.getSession(), user, updatedProfile, false); + UserProfileUpdateHelper.update(UserUpdateEvent.RegistrationUserCreation, context.getSession(), user, updatedProfile, false); context.getAuthenticationSession().setClientNote(OIDCLoginProtocol.LOGIN_HINT_PARAM, username); diff --git a/services/src/main/java/org/keycloak/authentication/requiredactions/UpdateProfile.java b/services/src/main/java/org/keycloak/authentication/requiredactions/UpdateProfile.java index 55a54279df..a6d3e59d0d 100644 --- a/services/src/main/java/org/keycloak/authentication/requiredactions/UpdateProfile.java +++ b/services/src/main/java/org/keycloak/authentication/requiredactions/UpdateProfile.java @@ -80,9 +80,7 @@ public class UpdateProfile implements RequiredActionProvider, RequiredActionFact String newEmail = updatedProfile.getFirstAttribute(UserModel.EMAIL); UserProfileProvider userProfile = context.getSession().getProvider(UserProfileProvider.class, LegacyUserProfileProviderFactory.PROVIDER_ID); - DefaultUserProfileContext updateContext = - new DefaultUserProfileContext(UserUpdateEvent.UpdateProfile, new UserModelUserProfile(user), updatedProfile); - UserProfileValidationResult result = userProfile.validate(updateContext); + UserProfileValidationResult result = userProfile.validate(DefaultUserProfileContext.forUpdateProfile(user),updatedProfile); List errors = Validation.getFormErrorsFromValidation(result); if (errors != null && !errors.isEmpty()) { diff --git a/services/src/main/java/org/keycloak/services/resources/account/AccountFormService.java b/services/src/main/java/org/keycloak/services/resources/account/AccountFormService.java index 5c3578a582..4cb4569450 100755 --- a/services/src/main/java/org/keycloak/services/resources/account/AccountFormService.java +++ b/services/src/main/java/org/keycloak/services/resources/account/AccountFormService.java @@ -369,10 +369,8 @@ public class AccountFormService extends AbstractSecuredLocalService { event.event(EventType.UPDATE_PROFILE).client(auth.getClient()).user(auth.getUser()); UserProfileProvider profileProvider = session.getProvider(UserProfileProvider.class, LegacyUserProfileProviderFactory.PROVIDER_ID); - DefaultUserProfileContext updateContext = - new DefaultUserProfileContext(UserUpdateEvent.Account, new UserModelUserProfile(user), updatedProfile); - UserProfileValidationResult result = profileProvider.validate(updateContext); + UserProfileValidationResult result = profileProvider.validate(DefaultUserProfileContext.forAccountService(user), updatedProfile); List errors = Validation.getFormErrorsFromValidation(result); if (!errors.isEmpty()) { diff --git a/services/src/main/java/org/keycloak/services/resources/account/AccountRestService.java b/services/src/main/java/org/keycloak/services/resources/account/AccountRestService.java index ceef3b8495..29e1109b44 100755 --- a/services/src/main/java/org/keycloak/services/resources/account/AccountRestService.java +++ b/services/src/main/java/org/keycloak/services/resources/account/AccountRestService.java @@ -48,11 +48,11 @@ import org.keycloak.services.util.ResolveRelative; import org.keycloak.storage.ReadOnlyException; import org.keycloak.theme.Theme; import org.keycloak.userprofile.LegacyUserProfileProviderFactory; +import org.keycloak.userprofile.UserProfile; import org.keycloak.userprofile.UserProfileProvider; import org.keycloak.userprofile.utils.UserProfileUpdateHelper; import org.keycloak.userprofile.profile.representations.AccountUserRepresentationUserProfile; import org.keycloak.userprofile.profile.DefaultUserProfileContext; -import org.keycloak.userprofile.profile.representations.UserModelUserProfile; import org.keycloak.userprofile.validation.UserProfileValidationResult; import org.keycloak.userprofile.validation.UserUpdateEvent; @@ -175,11 +175,9 @@ public class AccountRestService { event.event(EventType.UPDATE_PROFILE).client(auth.getClient()).user(auth.getUser()); + UserProfile updatedUser = new AccountUserRepresentationUserProfile(rep); UserProfileProvider profileProvider = session.getProvider(UserProfileProvider.class, LegacyUserProfileProviderFactory.PROVIDER_ID); - AccountUserRepresentationUserProfile updatedUser = new AccountUserRepresentationUserProfile(rep); - DefaultUserProfileContext updateContext = - new DefaultUserProfileContext(UserUpdateEvent.Account, new UserModelUserProfile(user), updatedUser); - UserProfileValidationResult result = profileProvider.validate(updateContext); + UserProfileValidationResult result = profileProvider.validate(DefaultUserProfileContext.forAccountService(user), updatedUser); if (result.hasFailureOfErrorType(Messages.READ_ONLY_USERNAME)) return ErrorResponse.error(Messages.READ_ONLY_USERNAME, Response.Status.BAD_REQUEST); diff --git a/services/src/main/java/org/keycloak/userprofile/LegacyUserProfileProvider.java b/services/src/main/java/org/keycloak/userprofile/LegacyUserProfileProvider.java index 4bddc03946..d9cbf2f1e9 100644 --- a/services/src/main/java/org/keycloak/userprofile/LegacyUserProfileProvider.java +++ b/services/src/main/java/org/keycloak/userprofile/LegacyUserProfileProvider.java @@ -44,7 +44,7 @@ public class LegacyUserProfileProvider implements UserProfileProvider { } @Override - public UserProfileValidationResult validate(UserProfileContext updateContext) { + public UserProfileValidationResult validate(UserProfileContext updateContext, UserProfile updatedProfile) { RealmModel realm = this.session.getContext().getRealm(); ValidationChainBuilder builder = ValidationChainBuilder.builder(); @@ -64,7 +64,7 @@ public class LegacyUserProfileProvider implements UserProfileProvider { addUserCreationValidators(builder); break; } - return new UserProfileValidationResult(builder.build().validate(updateContext)); + return new UserProfileValidationResult(builder.build().validate(updateContext,updatedProfile)); } private void addUserCreationValidators(ValidationChainBuilder builder) { diff --git a/services/src/main/java/org/keycloak/userprofile/profile/DefaultUserProfileContext.java b/services/src/main/java/org/keycloak/userprofile/profile/DefaultUserProfileContext.java index 7589cf2f6f..3e214a031d 100644 --- a/services/src/main/java/org/keycloak/userprofile/profile/DefaultUserProfileContext.java +++ b/services/src/main/java/org/keycloak/userprofile/profile/DefaultUserProfileContext.java @@ -17,8 +17,14 @@ package org.keycloak.userprofile.profile; +import org.keycloak.authentication.authenticators.broker.util.SerializedBrokeredIdentityContext; +import org.keycloak.models.UserModel; +import org.keycloak.representations.idm.UserRepresentation; import org.keycloak.userprofile.UserProfile; import org.keycloak.userprofile.UserProfileContext; +import org.keycloak.userprofile.profile.representations.IdpUserProfile; +import org.keycloak.userprofile.profile.representations.UserModelUserProfile; +import org.keycloak.userprofile.profile.representations.UserRepresentationUserProfile; import org.keycloak.userprofile.validation.UserUpdateEvent; /** @@ -27,23 +33,37 @@ import org.keycloak.userprofile.validation.UserUpdateEvent; public class DefaultUserProfileContext implements UserProfileContext { private boolean isCreated; private UserProfile currentUserProfile; - private UserProfile updatedUserProfile; private UserUpdateEvent userUpdateEvent; - public DefaultUserProfileContext(UserUpdateEvent userUpdateEvent, UserProfile updatedUserProfile) { + private DefaultUserProfileContext(UserUpdateEvent userUpdateEvent, UserProfile currentUserProfile) { this.userUpdateEvent = userUpdateEvent; this.isCreated = false; - this.currentUserProfile = null; - this.updatedUserProfile = updatedUserProfile; - } - - public DefaultUserProfileContext(UserUpdateEvent userUpdateEvent, UserProfile currentUserProfile, UserProfile updatedUserProfile) { - this.userUpdateEvent = userUpdateEvent; - this.isCreated = true; this.currentUserProfile = currentUserProfile; - this.updatedUserProfile = updatedUserProfile; } + public static DefaultUserProfileContext forIdpReview(SerializedBrokeredIdentityContext currentUser) { + return new DefaultUserProfileContext(UserUpdateEvent.IdpReview, new IdpUserProfile(currentUser)); + } + + public static DefaultUserProfileContext forUpdateProfile(UserModel currentUser) { + return new DefaultUserProfileContext(UserUpdateEvent.UpdateProfile, new UserModelUserProfile(currentUser)); + } + + public static DefaultUserProfileContext forAccountService(UserModel currentUser) { + return new DefaultUserProfileContext(UserUpdateEvent.Account, new UserModelUserProfile(currentUser)); + } + + public static DefaultUserProfileContext forRegistrationUserCreation() { + return new DefaultUserProfileContext(UserUpdateEvent.RegistrationUserCreation, null); + } + + public static DefaultUserProfileContext forRegistrationProfile() { + return new DefaultUserProfileContext(UserUpdateEvent.RegistrationProfile, null); + } + + public static DefaultUserProfileContext forUserResource(UserRepresentation rep) { + return new DefaultUserProfileContext(UserUpdateEvent.UserResource, new UserRepresentationUserProfile(rep)); + } @Override public boolean isCreate() { @@ -51,15 +71,10 @@ public class DefaultUserProfileContext implements UserProfileContext { } @Override - public UserProfile getCurrent() { + public UserProfile getCurrentProfile() { return currentUserProfile; } - @Override - public UserProfile getUpdated() { - return updatedUserProfile; - } - @Override public UserUpdateEvent getUpdateEvent(){ return userUpdateEvent; diff --git a/services/src/main/java/org/keycloak/userprofile/validation/StaticValidators.java b/services/src/main/java/org/keycloak/userprofile/validation/StaticValidators.java index 0c9dce0f84..c5636b1951 100644 --- a/services/src/main/java/org/keycloak/userprofile/validation/StaticValidators.java +++ b/services/src/main/java/org/keycloak/userprofile/validation/StaticValidators.java @@ -41,16 +41,16 @@ public class StaticValidators { public static BiFunction userNameExists(KeycloakSession session) { return (value, context) -> - !(context.getCurrent() != null - && !value.equals(context.getCurrent().getFirstAttribute(UserModel.USERNAME)) + !(context.getCurrentProfile() != null + && !value.equals(context.getCurrentProfile().getFirstAttribute(UserModel.USERNAME)) && session.users().getUserByUsername(value, session.getContext().getRealm()) != null); } public static BiFunction isUserMutable(RealmModel realm) { return (value, context) -> !(!realm.isEditUsernameAllowed() - && context.getCurrent() != null - && !value.equals(context.getCurrent().getFirstAttribute(UserModel.USERNAME)) + && context.getCurrentProfile() != null + && !value.equals(context.getCurrentProfile().getFirstAttribute(UserModel.USERNAME)) ); } @@ -65,7 +65,7 @@ public class StaticValidators { RealmModel realm = session.getContext().getRealm(); if (!realm.isDuplicateEmailsAllowed()) { UserModel userByEmail = session.users().getUserByEmail(value, realm); - return !(realm.isRegistrationEmailAsUsername() && userByEmail != null && context.getCurrent() != null && !userByEmail.getId().equals(context.getCurrent().getId())); + return !(realm.isRegistrationEmailAsUsername() && userByEmail != null && context.getCurrentProfile() != null && !userByEmail.getId().equals(context.getCurrentProfile().getId())); } return true; }; @@ -77,7 +77,7 @@ public class StaticValidators { if (!realm.isDuplicateEmailsAllowed()) { UserModel userByEmail = session.users().getUserByEmail(value, realm); // check for duplicated email - return !(userByEmail != null && (context.getCurrent() == null || !userByEmail.getId().equals(context.getCurrent().getId()))); + return !(userByEmail != null && (context.getCurrentProfile() == null || !userByEmail.getId().equals(context.getCurrentProfile().getId()))); } return true; }; diff --git a/services/src/main/java/org/keycloak/userprofile/validation/ValidationChain.java b/services/src/main/java/org/keycloak/userprofile/validation/ValidationChain.java index 4ef81c1c0f..15875bfb15 100644 --- a/services/src/main/java/org/keycloak/userprofile/validation/ValidationChain.java +++ b/services/src/main/java/org/keycloak/userprofile/validation/ValidationChain.java @@ -17,6 +17,7 @@ package org.keycloak.userprofile.validation; +import org.keycloak.userprofile.UserProfile; import org.keycloak.userprofile.UserProfileContext; import java.util.ArrayList; @@ -32,17 +33,17 @@ public class ValidationChain { this.attributeValidators = attributeValidators; } - public List validate(UserProfileContext updateContext) { + public List validate(UserProfileContext updateContext, UserProfile updatedProfile) { List overallResults = new ArrayList<>(); for (AttributeValidator attribute : attributeValidators) { List validationResults = new ArrayList<>(); String attributeKey = attribute.attributeKey; - String attributeValue = updateContext.getUpdated().getFirstAttribute(attributeKey); + String attributeValue = updatedProfile.getFirstAttribute(attributeKey); boolean attributeChanged = false; if (attributeValue != null) { - attributeChanged = updateContext.getCurrent() != null && !attributeValue.equals(updateContext.getCurrent().getFirstAttribute(attributeKey)); + attributeChanged = updateContext.getCurrentProfile() != null && !attributeValue.equals(updateContext.getCurrentProfile().getFirstAttribute(attributeKey)); for (Validator validator : attribute.validators) { validationResults.add(new ValidationResult(validator.function.apply(attributeValue, updateContext), validator.errorType)); } diff --git a/services/src/test/java/org/keycloak/userprofile/validation/ValidationChainTest.java b/services/src/test/java/org/keycloak/userprofile/validation/ValidationChainTest.java index c43328e5cb..c302ad32c1 100644 --- a/services/src/test/java/org/keycloak/userprofile/validation/ValidationChainTest.java +++ b/services/src/test/java/org/keycloak/userprofile/validation/ValidationChainTest.java @@ -18,6 +18,7 @@ public class ValidationChainTest { ValidationChain testchain; UserProfile user; DefaultUserProfileContext updateContext; + UserRepresentation rep = new UserRepresentation(); @Before public void setUp() throws Exception { @@ -27,7 +28,6 @@ public class ValidationChainTest { .addAttributeValidator().forAttribute("firstName") .addValidationFunction("FIRST_NAME_FIELD_ERRORKEY", (value, updateUserProfileContext) -> true).build(); - UserRepresentation rep = new UserRepresentation(); //default user content rep.singleAttribute(UserModel.FIRST_NAME, "firstName"); rep.singleAttribute(UserModel.LAST_NAME, "lastName"); @@ -35,15 +35,14 @@ public class ValidationChainTest { rep.singleAttribute("FAKE_FIELD", "content"); rep.singleAttribute("NULLABLE_FIELD", null); - user = new UserRepresentationUserProfile(rep); - updateContext = new DefaultUserProfileContext(UserUpdateEvent.Account,null, user); + updateContext = DefaultUserProfileContext.forRegistrationProfile(); } @Test public void validate() { testchain = builder.build(); - UserProfileValidationResult results = new UserProfileValidationResult(testchain.validate(updateContext)); + UserProfileValidationResult results = new UserProfileValidationResult(testchain.validate(updateContext, new UserRepresentationUserProfile(rep))); Assert.assertEquals(true, results.hasFailureOfErrorType("FAKE_FIELD_ERRORKEY")); Assert.assertEquals(false, results.hasFailureOfErrorType("FIRST_NAME_FIELD_ERRORKEY")); Assert.assertEquals(true, results.getValidationResults().stream().filter(o -> o.getField().equals("firstName")).collect(Collectors.toList()).get(0).isValid()); @@ -58,7 +57,7 @@ public class ValidationChainTest { .addAttributeValidator().forAttribute("FAKE_FIELD") .addValidationFunction("FAKE_FIELD_ERRORKEY_2", (value, updateUserProfileContext) -> false).build().build(); - UserProfileValidationResult results = new UserProfileValidationResult(testchain.validate(updateContext)); + UserProfileValidationResult results = new UserProfileValidationResult(testchain.validate(updateContext, new UserRepresentationUserProfile(rep))); Assert.assertEquals(true, results.hasFailureOfErrorType("FAKE_FIELD_ERRORKEY_1")); Assert.assertEquals(true, results.hasFailureOfErrorType("FAKE_FIELD_ERRORKEY_2")); Assert.assertEquals(true, results.getValidationResults().stream().filter(o -> o.getField().equals("firstName")).collect(Collectors.toList()).get(0).isValid()); @@ -68,7 +67,7 @@ public class ValidationChainTest { @Test public void emptyChain() { - UserProfileValidationResult results = new UserProfileValidationResult(ValidationChainBuilder.builder().build().validate(updateContext)); + UserProfileValidationResult results = new UserProfileValidationResult(ValidationChainBuilder.builder().build().validate(updateContext,new UserRepresentationUserProfile(rep) )); Assert.assertEquals(Collections.emptyList(), results.getValidationResults()); } }